getAsPlainText problem

Here’s a routine that works perfectly every time when I step through it with the debugger. But fails every time otherwise.

The purpose is to extract text from an HTML area field and store it without HTML codes in a related record. It’s important to leave the HTML codes untouched in the original HTML area field. Therefore I’ve created a clone of that field, also formatted as an HTML area field, named and placed on a special form.

First the form is loaded with the target record and I check to see if the correct record has indeed been properly loaded. Then the “letter” field is copied into letter_dup1. If the two are equal to each other all instances of "
" are converted into “qqq”, the plain text is captured and instances of “qqq” converted to line breaks.

Finally the related record is updated starting with the date and time, followed by the captured text. If I step through this, then everything’s correct. But if I just run it, then only the time stamp is correct; the text is the plain text of a previous letter.

var vCorid = arguments[0];
if ( corid == vCorid )
{
	if ( letter )
	{
		letter_dup1 = letter;
		controller.saveData();
		
		if ( letter_dup1 == letter )
		{
			letter_dup1 = utils.stringReplace(letter_dup1, '
', 'qqq');
			letter_dup1 = elements.letter_dup1.getAsPlainText();
			globals.gutility4 = utils.stringReplace(letter_dup1, 'qqq', '\n');
			controller.saveData();
			crid$cor_to_cr.crtext += '\n\n' + i18n.getI18NMessage('7office.mthd.emailsent') + ' ' + utils.dateFormat(cor_date,'EEE dMMMyyyy h:mm aaa'); 
			crid$cor_to_cr.crtext += '\n_________________________________________________\n';
			crid$cor_to_cr.crtext += globals.gutility4;
			controller.saveData();
		}
		else
		{
			plugins.dialogs.showErrorDialog( 'Error', '<html>letter_dup1 not equal to letter.
corLetterDup.storeTextInRelatedCR.

Please report the circumstances.');
		}
	}
	else
	{
		plugins.dialogs.showErrorDialog( 'Error', '<html>Empty letter field in corLetterDup.storeTextInRelatedCR.

Please report the circumstances.');
	}
}
else
{
	plugins.dialogs.showErrorDialog( 'Error', '<html>Wrong record loaded.
corLetterDup.storeTextInRelatedCR.

Please report the circumstances.');
}

Why does this code process properly when stepped through but not when run normally? Any ideas on how to fix this?

Appreciated.

Hi Morley,

What actually triggers your script?(button , onShow, etc..)

maarten:
Hi Morley,

What actually triggers your script?(button , onShow, etc..)

A button which sends the eMail. Once sent the guts of the message (without fancy formatting) is extracted and copied into a related Call Report record.

It would be great if there were a function which didn’t rely on a named screen element to extract plain text (preserving line returns) into a variable.

Thanks.

Therefore I’ve created a clone of that field, also formatted as an HTML area field, named and placed on a special form.
First the form is loaded with the target record and I check to see if the correct record has indeed been properly loaded.

Are you really sure that everything stays “in sync” during execution of your script?
Because if this happens consistently…

But if I just run it, then only the time stamp is correct; the text is the plain text of a previous letter.

Then maybe there’s a mismatch occuring.
(hm, which doesn’t explain why stepping through the debugger doesn’t screw things up)

maarten:

Therefore I’ve created a clone of that field, also formatted as an HTML area field, named and placed on a special form.
First the form is loaded with the target record and I check to see if the correct record has indeed been properly loaded.

Are you really sure that everything stays “in sync” during execution of your script?
Because if this happens consistently…

But if I just run it, then only the time stamp is correct; the text is the plain text of a previous letter.

Then maybe there’s a mismatch occuring.
(hm, which doesn’t explain why stepping through the debugger doesn’t screw things up)

Exactly!

I’ve tried a lot of tricks to verify whether the right record is being loaded for processing. It is. That the right related record is being updated. It is.

Just so I can generate some demo records here’s what I’ve been doing this morning. I’ve maintained the loadRecords call to the form which does the processing but I’ve disabled activating the method itself. Therefore I create the eMail, click “send”, get back the confirmation message the eMail has been sent. Then manually switch to the form which holds the method quoted in my original posting here. I then run the method with the debugger without stepping through it. This works perfectly, at least for now, but too klutzy to inflict on end users.

I tried creating a button which would do the above for me. However, get this, it processed the right text but dumped all the line returns.

Here’s a possible complicating factor. The send eMail button which triggers this process is located on a FID (form in dialogue) and the FID remains in place while all this is happening. Don’t know whether that matters. But right after writing this I’ll try closing the FID right at the top of the send eMail method.

Here’s what happens if the FID is closed prior to processing the eMail.

This time the correct record is loaded but no text is processed. The date and time of sending is added to the related CR record but the text itself isn’t.

It feels strange to have to load up a form and process the contents of a named field in order to do this. Intuitively the problem is in that convention somewhere. The form is correctly loaded but that function is pointing elsewhere when it processes.

Let me know if you’d like me to try something.

Hi Morley,

I’ll be happy to help you out but iin order to locate the bug I would need a sample solution.

So here’s the deal:
If it’s a bug in Servoy we’ll fix it.
If it’s a bug in a script we’ll charge you for hours made.:)

Hi Maarten

I’ve figured out what’s going on here, but it requires a klutzy workaround. In the style of FMP, it requires placing a 1 pixel by 1 pixel field on the form in order to work. I thought we’d left this stuff behind.

All I want to do is fetch the plain text of an HTML area formatted field and place it in a related record. I’ve found no docs on element.getAsPlainText but by experiment I’ve discovered this function only works if the field to be processed is named, the method making the call belongs to the currently displayed form and the field itself is formatted as HTML area.

That’s a lot of very limiting conditions, especially for an undocumented function.

This is the first time I’ve had to resort to an FMP-style workaround within Servoy. It would be very helpful if getAsPlainText were able to process fields whether or not they were displayed and whether or not the calling method belonged to the currently displayed form.

Kind regards

Morley,

  1. You can only access NAMED elements programatically in Servoy (since 1.0)

  2. You CAN access any named element on any form from any method using: form.formName.elements.elementName

  3. The way a field is displayed is controlled by the “displayFormat” property of a field on a form. The only two types of display types that make sense to grab the data as plain text are the only two that store additional data in the column: HTML_AREA and RTF_AREA.

Hope this helps.

bcusick:
Morley,

  1. You can only access NAMED elements programatically in Servoy (since 1.0)

  2. You CAN access any named element on any form from any method using: form.formName.elements.elementName

  3. The way a field is displayed is controlled by the “displayFormat” property of a field on a form. The only two types of display types that make sense to grab the data as plain text are the only two that store additional data in the column: HTML_AREA and RTF_AREA.

Hope this helps.

Because the calling method doesn’t display the target field I created a special form for it, loaded that form with the current record, then ran a method attached to that form.

One would think that would meet all the criteria, but it doesn’t. Only when I actually showed the form would the function perform. It would be great if this function would process the contents of a field regardless of whether it’s being currently displayed.

My workaround has been to the move the code into a method attached to the currently displayed form and to place a 1 pixel by 1 pixel locked field on the layout. I’m sure you know what I’m talking about. Definitely not ideal for a utility function like this one, IMHO. :)

Morley, here is what I do!

At some place your HTML-area is typed-in or generated by somebody? right?
make a method (on data change, for example) which gets the plain text and drop that into another field for instance: html_plaintext

Use that field, to put into a related record!

I think the solution is the tip Harjo gave you.
Or, again, pick up the regular expression I posted before.

It is only logical you need to display the contents first since you are referrring to an element and not a dataprovider…

Hate to bring this thread back alive. But I thought this would be the perfect function for wwhat I need to do with a webform using it to get the text from a html label. Getting and setting the whole text is easy as it turns out. But since it is HTML text, I needed getAsPlainText(). No go of course I move it to an HTML area and work from there. which in my web case getAsPlainText() does not seem to work even then.

var labelText = forms.GD_entryDB.elements.gText.getAsPlainText();

So I agree that getAsPlainText() should work with any field/label or variable. Seems to me, that if there is an issue of HTML vs RTF, pass in a second argument, the type. Return what you return now. If the text is already plain text… return it after processing. Limiting this function to a global field creates a lot of limits for using the function. There is often no need to put data into a field until after the parsing is done.