EntropySink

Technical & Scientific => Programming => Topic started by: ober on October 31, 2012, 11:46:51 PM

Title: JQuery and DOM
Post by: ober on October 31, 2012, 11:46:51 PM
Maybe this is flawed design, but I don't think it is.  I have 3 fields on form.  The first is an autocomplete field pulled from the database and stored in javascript so there is no ajax on that field.  They type and it gives them the matching results from the javascript array.  Simple.

THEN, on the 'change' jquery event (selecting an option), I use ajax to go and create the select for the next field and dump the output of the entire select tag into a div.  The select tag appears with all the options and I can see it in Firebug.

I then need to trigger a similar event for the 3rd field but it's not happening.  So I'm wondering if it just can't find the object or it can't trigger the event because the object doesn't exist when the page is created.  I use the following call which is in my document ready function:

Code: [Select]
$( "#client" ).change(function(){
           
            var client = $("#client").val();
            $.ajax({
                url: "sources/ticketform/backendClient.php",
                data: "client="+client+"&action=accts",       
                type: "GET",
                dataType: "html",                                                                 
                success: function( data ) {       
                    $("#acctreturn").html(data);                       
                },
                error: function(message) {                       
                    $("#acctreturn").html('None Found');
                }
            });               
                       
        });

Anytime I change that dropdown (#client), it doesn't do anything.  I also don't get any errors.  Help :(
Title: Re: JQuery and DOM
Post by: Mike on November 01, 2012, 12:24:28 AM
First, which version of jQuery are you using?  It matters for the exact jQuery calls to make.  With jQuery 1.7+ you should use on() (http://api.jquery.com/on/)
Code: [Select]
$(document).on('change', '#client', function(){
// ...
});

This will handle registering the change handle regardless of when it is created.

Alternatively you can bind the change handler when you create the select element.
Code: [Select]
var select = $('<select></select>');
// Other stuff to setup the select and insert it into the dom
$(select).change(function()
{
  // Stuff
});
Title: Re: JQuery and DOM
Post by: ober on November 01, 2012, 12:29:36 AM
I'm using 1.9.  The on() method might be the way to go.

I'll try it when I get back into that code.  Thanks Mike!
Title: Re: JQuery and DOM
Post by: Mike on November 01, 2012, 12:31:19 AM
Shit 1.9 is out already?  Time to review the change logs.

NP man.  I've ran into that same problem with dynamically created elements.
Title: Re: JQuery and DOM
Post by: micah on November 01, 2012, 09:16:02 AM
have you tried just putting a simple alert() at the start of that function to see if its being triggered at all?

also, I'm pretty sure
Code: [Select]
var client = $("#client").val();could be:
Code: [Select]
var client = $(this).val(); though I suppose it doesn't matter (and certainly doesn't pertain to the problem you're having)
Title: Re: JQuery and DOM
Post by: ober on November 01, 2012, 10:16:07 AM
I keep forgetting that I can reference it using that way.  I haven't tried to use 'this' as much as I could so I'm probably inefficient in a few areas like that.  I will clean that up though.  Thanks for pointing it out.
Title: Re: JQuery and DOM
Post by: ober on November 05, 2012, 10:24:22 PM
Hey Mike, your trick worked.  But I'm curious... you use $(document) but I already have a 'document ready' function:
Code: [Select]
$(function() {
$('#createdate').datepicker({
showButtonPanel: true,
            changeMonth: true,
changeYear: true,
            dateFormat: 'yy-mm-dd'
});       
         
        var clientgroups = [
<?php
            $clientgroups 
ClientGroup::all();
            
$c = array();
            if(
count($clientgroups) > 0) {
                foreach(
$clientgroups as $key) {
                    
$c[] = $key->name;
                }
                echo 
'"'.implode('","'$c).'"';
            }            
            
?>

];
$( "#clientgroup" ).autocomplete({
source: clientgroups
});
 // etc.

So what is the difference and can I have both?  I mean obviously it's working... but still?
Title: Re: JQuery and DOM
Post by: Mike on November 05, 2012, 11:05:21 PM
Are you referring to
Code: [Select]
$(document).on('change', '#client', function(){
// ...
});

If so:  You are saying to monitor the tree with the root of (document) for any nodes that match the selector '#client' and to bind the event 'change'.  It is better to use a more localized subtree instead of root, for example the form.  If the form had an id of 'form' then you could do
Code: [Select]
$('#form').on('change', '#client', function(){
// ...
});

This only needed when the element is dynamically created.  Another example:  You get a set of data via ajax and build out a table.  In that table there are edit and delete links that are generated for each row.  You could do something like:
Code: [Select]
$('#table').on('click', 'a.edit, a.delete', function(){
// ...
});
Title: Re: JQuery and DOM
Post by: ober on November 06, 2012, 12:32:35 AM
Awesome.  Thanks Mike.

I guess my confusion was/is that I thought most JQuery stuff had to be in the 'document ready' function.  Is that not true?
Title: Re: JQuery and DOM
Post by: Mike on November 06, 2012, 12:47:08 AM
I usually just assume the document ready function.  Though there are some times when you need to hook into other pieces (like $(window).load()).  In this particular case you don't have to but I still would.