Issues with On Demand Process Response - oracle-apex

I am using Oracle ApEx v4.1 together with Dynamic Actions, which basically calls a javascript function, which in turn calls an On Demand Process to save data, to the database.
Just a bit of background, I am using jQuery to scan each of the elements with their values, when the user either presses the "Save" button or the "Next" button, which in turn then passes these elements with values into the above on demand process.
My question/issue is, it looks like sometimes the process is missing the data passed in and I am not sure why and I thought that perhaps in my dynamic action I am performing both a ape.submit('SUBMIT') as well as a JavaScript function call to an on demand process.
Do I need to delay one of these calls, as at the moment, I am unsure why it works sometimes and other times, it doesn't.
Any ideas on how to lay out the code, i.e.
apex.submit('SUBMIT');
saveTheData(); <-- calls my ondemand process to save data to database

First of all, let's hark back a bit to your previous question. And what exactly you are exactly doing here. It seems wildly unnecessary!
What reason is there to collect item values in jQuery and submit them to session state when you are submitting the page anyway? When you use a next/prev/appy button and the page submits then the items' values are in session state, and you can use them in processes.
You are submitting the page with apex.submit. This submits the page, and sets all item's values in session state. You perform your JavaScript function which would call an on-demand process, providing values to the process. These values are page item values, and thus you're actually just setting session states in your on-demand process. It honestly seems like you have a real wacky design going on!
As to why it sometimes works, and sometimes it doesn't: apex.submit will submit the page. Like, right away. If you need code executed before the page is processed then do it before the submit. Note that if you were to switch the lines around it might still not work, depending on how you call the ondemand process (async or synchronous), and whether you want a success function to do something or not. When the call is async, then it might be your success function is not handled before the submit is done.

Related

Refreshing a new document so default displays in computed control

This problem has been bugging me for awhile and I can not seem to get around it. So I stripped it down to the most basic level.
1. created a new XPage and bound it to an exiting form
2. created a panel called 'displayPanel'
3. inside the panel create a comboBox and give it a few values and a default value of any valid value.
4. Set an onChange event that does a partial refresh of displayPanel
5. Add a computed field that simply displays the value of the comboBox.
6 added a button that does a partial refresh of displayPanel onClick.
Open the XPage and the computed field is blank, make a change and the computed field displays.
open the XPage again and click the refresh button and the computed field displays
Now this is a very simple example but what I need to do is actually more complex but the value of the comboBox (Does not need to be a comboBox) is not available until a refresh is performed. This is only an issue on a new document when it first gets it's defaults.
I have added this:
view.postScript("XSP.partialRefreshGet('#{id:displayPanel}')")
to every one of the page events but it does not appear to do an actual page refresh like clicking the button or making a change.
I'm at a loss as to how to make this work. If I could get this simple example to work the rest of what I need is easy.
Thanks
Fredrik is on the right track -- you should set the value manually during an event -- but I would add two caveats:
Call setValue instead of replaceItemValue (e.g. document1.setValue("myComboBox", "Default Value");). The comparative advantages might not be applicable in this specific case, but you should be in the habit of always calling setValue instead of replaceItemValue (and getValue instead of getItemValue) so that, when you've encountered a scenario where it makes a real difference, you just get that benefit for free... the rest of the time, the methods are equivalent, so you might as well just use the one that requires less typing. :)
You'll probably need to do this in afterPageLoad: the data source may not be ready yet during beforePageLoad; depending on why you're referencing the default value elsewhere in your page, beforeRenderResponse might be too late; and afterRenderResponse would definitely be too late...
...which leads me to why the defaultValue attribute does not behave the way we might expect it to, especially for those of us with experience developing Notes client apps.
The XPages engine splits the processing of every HTTP request into several "phases". Depending on the type of request (initial page load, partial refresh event, etc.) and other factors, the lifecycle will consist of as many as 6 phases and as few as 2.
This tutorial page provides an excellent description of these phases, but in the context of this question, the following are specifically of interest:
Apply Request Values
When an event runs against a page that has already been loaded (e.g. a user clicks a button, or selects a value from a combobox that has an onChange event, etc.), the HTTP request sent to the server to trigger the event includes POST data that represents the value of all editable components. This phase temporarily stores these values in the submittedValue property of any affected components, but the data source doesn't "know" what the new values are yet.
Process Validations
This phase runs any applicable validators and, if any fail, skips straight to the last phase (which means it never runs the code of the event that was triggered).
Update Model Values
If no validations fail (or none are defined), this phase takes the submitted values and actually stores them in the corresponding data source. Until this point, the data source is completely unaware that there has been any user interaction. This is intended to avoid prematurely polluting any back end data with user input that might not even be valid. Remember, not every data source is a "document"; it might be relational data that is changed via an UPDATE the instant setValue is called... which is basically what this phase does: it takes the submittedValue and calls setValue on the corresponding data source (and then sets submittedValue to null). This separation allows components to simply be visual representations of the state of the back end data -- visual representations that the user interacts with; our code should always be interacting directly with the back end data via the abstraction layer of a data source.
Render Response
Once all of the other phases have run (or been skipped), this phase sends a response to the consumer. In other words, it sends HTML (or JSON, or XML, or PDF, etc.) back to the browser. But the most salient point in the context of this question is that the prior phases are always skipped on initial page load. When the user first accesses a page, they haven't had a chance to enter any data yet, so there are no request values to be applied. Since no data has been posted, there's nothing to validate. And -- most pertinent of all -- there's nothing to be pushed to the data model. So a representation of the component tree (or a subset of it, in the case of a partial refresh event) always needs to be sent to the user, but until the user interacts with that representation, the data source remains in whatever state it was when the most recent response was rendered... which is why, if you want a specific property of the data source to have a specific value before the user interacts with it, your code needs to set that property's value manually.
In summary, components are visual. Data sources are abstract. Perhaps this behavior would be more self-explanatory if the component property had simply been called defaultClientValue instead of defaultValue, because that's essentially what it is: a default suggestion to the user for what data to send back to the data source. But until they do, the data source has not received that value. So if, on initial page load, you need a data source property to have a value that it wouldn't already have in its default state, you should manually call setValue to give it the desired value.
P.S. Ironically, if you'd called partialRefreshPost instead of partialRefreshGet, you likely would have achieved the result you were looking for, because the former sends all the form data, while the latter just asks the existing component state to be rendered again. But then you're forcing all of the form data to be sent just to update one data source property, so it's better to simply do what's described above.

