Re: [Proto-Scripty] Attach Ajax.Updater to link

59 views
Skip to first unread message

Walter Lee Davis

unread,
Oct 28, 2012, 11:53:31 AM10/28/12
to prototype-s...@googlegroups.com

On Oct 28, 2012, at 4:15 AM, donnek wrote:

> I'm new to Prototype, and I'm trying to use AJAX to update divs inthe background, pulling data from a database. I've got Ajax.Updater to work with the output of a form, but I'm having difficulty with adpting it for use with a link. Basically, I have a list of words produced by the db, each of them a clickable link, and when I click on the word I want the context of the word (likewise drawn from the db) to come up in a div below the list.
>
> What I have at the minute:
>
> calling page:
> <div><a href="javascript:void(0);" class='textword' id='myword1' onclick="get_word()">myword1</a></div>
> <div><a href="javascript:void(0);" class='textword' id='myword2' onclick="get_word()">myword2</a>
> <div id="output">[Results appear here.]</div>
> <script>
> function get_word()
> {
> new Ajax.Updater
> (
> 'output',
> 'mylist.php',
> {
> method: 'get',
> parameters: { word: $(this).attr("id") }

I'm pretty sure your problem is right here. There's no attr() method in Prototype. Try readAttribute() instead, and you appear to have everything right besides.

Walter

> }
> );
> }
> </script>
>
> mylist.php:
> [db connection stuff]
> $word=trim($_GET['word']);
> $sql=query("select * from mytable where word~'$word';");
> while ($row=pg_fetch_object($sql))
> {
> echo $context."<br />";
> }
>
> Run by itself, mylist.php gives the results I want, so I think I haven't got the right invocation for the link, but after several hours searching and experimenting, I have to ask!
>
> --
> You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/prototype-scriptaculous/-/z616OxDuu6oJ.
> To post to this group, send email to prototype-s...@googlegroups.com.
> To unsubscribe from this group, send email to prototype-scripta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.

donnek

unread,
Oct 28, 2012, 12:05:02 PM10/28/12
to prototype-s...@googlegroups.com
On Sunday, 28 October 2012 15:53:37 UTC, Walter Lee Davis wrote:
I'm pretty sure your problem is right here. There's no attr() method in Prototype. Try readAttribute() instead, and you appear to have everything right besides.

Thanks, Walter, but unfortunately changing that line to:
            parameters: { word: $(this).readAttribute("id") }
doesn't help.

Walter Lee Davis

unread,
Oct 28, 2012, 12:08:35 PM10/28/12
to prototype-s...@googlegroups.com
What does Firebug say your request looks like? What does your server respond with?

Walter

donnek

unread,
Oct 28, 2012, 3:23:54 PM10/28/12
to prototype-s...@googlegroups.com


On Sunday, 28 October 2012 15:53:37 UTC, Walter Lee Davis wrote:
What does Firebug say your request looks like? What does your server respond with?

TypeError: $(this).readAttribute is not a function

Walter Lee Davis

unread,
Oct 28, 2012, 4:32:27 PM10/28/12
to prototype-s...@googlegroups.com
Okay, that means that 'this' inside the Ajax.Updater is not set to what you think it is. Try this:

function get_word(elm)
{
new Ajax.Updater
(
'output',
'mylist.php',
{
method: 'get',
parameters: { word: $(elm).readAttribute("id") }
}
);
}

call it with get_word(this) in your inline handler example.

A much neater way to handle this is with an unobtrusive handler. For this HTML (note the differences):

<div><p class='textword' id='myword1'>myword1</p>
<p class='textword' id='myword2'>myword2</p></div>
<div id="output">[Results appear here.]</div>

could be handled with this JavaScript:

<script type="text/javascript">
document.observe('dom:loaded', function(){
document.on('click','.textword', function(evt, elm){
new Ajax.Updater(
'output',
'mylist.php', {
method: 'get',
parameters: {
word: elm.readAttribute('id')
}
}
);
});
});
</script>

Much cleaner and fewer global variables are massacred.

Walter

On Oct 28, 2012, at 3:23 PM, donnek wrote:

>
>
> On Sunday, 28 October 2012 15:53:37 UTC, Walter Lee Davis wrote:
> What does Firebug say your request looks like? What does your server respond with?
>
> TypeError: $(this).readAttribute is not a function
>
> parameters: { word: $(this).readAttribute("id") }
>
> There's no change to the calling page - it shows nothing in the "output" div.
>
> --
> You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/prototype-scriptaculous/-/23HHumtY6uYJ.

donnek

unread,
Oct 28, 2012, 5:51:17 PM10/28/12
to prototype-s...@googlegroups.com
On Sunday, 28 October 2012 20:32:34 UTC, Walter Lee Davis wrote:
Okay, that means that 'this' inside the Ajax.Updater is not set to what you think it is. Try this:
<snip>

Much cleaner and fewer global variables are massacred.

Hey, thanks!  Both of those work. But I don't understand what "elm" (not the tree, I assume!) and "evt" are/do.  And why is the second cleaner (because I find the first easier to understand).  Thanks again for taking the time on this.

Walter Lee Davis

unread,
Oct 28, 2012, 6:06:29 PM10/28/12
to prototype-s...@googlegroups.com
I use elm to stand for element, and evt to stand for event. It's just a habit I have, to keep clear in my head what I am dealing with when I use an observer or an iterator.

If I am iterating over a collection of elements with each, I will usually write this:

$$('.foo').each(function(elm){
/* do something to elm here */
});

Using elm here reminds me that I am dealing with an element, rather than an event, and that I will have direct access to the element.

Using the same collection and observing the click on it, I would write this:

$$('.foo').invoke('observe', 'click', function(evt){
// inside here, evt is the click event
evt.stop();
// and 'this' is the element that received the click: one of the .foo elements
this.highlight();
});

I prefer unobtrusive observers for several reasons.

First, they remove the masses of repeating inline code from the HTML, where all it does is bloat the page without adding any value. Any time you find yourself writing the same thing more than once, that's an opportunity for improvement.

Second, if your observer is all in one place, you can make sweeping changes without having to go back and rewrite every invocation of the method. Imagine if you changed your function definition to need two variables passed to it rather than one. With your method, that means touching every row of your interface, while with mine, you just rewrite it in one place.

Walter
> --
> You received this message because you are subscribed to the Google Groups "Prototype & script.aculo.us" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/prototype-scriptaculous/-/eGR_Yuma92gJ.

donnek

unread,
Oct 29, 2012, 5:08:49 AM10/29/12
to prototype-s...@googlegroups.com
On Sunday, 28 October 2012 22:06:35 UTC, Walter Lee Davis wrote:
I use elm to stand for element, and evt to stand for event. It's just a habit I have, to keep clear in my head what I am dealing with when I use an observer or an iterator.
<snip>
 
I see - that seems like a very good habit for me to copy!

I prefer unobtrusive observers for several reasons.

First, they remove the masses of repeating inline code from the HTML,
<snip>


Second, if your observer is all in one place, you can make sweeping changes without having to go back and rewrite every invocation of the method.
<snip>

Again, that makes a lot of sense, expecially now I've read over everything again this morning.

Thanks again for your help, Walter - I spent most of Friday on this, and wouldn't have worked it out on my own.
Reply all
Reply to author
Forward
0 new messages