How to automatically process contents of <textarea> without user pressing a button? - ajax

On my page I have a textarea where users can enter a list of items, items being separated by a newline.
I would like to process the user's input without him/her having to press a submit button. ("Process" means send the information the user entered to the server and update other elements on the current page.) I thought of two days of doing this:
1- Install an event handler for keypress events and, when I get an event for the Enter key being pressed, process the line the user just completed. (Getting cursor position info as done here.) This has the disadvantage of not handling copy-pasting into the form. (And, if I understood correctly from browsing Stack Overflow, support for handling paste events is not great even among most common browsers, right?)
2- Periodically process the contents of the textarea by using setInterval(). I am already using a setInterval() on the page to implement the unique URLs pattern, so if I could I would avoid that.
Are there better ways to achieve this?

There is also an "onchange" event for a textarea. You can use it to detect any changes, including paste or magic inserts.

Related

Calling a child dialog and passing in input parameters

I've read a bunch of articles on how to call dialogs from javascript and integrate them into a ribbon button, but I am running into a problem where I need to do all that AND pass in a string as an input parameter (to a child dialog?).
Is this possible? Would I have to modify the calling url of the dialog?
I've read this one about calling dialogs with the SelectedControlAllItemsId, which is almost what I need.
Ideally I would open the form of the parent entity, click on one of the subgrids in the left hand navigation, then select some of the related/associated entities, click the ribbon button and wait for the dialog or workflow to chew through all of those Ids.
Is it possible to capture these selected items using SelectedControlAllItemsId, then pass that string to a child dialog so it can then call another workflow? Or should I capture that string, store it in the calling record via REST and then let a workflow run on a field-trigger?
The end result is that I must run a custom workflow and manipulate the parent record + the selected related records. I have already written the workflow, but I do not know how to trigger it the way I want.
Perhaps there is something I am overlooking? Is there a way to call a custom bit of code directly from javascript and let it work the rest of the way?
I'm not sure how an interactive dialog should deal with a collection of records. Surely that would require sequential iterations of the dialog, as the user processes each record? As you will see from the SDK (and discussed in your linked thread), it is only possible to run a dialog against a single record.
A workflow is a different matter.
- Custom ribbon button, using SelectedControlAllItemsId
- Supporting JScript handler should iterate SelectedControlAllItemsId
- Each iteration should issue an ExecuteWorkflowRequest using the current item id and based on code such as this (which issues an ExecuteWorkflowRequest from JScript
Remember that the workflow request is asynchronous so you can just send all the requests one after another rather than waiting for the outcome of each request.

AjaxFormValidatingBehavior Performance and Lost focus on Firefox

My project is using Wicket's AjaxFormValidatingBehavior to auto-save form content to Session on sort of a multi-tab form with a tree menu (there is no save button on individual tabs, though there is a "Save" button that actually submits the form, runs the validations and saves contents to database). I am facing few issues:
Since the behavior is added to all form components' onChange event, there is a server-trip every time user moves from one field to another. I know that a throttle duration can be specified to prevent this, but its not possible to set in my case as my forms are of different lengths/complexity, many components dynamically generated (including the tree menu). But is there a more elegant solution to auto-save form content (that doesn't have a submit button) rather than this annoying solution.
Another issue I am facing is that post onChange event, on Firefox the component loses its focus after the "server trip" ends. While on IE7 it works fine.
For the first question I think you need to add a pipelining facility, on your components' onchange call a javascript function of your which calls your webapp. You can include a feature similar to the one provided with the throttle duration but page-wide (delay each calls and only trigger the last if it is older than x milliseconds for example).
For the second one, I think you have to use the AjaxRequestTarget#focusComponent in your behaviors, or handle this thing in your "wrapper" as described in the first answer.

Joomla handling multiple ajax forms on the same page

