One problem with APEX is it has issues with dealing with text values of greater than 32k, while there is a fairly simple workaround it does have quite a few pieces and there has to be an easier way to do it.
Well in APEX 3.1 there is now an integrated javascript call to take care of this. This example also shows some of our new namespaced javascript objects and functions.
I've created a working example here.
Setting the CLOB
What's happening in the previous piece of javascript is I'm creating a apex.ajax.clob object. This object only takes one parameter when being initialized which is a function , or pointer to a function, to call when the XMLHTTP object's readyState changes. In that return function ,and for all built in APEX asynchronous AJAX calls, p is the XMLHTTP object.
Once the apex.ajax.clob object is created you just call set method giving it a string ._set(String Value);
It will automatically create a collection in your session CLOB_CONTENT and populate the CLOB001 column.
You can then use that in a page or application level process , usually by calling a doSubmit() and submitting the page.
The p.responseText on successful population of the CLOB will be SUCCESS.
Getting the CLOB
Getting a CLOB is much the same as setting one. Create the apex.ajax.clob object setting the function to call when p.readyState and then call the ._get() method which doesn't take any parameters.
This solution only deals with one clob at a time and the clob is alway put into the CLOB_CONTENT collection, though dealing with multiple clobs is also much easier, more on that later ;). But it is much easier to work with than the old workaround.
I just watched 2001: A Space Odyssey in the last week in HD. If you've never seen or it's been awhile or never seen it in HD do yourself a favor and check it out it's an amazing movie, though it looks like they were a little off on the dates.
Most of my last couple posts have focused on new APEX 3.1 features. And there have been some good questions in the comments. So I figured I'd go through some of them in a post to make the answers a little easier to find.
Question 1
What is the difference between add() and addParam()
They are used for passing values in slightly different ways and with different results.
.add() should only be used when dealing with a page or application items, anything else will cause an error, things you set with .add() will also automatically be set in the session state.
.addParam() should be used with what we term as parameters, the main difference being is they are not set in session and are only available for that particular request.
Can I set those global variable's values like common items in PL/SQL:
APEX_UTIL.SET_SESSION_STATE(wwv_flow.g_x01,null);
... or is there any more concise way to do it ?
No you can't set these into the session in PL/SQL. Remember those values are temporary and will not be saved past each specific request. If you need to save values from one of these that's the perfect reason to use a application level item, or collection.
Question 2
There's something I don't get.
Why do you need a temp item at all?
Mainly because it's much easier to build reusable/generic AJAX components that can be used in multiple applications. It's also going to be a big part of how the AJAX component for custom item and regions types will be implemented, more on that later. Don't get me wrong there are very good reasons sometimes to use an application or page item but many times it's not.
A quick rule of thumb is if you want to save a value into session use the application or page items, if you just passing values, use the generic ones.
Question 3
There is also g_widget_name, g_widget_num_return and g_clob_01. Could you explain them also?
g_widget_num_return I just plain missed this, my bad. Many times when I was building something using these new handy parameters it just seemed like I was also adding a number to set the number of return values, instead of wasting one of my x01-x10 we added another one. I've update my code example and the blog posting to show this.
I skipped g_widget_name on purpose as it will be used in a slightly different way in the future. You can absolutly use it now to pass values and it it won't break anything, in fact I'm working on an example that does just that.
g_clob_01 That one at the moment is unused, and might be removed, so I'd stay away from it. If you need to hold on to a specific CLOB the best way is to create a collection and use the clob column in that.
Thanks, for the questions, Matjaz , Anonymous and Mark
Also Doug Gault yet again is the first to to figure out one of my slightly obscure cultural references , good job Doug!