OraOpenSource / apex-plugin-clob-load

Oracle Application Express (APEX) Plugin for form items with long text content (over 32k)
Other
21 stars 3 forks source link

Rich Text Editor Content Sporadically fails to populate #8

Open maahelal opened 7 years ago

maahelal commented 7 years ago

Great Work, I must say.

Works -almost- every time and addresses a major issue for real world applications with a lot of content to edit.

So , for a random sample of instances the CLOB content is loaded correctly; check below; yet the content of the Rich text editor fails to update.

Debugging the javascript code, I could suggest that issue is related to the timing of execution of the function _handleClobRenderSuccess in apex-clob-load.js

even in problematic instances of execution, data param is correctly populated, however $s(opts.$elmt[0], data); seems to have no effect. I've tried to modify the code to reference the affected element using its Id rather than its dom node reference, still no luck.

I really wish I could spend more time on this issue to give a more detailed explanation and possibly a fix.

Will post if I find a solution

Keep it up Best Regards

maahelal commented 7 years ago

So it seems that simply delaying the value assignment by merely logging the value of the data parameter seems -to delay the execution long enough- to get rid of the problem, At least for now. So this is an ugly workaround but so far it works.

sthilaire commented 7 years ago

I appreciate the feedback and the second set of eyes. Yes, the Rich Text area is the biggest issue right now as logged in another bug.
I suspect that it is a race condition with the normal APEX rendering of the CK editor. Without determining a different event to pick up on, a delay may be the closest solution at this time.

sthilaire commented 7 years ago

Rough Patch for this bug - Added a timeout (non-blocking) delay for the CLOB LOAD code. This has been set to a fixed 1 second value. This is not an ideal situation, but reduces the occurrences at this time.

bjshumway commented 5 years ago

Hi @sthilaire

Even with the fix you added "setTimeout(function(){void(0);}, 1000);", I was experiencing the bug about 50% of the time.

Two things to note:

  1. "setTimeout(function(){void(0);}, 1000);" is asynchronous, so you're not technically pausing the script for a full second. In fact this has very little effect on the actual problem.
  2. A diagnosis of the actual cause can be found here: https://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful
    • The gyst of it is that sometimes JavaScript gets confused between rendering items and setting items. To remedy this, we want to push the "set value" onto the end of JavaScript's event loop so that we don't get into a race condition with JavaScripts rending engine. The easiest way to do this is with setTimeout.

Actual Solution: //Get the value of the item before we set it let val = $v(opts.$elmt[0]);

//We are using setTimouet so that the code below runs at the end of the existing event loop setTimeout(function(){ //Set the item $s('P10_HEADER',val ); } ,0) ;

bjshumway commented 5 years ago

@sthilaire

I think this issue should be re-opened until the fix I found is added.

Would you be free to skype over this for a half hour? I can show you the working example in my APEX application.

Thanks,

Ben

sthilaire commented 5 years ago

Ben,

I appreciate your feedback and input. I totally agree that the timeout was a hack. My hope was that it would be the 80% case. As you indicated, if it is not tied directly to the component, it runs a high risk of not working as both the editor generation and the loading process execute at the same time.

The issue is due to the editor re-building the component. The ideal case would be, the loading would execute after the editor is built. At this time, I don't know what event to pick up effectively on.

I will re-open this bug and re-visit this issue.

(also - open to suggestions and research done by others....)

-- Tim

bjshumway commented 5 years ago

Hi sthilaire,

I found my solution (using setTimeout) didn't solve the problem. I think it helped... but I found the bug still occuring.

By the way, the easiest way to test this bug is to setup a page with a few rich text editors (rather than just one) and then set each one on page load.

I did some more digging and I think I've found a solution. So far I haven't been able to reproduce the bug.

The solution was to delay setting the rich text editor until both conditions are met:

  1. All the ajax on the page is finished loading
  2. All of the rich text editors are finished loading

Condition 1 is just a precaution... not sure if it's required, but condition 2 is mandatory. With some testing, I've found that if you set a rich text editor before the editor's finished loading Most of the time it succeeds.... but occasionally seems to fail due to some race condition.

I used $(document).ajaxStop(function() { /this runs everytime all ajax is finished loading on the page /})

I also used CKEDITOR.on('instanceReady', function() { /this runs each time a rich text editor is finished loading /})

In my case I had three rich text editors on the page, so I waited until all 3 instanceReady Events fired, and then I called apex.item().setValue for each.

bjshumway commented 5 years ago

Hi @sthilaire

I haven't tried it out yet... but this plugin appears to successfully perform clob-loads... even for rich text editors.

https://github.com/RonnyWeiss/APEX-CLOB-Load-2/blob/master/js/script.js

Do a search for "CKEDITOR" and you'll see how it's handled.

Thanks,

Ben