Django save before leaving page prompt [duplicate]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am currently building a registration page where if the user leaves, I want to pop up a CSS box asking him if he is sure or not. I can accomplish this feat using confirm boxes, but the client says that they are too ugly. I've tried using unload and beforeunload, but both cannot stop the page from being redirected. Using those to events, I return false, so maybe there's a way to cancel other than returning false?
Another solution that I've had was redirecting them to another page that has my popup, but the problem with that is that if they do want to leave the page, and it wasn't a mistake, they lose the page they were originally trying to go to. If I was a user, that would irritate me.
The last solution was real popup window. The only thing I don't like about that is that the main winow will have their destination page while the pop will have my page. In my opinion it looks disjoint. On top of that, I'd be worried about popup blockers.
Just to add to everyones comments. I understand that it is irritating to prevent users from exiting the page, and in my opinion it should not be done. Right now I am using a confirm box at this point. What happens is that it's not actually "preventing" the user from leaving, what the client actually wants to do is make a suggestion if the user is having doubts about registering. If the user is halfway through the registraiton process and leaves for some reason, the client wants to offer the user a free coupon to a seminar (this client is selling seminars) to hopefully persuade the user to register. The client is under the impression that since the user is already on the form, he is thinking of registering, and therefore maybe a seminar of what he is registering for would be the final push to get the user to register. Ideally I don't have to prevent the user from leaving, what would be just as good, and in my opinion better is if I can pause the unload process. Maybe a sleep command? I don't really have to keep the user on the page because either way they will be leaving to go to a different page.
Also, as people have stated, this is a terriable title, so if someone knows a better one, I'd really appreciate it if they could change the title to something no so spammer inviting.
As soon as I saw the words "prevent the user" I started to wail in agony. Never prevent the user, only help them.
If they see your registration page and run off, that's their choice. Pop up a javascript confirm box if they've already filled in some data (because they might be navigating away accidentally) but leave it at that. If they haven't touched the form, leave them alone - they don't want to fill in your form.
Look at other methods of engaging users. If your form is huge and scary, break it into simple manageable chunks or better yet, simplify things so much that the user only gives you data when you need it. For example, you might not need their address until you want to post something to them.
By breaking it into multiple parts you can hook them with a simple form and once they've invested that time, they'll be more likely to continue the process.
But don't harass users. If they don't want to register, pestering them with pop-ups and jaavscript dialogues will just chase them off the site completely.
With that in mind, assuming you're just trying to stop people half-filling-in forms, there are a couple of options to genuinely help people:
Detect if the form has changed and ask them a simple confirm() message.
This is all you can do. A CSS "pop-in" just won't work because you can't control* the window location in the unload event.
*You can put an event listener on all your page's links to fire off something to check the form, but this only helps if the user clicks on one of those links. It won't help if, for example, the user clicks back or closes the window. You could do both CSS and javascript but you end up with a bit of a mess.
Persist the state of the form behind the scenes.
An extension to #1. Instead of squabbling with the user, let them go where they want but save the content of the form either to session or cookie (if it'll fit) and put something on the page (like SO's orange prompt bars at the top of the page) that reminds them that they've started filling in a form and gives them a link back to the form.
When they click that link, you load the data out of the cookie (or session) back into the form and let them carry on. This has the clear benefit of letting them do what they like on your site and keeps the data safe.. ish.
If they don't come back and their cookie/session expire, that's their fault. You can only lead a horse to water. It's not your job to force it to drink.
Don't do it.
But if you want, try this. Record mouse positions and detect a quick upward thrust -- the user is reaching for the BIG X or the top left or top right. Now might be your chance for an unobtrusive box in the screen.
I've seen this implement on the web and it is evil.
If you want to trap links, you could rewrite the links in the page to go to a "you really want to leave?" javascript function, passing the destination URL as an argument.
If you wanna keep users from using their "Back" button, or keep them from putting another URL in the address bar, stop. Stop now. (1) Browsers were made to prevent exactly that kind of obnoxious behavior, and (2) Even if they allowed it, see the last two words of (1). It's freaking rude. Your site is not that special, no matter how cool you think it is.
window.onbeforeunload = function() { return "Message"; };
Use a JavaScript like this to display a leave confirmation message.
Here are just a couple of approaches I could think of but they are not without flaw:
Whatcha Gonna Do technique
Detect the mouse position going towards the edges of the browser as the user might be going to close the tab, window, go back, navigate elsewhere among other things. If so, immediately prompt them that that may be a mistake and they are going to lose out on something very valuable. However, the catch here is that you don't know for sure what their intentions were and you might piss them off with that popup. Also, they might use a bunch of shortcuts such as Ctrl+W etc to do the same.
You've Got Mail technique
If you've managed to get hold of the user's email address before they closed the page, you've hit a jackpot. As soon as the user types anything into the email box and then leaves it, immediately send it to the server using AJAX. Save the state of the page into localStorage or on the server using a cookie or something so it can be recreated later. Every couple of hours send them an email giving them a direct link to the previously saved form, and maybe with special offers this time.
History Repeats Itself technique
Then there's the infamous history manipulation where you keep stacking the current page into the document history so the back button renders effectively worthless.
Don't Put All Your Eggs In One Basket technique
Another technique off the top of my head is to create multiple windows in the background with the registration form and keep them all in sync when any the fields in any one changes. This is a classical technique and really puts the "don't put all your eggs in one basket" saying into real-life usage.
Another advantage of this awesome technique is even if the user closes one of the windows, and later comes across an identical cloned window with all the fields they filled up-to-date populated, they might get confused and think that they never closed the page. And guess what, this time they might just go ahead and fill out the registration form. But you have to be cautious with this as anything more than 2 or 3 clones will make it obvious as to what's going on.
You're Winner technique
Another technique is to tell every user they they are the Xth visitor on the site and use a good rounded number for X such as 1000, 10000, 50000, etc. Tell them that they can claim their prize once they register on the site. Imagine how special each user feels when they land on your site. The prize doesn't have to be anything tangible, it can simply be free coupons that you find on the intertubes.
Where Do You Want To Go Today? technique 1
This is basically a rip-off of your answer. Use document.location.href = 'some url' inside your onbeforeunload callback to navigate to a different page before it is unloaded.
1 Firefox only.
Note: there is no silver bullet solution here unless you write your own browser with your own security policies, but these are all optimizations that you can do to make it utterly impossible for users to leave.
Not all browsers support a modal popup, without which your page would go ahead and navigate anyway.
This is real awful requirement. The sort of requirement that is reasonable in a desktop application but entire unreasonable feature of a web site. Imagine being unable to leave a website.
The answer is either use the horrible confirm box and lump it. Or don't ask the user to enter too much data per page. Use a step by step wizard style data entry, the loss due to accidental navigation is minimised.
You can change the Value of the url using document.location.href = "www.website.com"
I can accomplish this feat using confirm boxes, but the client says that they are too ugly.
If the problem is the ugliness of the standard JS popup boxes, try something like this: http://www.sohtanaka.com/web-design/inline-modal-window-w-css-and-jquery/
Apart from that I second what most people are saying: do this with extreme caution if you don't want to lose users.

