SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Wizard Wolf_22's Avatar
    Join Date
    Jul 2005
    Posts
    1,710
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Using load() within ready() and changing markup IDs of those loaded...

    I'm trying to use <element>.load() within a document.ready() block to dynamically load specific elements from another page (on the same server) and from those loaded, add an ID to the elements by using either attr() or prop(). Here's the problem: attr() and prop() will not add the ID to save my life. They just won't, and from what little I understand about this, it boils down to having to do with how the elements have been loaded. For example, there's something I read somewhere about how elements that get loaded this way have to be "bound" using something like live() or bind() before any changes can be made to the elements. Is this true?

    Here's my code:
    Code:
    $(document).ready(function(){
        $('#r div form[name="loginform"]').load('foobar.htm #UserID, input[type="password"], input[type="submit"]');
        $('#r div form[name="loginform"] input[type="submit"]').prop('id', 'submit');
    });
    The first line ensures the document is done loading before anything else... No biggy there. The next line loads the login form elements (#UserID, password input, and the submit button) into the current page from the foobar.htm. It puts these into a form element. The next line I'm trying to use to change the new submit button's ID... But no dice.

    It just won't work! No matter what I do... I've even tried to light some candles and poke some needles into some effigies... Just... Won't... Work. And since I don't know enough about binding things in jQuery / JavaScript, I'm hoping someone on here knows enough about this kind of approach to shine some light.

    What am I doing wrong?

    Note: When outputting the resulting "ID assignment attempt" using console.log as follows, it comes back as undefined:
    Code:
    console.log($('#r div form[name="loginform"] input[type="submit"]').prop('id'));
    Help is VERY appreciated here. It's so frustrating.

  2. #2
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,890
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Hi there,

    what about using .ajaxComplete()?

    Code JavaScript:
    $(document).ready(function(){
      $('#r div form[name="loginform"]').load('foobar.htm #UserID, input[type="password"], input[type="submit"]');
      $('#r div form[name="loginform"]').ajaxComplete(function() {
        $('#r div form[name="loginform"] input[type="submit"]').attr('id', 'submit');
      })
    });

    This should hopefully work in your case.

  3. #3
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,036
    Mentioned
    152 Post(s)
    Tagged
    2 Thread(s)
    @Pullo ; is heading in the right direction, but .ajaxComplete is a bit too much here. .ajaxComplete responds to every AJAX request that is ever fired, not just the one(s) started on the object.
    Fortunately, there's a relatively simple alternative; just use a callback function to jQuery.load:

    Code javascript:
    $(document).ready(function() {
      $('#r div form[name="loginform"]').load('foobar.htm #UserID, input[type="password"], input[type="submit"]', function() {
        $('#r div form[name="loginform"] input[type="submit"]').attr('id', 'submit');
      });
    });

    The problem with your script was that the javascript doesn't wait for .load to be ready, but just goes on to the next line. At that point the new data hasn't been loaded yet, so nothing can be done.

    As an aside, those selector's you're using look pretty overkill. Since #r is an ID, you should be able to just use the following:

    Code javascript:
    $(document).ready(function() {
      $('#r form[name="loginform"]').load('foobar.htm #UserID, input[type="password"], input[type="submit"]', function() {
        $('#r input[type="submit"]').attr('id', 'submit');
      });
    });
    Rémon - Hosting Advisor

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  4. #4
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,890
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    Fortunately, there's a relatively simple alternative; just use a callback function to jQuery.load
    Wow, that's cool. I didn't know you could do that.
    Thanks, Rémon.

  5. #5
    SitePoint Wizard Wolf_22's Avatar
    Join Date
    Jul 2005
    Posts
    1,710
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the info, guys. I really appreciate it and I was able to have better control over the elements with the above suggestions.

    Rémon, could you elaborate a bit on why load() wasn't being executed after the page finished loading? I'm a little confused about that part... Are you saying that I didn't call / execute it correctly or that it just needed something extra to it to make it function correctly (i.e. - your callback). I guess I'm just not understanding why that callback was so important in this... :S

  6. #6
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,890
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Wolf_22 View Post
    ... could you elaborate a bit on why load() wasn't being executed after the page finished loading? I'm a little confused about that part... Are you saying that I didn't call / execute it correctly or that it just needed something extra to it to make it function correctly (i.e. - your callback). I guess I'm just not understanding why that callback was so important in this... :S
    That's actually quite straight forward:
    You want to load elements from an external file via Ajax.
    So, in your script you fire of an asynchronous request (using .load()) to go get these elements.
    However, while that request off doing what you asked it to do, execution continues in your main file.
    The next thing your code does is try to manipulate the elements you're attempting to fetch.
    Yet the request still hasn't completed at this point, so the elements simply aren't present in the DOM.

    Using a callback is a way of telling JavaScript to wait until it has finished fetching the elements, before doing something with them.

    I hope that makes sense. If not, I'm sure Rémon can explain it better

  7. #7
    SitePoint Wizard Wolf_22's Avatar
    Join Date
    Jul 2005
    Posts
    1,710
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, I guess that does make sense but how would one know to suspect something like that? I mean, how would one know something like that is responsible? I'll have to go look again at the jQuery write-up about that function to see what's mentioned about it because it seems logical to me to think that load() *should* have some form or feature which says, "...don't continue until you're finished," as most functions seem to do. I mean, most functions seem to return something. Does load? And if so, shouldn't a return of data indicate that it's finished loading whereby execution of the script would continue?

    (Again, I'll need to go look at the load() jQuery page again, but I guess I'm just "thinking out loud.")

  8. #8
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    There are a number of calls in JavaScript that work asynchronously - which means that they don't wait for the call to finish before running the code that follows them. When your JavaScript or the jQuery processing you are calling uses an asynchronous command you need to use a callback function to define what is to be run using whatever the call eventually returns.

    Perhaps the simplest example is the setTimeout command which simply adds the callback function you specify in the first parameter to the queue of commands to run after the time specified in the second parameter has elapsed.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  9. #9
    Grüße aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,890
    Mentioned
    211 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by Wolf_22 View Post
    Yeah, I guess that does make sense but how would one know to suspect something like that?
    It helps to read the api documentation, where you can read which parameters it can take:

    .load( url [, data] [, complete(responseText, textStatus, XMLHttpRequest)] )
    url - A string containing the URL to which the request is sent.
    data - A map or string that is sent to the server with the request.
    complete(responseText, textStatus, XMLHttpRequest) - A callback function that is executed when the request completes.

    As you can see, the last parameter gives you the clue you need.

    Please don't get me wrong, I'm not telling you to RTFM.
    This was something I had to learn to do myself (i.e. to read the docs), but since I have started doing this, I am amazed at how much more effective I have become.

    My initial answer to your question (incorrect as it was) also proves the validity of this method.
    Had I first looked at the documentation I would have seen what Rémon pointed out.
    Instead I googled something like "manipulate DOM elements after load()", found something about ajaxComplete() on Stack overflow, checked it worked and posted my answer.

    Hope this helps


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •