在表格中实现ajax保存

I'm implementing a virtual tour application, and want to add ajax functionality to the tour build process.

I have a number of mini-forms on the page, the number of which is determined by the count of images in a specified directory.

So the page currently looks like

---------------------------------------------------
|             |           Location   
|             |           Latitude
|  Thumb      |           Longitude       --------
|             |                           | Save |
|--------------                           --------
|
---------------------------------------------------
---------------------------------------------------
|             |           Location   
|             |           Latitude
|  Thumb      |           Longitude       --------
|             |                           | Save |
|--------------                           --------
|
---------------------------------------------------
---------------------------------------------------
|             |           Location   
|             |           Latitude
|  Thumb      |           Longitude       --------
|             |                           | Save |
|--------------                           --------
|
---------------------------------------------------

and goes on for n number of images.

What I'd like to do is have the save button execute an ajax function to save the information without refreshing the page. My issue has to do with the button IDs. As the form is rendered via PHP echo statements in a loop, I can add the loop number to the button ID, but how can I use said ID in a jquery function?

Specifically,

$("#save").click(function(){
  //ajax POST code goes here
});

won't work when the #save has a number added to the end.

What other options do I have to implement ajax functionality to these forms?

I would add a class to each button then attach the click event to that class and then find the ID that way. Then you can run your AJAX.

Like this:

$('.buttonClass').click(function (){
    var id = this.id;
    var $thisButton = $('#' + id);
    //Can do jQuery stuff with $thisButton now
    //Run AJAX
});

Just make sure you add the class to every save button.

EDIT I may have misunderstood your question --- I thought you were looking to upload images via these forms. The first part of my answer would apply, the second part is probably not relevant. You could still use the method, even with the form you've got (no file elements), but there are other methods that may be more "common" for your use case.


It looks like you're using jQuery, but I'll talk about vanilla methods for this before I get in to the "jQuery Way"

Your goal here is twofold: first, differentiate between forms so you can keep track of which for is doing what, and second, you want to submit your form via an IFRAME to simulate AJAX-like form submission.

The first part is easy: use some kind of unique identifier for the form element, the button, and the container itself:

<div class="oneFormContainer oneFormContainerGTRX2">
    <form class="oneForm oneFormGTRX2" id="GTRX2">
         <!-- form elements -->
        <button class="oneFormButton onFormButtonGTRX2" rel="GTRX2">Submit</button>
    </form>
</div>

In this example, the entire shebang has a unique identifier of "GTRX2" (a random string), so I put that on each element as a class. I prefer to deal with classes rather than ids, but you could do the same thing with ids for the most part. The bottom line here is that when the button is clicked, one can read the rel attribute and quickly locate the associated container (to show a loading message) and the associated form (to submit it).

The second part of the goal here, as I mentioned, is to submit the form to an IFRAME. This might be surprising, given that IFRAMEs have a bad rap, but in this case you're going to use a hidden one to simulate an AJAX request -- that is, you are going to use a normal form post, but it will happen asynchronously to the page load. This strategy is required because, using the standard XHR method for AJAX, one cannot submit a file.

In pseudo-javascript, then:

onPageLoad {
    // add a 'click' event to all elements with the class "oneFormButton"
    document.body.getElementsByClassName('oneFormButton').addEvent('click', handleFormUpload);
}
handleFormUpload {
    var uid = clickedButton.get('rel');
    var form = document.getElementByClassName('oneForm'+uid);
    var container = document.getElementByClassName('oneFormContainer '+uid);

    // make a hidden iframe element, add to body
    var iframe = createElement('iframe');
    iframe.id = 'ajFormSubmitFrame'+uid;
    iframe.name = 'ajFormSubmitFrame'+uid;
    iFrame.style.position = 'absolute';
    iFrame.style.top= '-9000';
    iFrame.style.left= '-9000';
    iFrame.style.width= '10px';
    iFrame.style.height= '10px';
    document.body.appendChild(iFrame);

    // tell the form to target the iframe
    form.target = 'ajFormSubmitFrame'+uid;

    // add an onload event to capture the return
    iFrame.addEvent( 'load', uploadCallback );

    // show some kind of loading message
    showLoader(container);

    // submit the form
    form.submit();
}

uploadCallback  {
  // deal with the response

  // and be sure to remove that iFrame, reset the target property of your form, and clean up the loading message
}

Whew! With all that understood, popular libraries usually encapsulate this into some kind of magic. You have these:

http://valums.com/ajax-upload/ - for jQuery http://pixeline.be/experiments/jqUploader/ - for jQuery http://www.fyneworks.com/jquery/multiple-file-upload/#tab-Examples - for jQuery

http://mootools.net/forge/p/form_upload - for mootools (Hurray!)

Don't get the idea you have to use a library for this -- using the pseudocode above as a basis, it would not be very difficult to roll your own that does exactly what you want and need without the clunky library overhead.

Also, you have the new FileReader API to consider (beyond the scope of this answer), see the docs for examples: https://developer.mozilla.org/en/DOM/FileReader