Cancel service call in Dojo

I want to know if it is possible to cancel a call to a webservice using Dojo. My problem is, e.g., that the user has many elementes to select in a map, and every time he clicks on one of them a call to a webservice is excuted to bring an important volume of data. This operation takes a few seconds of latency. Imagine that user clicks on five elements almost simultaneously: there will be a selected element (the last clicked), but the info panel will be refreshing periodically with the info of the previous elements clicked until the last element info is loaded.
What I want is to cancel all the previous calls (if it possible) and only allow to complete to the last one. I'm working with Dojo. I've seen the documentation but I haven't seen anything useful. Something like the "ajax.abort()" method is what I would expect to find.
I have also thought to create a class to manage the calls and add to a queue every call to a same url in order to only let the last call to render the data, but by this way I still would to wait to complete every service call and then discard the results. I think that the proper way to proceed is to cancel the old calls.
Any suggestion? Thanks.
After search in some forums and pages, I've found this one: www.mike-griffith.com - Cancel dojo XHR in progress. This is exactly what I was looking for (although in the web example is used to "GET" services, the "cancel()" method also works for "POST" calls).
So I will combine the service calls manager with this code to cancel calls with the same url. I also have to manage how to avoid (if I am able to) the raised error when a call is canceled, but this is other task and much less priority.

