views:

57

answers:

3

Ok this might be a bit confusing, but here goes. Let's say I have a a few select dropdowns on a page.

<select id="filter" name="filter[]">
        <option value="">-- Select Filter --</option>
    </select>

    <select id="load_choice" name="load_choice[]">
        <option value="">-- Select Load_choice --</option>
    </select>

    <select id="plastic" name="plastic[]">
        <option value="">-- Select Plastic --</option>
    </select>

These are dynamically filled from a database with an ajax request. Each set of select options are dependent on the previous selection. This is just a snippet of all the select dropdowns, but essentially their selections creates a "product". Here is the javascript that connects to the php (which connects to the DB).

$(document).ready(function() {
$('#filter').change(function(){

        $('#load_choice').fadeOut();
        $('#loader').show();

        $.post("ajax/ajax_load_choice.php", {
            country: $('#country').val(),
            filter: $('#filter').val()
        }, function(response){
            setTimeout("finishAjax('load_choice', '"+escape(response)+"')", 400);
        });
        return false;
    });


    $('#load_choice').change(function(){

        $('#plastic').fadeOut();
        $('#loader').show();

        $.post("ajax/ajax_plastic.php", {
            country: $('#country').val(),
            filter: $('#filter').val(),
            load_choice: $('#load_choice').val()
        }, function(response){
            setTimeout("finishAjax('plastic', '"+escape(response)+"')", 400);
        });
        return false;
    });


    $('#plastic').change(function(){

        $('#UG_tipping').fadeOut();
        $('#loader').show();

        $.post("ajax/ajax_UG.php", {
            country: $('#country').val(),
            filter: $('#filter').val(),
            load_choice: $('#load_choice').val(),
            plastic: $('#plastic').val()
        }, function(response){
            setTimeout("finishAjax('UG_tipping', '"+escape(response)+"')", 400);
        });
        return false;
    });

    });

    function finishAjax(id, response){
     $('#loader').hide();
     $('#'+id).html(unescape(response));
     $('#'+id).fadeIn();
    }
}

NOW, let's say I want to add another of the exact same form with the exact same select options in order to "create another product" on the same page (hence the array on the NAME tag for each select). Since the form is dependent on unique IDs, how could I make the IDs in this chunk of code dynamic?

$('#filter').change(function(){

        $('#load_choice').fadeOut();
        $('#loader').show();

        $.post("ajax/ajax_load_choice.php", {
            country: $('#country').val(),
            filter: $('#filter').val()
        }, function(response){
            setTimeout("finishAjax('load_choice', '"+escape(response)+"')", 400);
        });
        return false;
    });

I will eventually have 5 sets of those select groups so the user can create 5 products. How would I make it so I don't have to do id="filter1" and id="filter2" to coincide with $('#filter').change(function....blah blah blah. Basically, can I make ID's in a jquery function dynamic?

A: 

This is what I came up with, wrap each set of select boxes in a div or something. And then remove their id attribute.

With jQuery you can bind a change and still grab the other two selects like this.

$('select[name=filter[]]').change(function() {
  var $parent = $(this).parent();

  // hide and show other selects
  $parent.find('select[name=load_choice[]]').fadeOut();
  $parent.find('select[name=plastic[]]').show();

  // make the ajax call
});

// repeat the above code for the others
Baylor Rae'
A: 

I'm not, really, sure what you're asking. My best guess is something along the lines of:

Using jQuery, can I increment the id fields of the form elements in order that I can add multiple forms to the page, and have each form uniquely identified?

If this is a reasonable understanding of your question, and looking at @Baylor Rae's answer (which is definitely a valid interpretation) I'm not necessarily right, then the following should work:

jQuery

$(document).ready(
 function(){
  $('#formAdd').click(
      function(){
          var count = $('#formsBox form').length;
          $('#formsBox form').eq(0).clone().appendTo('#formsBox').find('label, input').each(
              function(){
                  if (this.id) {
                      var curId = this.id;
                      $(this).attr('id',curId + count);
                  }
                  else if ($(this).attr('for')) {
                      var curFor = $(this).attr('for');
                      $(this).attr('for', curFor + count);
                  }
              }
              );
      }
      );
 }
 );

html

<div id="formsBox">
    <form action="" method="post">
        <fieldset>
            <ul>
                <li>
                    <label for="firstInput">First Input:</label>
                    <input type="text" name="firstInput" id="firstInput" />
                </li>
                <li>
                    <label for="secondInput">SecondInput:</label>
                    <input type="text" name="secondInput" id="secondInput" />
                </li>
            </ul>
        </fieldset>
    </form>
</div>
<div id="formAdd">Add another form</div>

Effectively, on clicking the #formAdd div the jQuery finds the form, works out how many there are and stores that as the variable count.

It then clones the first form (without the .eq(0) the first click clones one form, the second click clones two forms and it's exponential thereafter), appends it to the same container (#formsBox, for want of a better name) and then looks for the labels and inputs; if these have an id (input) or a for (label) attribute, it adds the previously-stored count variable to these attributes, uniquely identifying them.

This is a pretty poor explanation, and I'm sure there's a far prettier way of achieving the same end-result in the jQuery, but it does seem to work. There's a JS Fiddle demo here

David Thomas
+1  A: 

It is recommended to have unique ids always.
The main reason is that performing a selector like $('#myId') may give unpredictable results when there are multiple elements in the page with that id.

jQuery relies on the native browser implementation of document.getElementById(), which in most cases returns just the first element found.

If you want to make sure by using jQuery that you have unique id's you can do something like:

$('select[id=filter]').each(function(i,el){
    el.id=el.id+'-'+i;
});

If you already have unique id's you can use a prefix selector(^= or |=) like this:

$('select[id^=filter]');
//or
$('select[id|=filter]');

You can see a live example of both in this jsFiddle


Alternately, if you don't care about duplicate ids you can select all elements with a given id (including duplicates) like this:

$('[id=my-id]');
Dan Manastireanu