Noob needs help with event handling

1 view
Skip to first unread message

Rhiq

unread,
Nov 6, 2009, 2:14:49 PM11/6/09
to Prototype & script.aculo.us
I'll try to explain what I am up to; feel free to slap me if I am
really messing this up.

I have a table that represents orders in a database, and it seems to
be working fine. When the user clicks on an order a div is updated
using an Ajax.updater call. This works well, the information is some
html code that gives details of the order. It includes an edit link,
and when the user clicks this another Ajax.updater updates the same
div - this time with a form. That seems to work will to.

Here is the problem that I am running into. When the submit button is
clicked, I want the data to be saved and the div to by updated again
with the refreshed order details. I can't seem to come up with a way
that works.

I have tried attaching an "onSubmit" observer to the form, but it
doesn't seem to work. In the edit link I had to wimp out and actually
use an "onClick=editOrder(OrderID)" right in the <a> tag. That won't
really work with the form submit...or probably it will but "I" haven't
been able to make it work.

At this point, I know there is a better way. Could anyone share it
with me?

The other question I have is how to attach an observer to a
dynamically created element - like my form?

Here is one of the many things that I have tried - this function is
called at the end of the function that updates the <div> with the form
for editing:

function detailChanges() {
if($("editOrder") != undefined) {
$('editOrder').observe('submit', saveOrder)
}

if ($('editDate') != undefined) {
var opts = {
formElements:{"editDate":"m-sl-d-sl-Y"}
};
datePickerController.createDatePicker(opts);
}
}

"editOrder" is the id and name of the <form> while the "editDate" is
an <input> passed in with the rest of the form. "editDate" will be
found (though getting the datepicker to work is a thread for another
day) but the "editOrder" form is never found.

Thanks for any help.

N

ColinFine

unread,
Nov 9, 2009, 8:51:43 AM11/9/09
to Prototype & script.aculo.us


On Nov 6, 7:14 pm, Rhiq <ndba...@gmail.com> wrote:
> I'll try to explain what I am up to; feel free to slap me if I am
> really messing this up.
>
> I have a table that represents orders in a database, and it seems to
> be working fine.  When the user clicks on an order a div is updated
> using an Ajax.updater call.  This works well, the information is some
> html code that gives details of the order.  It includes an edit link,
> and when the user clicks this another Ajax.updater updates the same
> div - this time with a form.  That seems to work will to.
>
> Here is the problem that I am running into.  When the submit button is
> clicked, I want the data to be saved and the div to by updated again
> with the refreshed order details.  I can't seem to come up with a way
> that works.
>
Do you mean that *instead* of doing an HTML submit (which always does
a GET or POST fetch of the whole page) you want to do an Ajax
operation which only refereshes the div?

In that case, don't use a 'submit' input at all: use a button (you can
call it 'submit' if you like) and observe it with a 'click'.
If you are concerned about getting all the inputs from from form, see
Form.serialize().

> The other question I have is how to attach an observer to a
> dynamically created element - like my form?
>
Either include some Javascript in the HTML you send from the Ajax
request, to set up an event handler (use Element.observe() rather than
the HTML 'onClick' property - in this case you will need to set
'evalScripts: true' in your Ajax.Updater options

Or, the better solution is to attache a handler to an element which
doesn't change (your <div> probably) and delegate handling.

If you say

$('mydiv').observe('click', function(ev) {
var input = ev.findElement('input');
if (input) ...

then any pick on your div, irrespective of how many times its contents
have changed, will call that function (which I've written inline, but
could be a named function), which will check whether the pick was
actually inside an <input> element - any <input> element - and if so
take action.

Walter Lee Davis

unread,
Nov 9, 2009, 9:40:46 AM11/9/09
to prototype-s...@googlegroups.com

On Nov 9, 2009, at 8:51 AM, ColinFine wrote:

>
>
>
> On Nov 6, 7:14 pm, Rhiq <ndba...@gmail.com> wrote:
>> I'll try to explain what I am up to; feel free to slap me if I am
>> really messing this up.
>>
>> I have a table that represents orders in a database, and it seems to
>> be working fine. When the user clicks on an order a div is updated
>> using an Ajax.updater call. This works well, the information is some
>> html code that gives details of the order. It includes an edit link,
>> and when the user clicks this another Ajax.updater updates the same
>> div - this time with a form. That seems to work will to.
>>
>> Here is the problem that I am running into. When the submit button
>> is
>> clicked, I want the data to be saved and the div to by updated again
>> with the refreshed order details. I can't seem to come up with a way
>> that works.
>>
> Do you mean that *instead* of doing an HTML submit (which always does
> a GET or POST fetch of the whole page) you want to do an Ajax
> operation which only refereshes the div?
>
> In that case, don't use a 'submit' input at all: use a button (you can
> call it 'submit' if you like) and observe it with a 'click'.
> If you are concerned about getting all the inputs from from form, see
> Form.serialize().

There's a great shortcut method in Prototype: Form#request().[1] It
takes a normally-wired form and "hijacks" it to send via Ajax. Then
it's up to your server to return a lump of JavaScript to update the
DIV in question if the form was submitted via Ajax.

It also follows the general usability guideline (dare I say RULE?)
that says -- first make it work, then make it pretty. By that I mean
that someone coming to your site without JavaScript should be able to
get along fine with everything you expect JavaScript to do, they just
won't have as "pretty" an experience of it. So your "click to load a
form" effect should lead to another page containing that form, and
your Ajax form submit should load back the original page with the
updated DIV in place, rather than just quietly updating the DIV
without a page refresh.

So let's say you have injected a form into your page:

<form action="form_handler.php" id="myForm" method="post">
<input type="text" name="foo" value="<?=$foo?>" />
<input type="submit" value="update" />
</form>

You would wire it to submit by Ajax thusly:

$('myForm').observe('submit',function(evt){
evt.stop();
var div = this.up('div'); //or whatever you want to update
this.request({
onComplete:function(transport){
div.update(transport.responseText);
},
evalScripts:true
});
});

Request takes care of the parameters for you -- everything about the
form that is already set in the source will behave exactly the same
way, except that the form submission will happen over the Ajax pathway
rather than a normal submission.

>
>> The other question I have is how to attach an observer to a
>> dynamically created element - like my form?
>>
> Either include some Javascript in the HTML you send from the Ajax
> request, to set up an event handler (use Element.observe() rather than
> the HTML 'onClick' property - in this case you will need to set
> 'evalScripts: true' in your Ajax.Updater options
>
> Or, the better solution is to attache a handler to an element which
> doesn't change (your <div> probably) and delegate handling.
>
> If you say
>
> $('mydiv').observe('click', function(ev) {
> var input = ev.findElement('input');
> if (input) ...
>
> then any pick on your div, irrespective of how many times its contents
> have changed, will call that function (which I've written inline, but
> could be a named function), which will check whether the pick was
> actually inside an <input> element - any <input> element - and if so
> take action.

Hope this helps,

Walter


1. http://api.prototypejs.org/dom/form.html#request-class_method

Rhiq

unread,
Nov 9, 2009, 6:22:48 PM11/9/09
to Prototype & script.aculo.us
Thanks! Using the advice of both responders I was able to get it
working just how I wanted :D

n
Reply all
Reply to author
Forward
0 new messages