Synchronizing DataGridView (DataTable) with the DB

I have the following situation: there is a table in the DB that is queried when the form loads and the retrieved data is filled into a DataGridView via the DataTable underneath. After the data is loaded the user is free to modify the data (add / delete rows, modify entries).
The form has 2 buttons: Apply and Refresh. The first one sends the changes to the database, the second one re-reads the data from the DB and erases any changes that have been made by the user.
My question is: is this the best way to keep a DataGridView synchronized with the DB (from a users point of view)?
For now these are the downsides:
the user must keep track of what he is doing and must press the button every while
the modifications are lost if the form is closed / app crash / ...
I tried sending the changes to the DB on CellEndEdit event but then the user also needs some Undo/Redo functionality and that is ... well ... a different story.
So, any suggestions?
I would say that the way you are currently doing it is fine. If you start attempting to update the database while the user is still making edits you can run in to issues updating or modfiying things that the user may ultimately decide they did not want to change. Additionally this has the chance to greatly increase the number of database calls.
Forcing the user to click apply helps ensure that only the changes the user actually wants are sent to the database.
As for losing the changes if the app crashes before applying them, I would be more concernced with why the app is crashing.
The only important thing to remember is that you should refetch the data before saving it and the refetched data should still match the data you originally displayed to the user. If it doesn't, someone else made a change your user will be unknowingly overwriting. Your users probably will not like that.
How you handle this is dependent on what your client needs in their database.

where do functions that don't display go in django

I have some links on an html page like , , currently I handle them as so
<p> rate down
and have a url.py entry:
(r'^cases/(?P<case_id>\d+)/case_rate/(?P<oper>.)$', 'mysite.cases.views.case_rate'),
then I have a view function that handles the logic and hits the DB, then does this:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
I's there a better way to do this? I can see how this would be OK because it does have to redraw the screen to show the new rating...
The typical way to handle this is with an ajax request.
Instead of a link, you put a javascript handler that calls a view, wich updates the db, and returns a json / xml object with the new rating for the item. Then another javascript handle receives that response and updates the rating number on the screen, without a page reload.
Ideally, you'll keep both versions: plain html (the one you currently have) and the ajax one. The ajax one can be attach to the element after page load, so if javascript is not available, you'll still have a working site.
Then, regarding organization, you can have an "ajax" parameter on your view. The view should update the db accordingly, and if it's an ajax call, return the json / xml response, otherwise, return the new page. That way you can keep the logic (fetching the object, updating the db) on one place.
If you're asking whether case_rate should still go in the views.py given that it returns a redirect rather than providing content, the answer is yes, since case_rate is handling an request and returning a response.
But consider a situation where you had two view functions in views.py that had some duplicate code, and you chose to factor that duplicate code into another function that didn't both take request and return a response. Would that be fair game to leave in views.py? Sure, if moving it elsewhere would make the code harder to read. Or you might choose to put it elsewhere. It's really your call based on your sense of taste.