I'm using Joomla to develop a user profile management component with AJAX.
The goal is to allow the user to edit his own user information. There is a lot of information so instead of having one massive form, I decided to make "subforms" or sections. And for the whole thing to be user-friendly I want to send the forms and refresh the user information with AJAX.
Here's an example :
There are two sections, "Basic user info" which displays the first name, the last name and the age of the person and "Extended user info" which displays the occupation, the company and the skills of the person. Each section has an "edit" link (or button) which turns the content into a form (AJAX) allowing the user to modify the presented information. You can only edit one section's information at a time. When the user has finished modifying the data, he sends the form with a "send" link (or button) and the section gets back to simply displaying the information of the section (with the updates that were just made).
So I need to know what is the most efficient way to develop such a component. I thought of two approaches :
1) In the "tmpl" directory of the main component view we the following files :
default_basic.php (displays the basic user information),
default_basic_edit.php (displays the form which allows the user to edit the basic information)
default_extended.php (displays the extended user information),
default_extended_edit.php (displays the form which allows the user to edit the extended info)
default.php (loads each of the display subtemplates with calls to JView::loadTemplate($subtemplate))
When the user clicks on an edit link, an AJAX call is made to the following URI index.php?option=com_userinfo&view=userinfo&subview=basic_edit&format=ajax, which causes the view class to call $this->loadTemplate('basic_edit') after assigning the user information to it.
If the user clicks cancel the same process is used to load the 'basic' template again. And if the user modifies the information and clicks the send link, the form is sent and then the 'basic' template is loaded too.
2) There is only a "default.php" file in the "tmpl" directory which holds the edit version and the display version of each section. But all the edit versions are hidden at first. And when the user clicks on the edit link the display version of the section becomes hidden and the edit version is displayed (using display:none and display:block). Then, if the user clicks the cancel button we do the opposite. And if the user clicks the send button we send an AJAX request to update the data in the database and return the updated user info which will be loaded into the display version of the section. And we finally replace the edit version of the section with its display version.
I know there's a lot of text but in the end it goes down to choosing between refreshing full HTML blocks with AJAX, or just sending the updated info and modifying the content of hidden blocks and then make them appear. So what do you think is the most logical approach, knowing that we are in a Joomla 1.5 environment ? How would you procede ? (maybe there are other ways to create such a component ?)
(I tried both ways and I couldn't entirely make it work so I decided to ask to see if it is a matter of conception...)
Thank you for taking the time to read all the text.
My answer is: why even refresh parts when it can be done without it?
For example when we are talking about basic form elements like text fields and check/radio buttons I would prefer the following: on a successful save/send simply display a nice message like "Profile saved" for some seconds and the user is sure that the changes are save and sound.
In case I msissed somthing let me know.
I have tried both solutions and #2 is the only one that worked for me.

AJAX and prediction of actions

I'd like to ask your opinion on this. This is a theoretical question.
I'm in a situation where I have an interface shown to a user that uses AJAX to talk to the server. The server-side language does not matter here. I have a form with fields and each of them are deletable. If the user selects a few "delete" -checkboxes and presses Update, then I have these two options to do:
Option 1:
When deleting fields, use JavaScript to remove the HTML immediately and run AJAX on background to delete those fields. This achieves a look of a fast interface -> better user experience. However, if the AJAX call fails on the server side (the fields couldn't be deleted), then the previously deleted HTML fields would give a false assumption for the user (of them being deleted).
Option 2:
When deleting fields, run AJAX, depending on its success, either remove the HTML or do not. This gives accurate feedback for the user, but the form would freeze until the AJAX call finishes = slow(er).
What are your thoughts? Which approach seems better for me to take or should I make it an option?
Option 3: Mark the controls as being deleted (e.g. overlay a translucent gray box with a delete icon on it). Send the request. When it returns, either remove the controls, or change the box to show an error icon for a few seconds (then remove the box).
Allow the rest of the interface to be interacted with while this goes on.
Nice question.
A third option would be to :
disable immediately the controls
delete them when the Ajax returns
This gives the user feedback that something was effectively requested (responsiveness),
while showing also the moment where it is effectively completed.
Also, the user somehow feels the "distant call", which does not induce him in error, because it is was really happens. Anyway, there is nothing meaningful we can do to hide this feeling, because the delay will always be there.

Is it possible to persist (without reloading) AJAX page state across BACK button clicks?

I am familiar with several approaches to making the back button work in AJAX applications in various situations, but I have not found a solution that will work gracefully in my specific scenario.
The pages I am working with are the search interface for a site. You enter terms in a normal search box, click "go and wind up at a search results page. On the search results page there are a ton of UI controls for filtering/sorting the search results to find what you are looking for. Some of the operations triggered by these controls may take a (relatively) long time to complete (e.g. several seconds).
This latency is fine in case where the user is initially filtering/sorting their results... there's a nice AJAX spinner and so on... however when the user clicks on a search result and then clicks on the BACK button, I would like the page to instantly be restored to the state it was in when they clicked through.
I can restore the states using IFRAMEs/fragment identifiers as a dictionary of page history, but what ends up happening is that when the user first hits the back button the initial page is loaded, then it (re) makes the AJAX query to get the page state back, which triggers the AJAX spinner and another wait of possible several seconds.
Is there any approach that does not require this kind of two-stage load of the page when the user returns to the page via the BACK button?
Edited to add: I am partial to jquery but I'd be happy with solutions that depend on other libraries/toolkits or that are standalone/raw javascript.
Edited to add: I should've added that I'm trying to avoid cookies/sessions because this prevents people having multiple brower windows/tabs open and manipulating different sets of search results at the same time.
Edit: Matt, can you elaborate on your proposed solution (triggering a page change event via fragment identifer)? I see how this would help with BACK button clicks across the same page but not coming BACK to the search results page after clicking on a specific result.
Just use a cookie.
Have you investigated the YUI Browser History Manager?
Try to use localStorage object. Here is crossbrower libs jStorage and WEBSHIMS json-storage
Would it help to trigger a page change event using the "Add some info to the # at the end of the URL approach".
That way, clicking the back button shouldn't actually change the page, and you should be able to restore state without the first page load.
Use something persistent that is tied to the user's profile.
Cookies and sessions are good ideas, but you can also keep those stuff in the database. That gives you an added advantage of being able to save the user's filtering preferences accross different browsing session.(if, for exampple, he was looking for something in the office and then decided to continue searching when he is back at home).
It all depends on the complexity of the filters and weather or not it is something you think that the user will want to use accross diffrent browsing sessions..
Edited to add: I should've added that
I'm trying to avoid cookies/sessions
because this prevents people having
multiple brower windows/tabs open and
manipulating different sets of search
results at the same time.
You can create a random token and assign it to the fragment identifier.
on first page load create a token if no fragment identifier is set
before navigating out, store all the temporary ajax data in a cookie with that token as index.
when hitting back, if you have a fragment identifier set, load the data from the corresponding token in the cookie.
you can even add a "time" field to expire tokens, etc...
sample cookie (JSON):
{"ajaxcache":[{"token":<token>,"time":<time>,"data":<data>}, ... ]}

Resources