views:

141

answers:

3

I have a selector that could look like this:

<label for="testselector">Test</label><br />
<select id="testselector" name="test[]" size="5" multiple="multiple">
    <option name="test_1" value="1">Test Entry X</option>
    <option name="test_3" value="2">Test Entry Y</option>
    <option name="test_5" value="5">Test Entry Z</option>
</select>

<div id="fieldcontainer"></div>

When an entry from the above fields is selected, I want two form fields to appear. I use jquery to add them:

$("#fieldcontainer").append("<div><label for=\"testurl\">Test Url</label><br /><input name=\"testurl[]\" type=\"text\" id=\"testurl_1\" value=\"\" /></div>");
$("#fieldcontainer").append("<div><label for=\"testpath\">Test Path</label><br /><input name=\"testpath[]\" type=\"text\" id=\"testpath_1\" value=\"\" /></div>");

I can easily add a click handler to make those form fields appear. But how would I keep track of what form fields were already added? When multiple fields are selected, the appropriate number of input fields needs to be added to the fieldcontainer div. And if they are unselected, the input fields need to be removed again. I also need to retrieve the value from the options in the select list to add them as identifier in the added input fields...

A: 

When an entry is selected, I would add a class such as "selected" Then you can set the #fieldcontainer's innerHtml based on all of the entries with a class of "selected".

derek
A: 

You could do something along these lines:

// For each of your options
$("#testselector option").each(function(i, option) {

  // Create a function that shows/hides the current option
  var showHide = function() {

    // Find the value of the clicked option
    var value = $(option).val();

    // Create an id that we can use for adding/removing the new html
    var uid = "someuniquename_" + value;

    // Check if the option is selected or unselected
    // Based on that, either create or remove desired html
    if ($(option).attr('selected')) {
      $("#fieldcontainer").append('<div id="' + uid + '">your html here, from id ' + value + '...</div>');
    } else {
      $("#fieldcontainer div#" + uid).remove();
    }
  };

  // Invoke showHide once right now, to initialize the page
  showHide();

  // Invoke showHide when the option is clicked
  $(option).click(showHide);
});

Also note that I'm using single quotes for the html-string, which allows me to write double-quotes without having to escape them. It improves the readability of the code :)

Jakob
Thank you! I was having trouble checking if the element was selected or not. Your example is going to help me out a lot! :-)
Workoholic
EDIT: Hmm... I tried it, but the part were the div containers are removed never gets executed.I could also just get all elements of the select list somehow and cycle through them to remove the unselected items. But the list can become very long! It would take too much time.
Workoholic
Also, on first page load, the containers connected to teh already selected items need to be shown.
Workoholic
1) I'm not an expert, so it could be that I've missed something, but it worked fine here. Post some code and I'll see if I can help you. 2) The page load issue could be fixed easily, by also directly invoking the function passed to the click-handler. I'll edit my solution!
Jakob
A: 

Here the solution I came up with. If there's a more elegant way, let me know. :-)

<script type="text/javascript"><!--
$(document).ready(function(){
    function changeVals() {
        var values = $("#testselector").val() || [];

        $.each(values, function(key, value) {

            if(!$("#testurl_"+value).length){
            //add field 1
            $("#fieldcontainer").append("<div id='testurl_"+value+"'><label>Test URL</label><br /><input name='testurl' type='text' value='...' /></div>");
            }
            if(!$("#testpath_"+value).length)
            {
            //add field 2
            $("#fieldcontainer").append("<div id='testpath_"+value+"'><label>TEST PATH</label><br /><input name='testpath' type='text' value='...' /></div>");
                    }
        });

        //remove all not selected fields
        var preg = '';
            $.each(values, function(k, v) {
                preg = preg + " #testurl_"+v + ",";
                preg = preg + " #testpath_"+v + ",";
            });
            //remove trailing comma
            preg = preg.slice(0,preg.length-1);
            $("#fieldcontainer > :not("+preg+")").remove();

        }
        $("#testselector").change(changeVals);
        changeVals();
});
//-->
</script>
Workoholic