views:

267

answers:

2

I previous recieved help with a problem, getting a multiple option select form to create new inputs, depending on how many were selected. The code below is what ended up working for me (credit goes to Peter Bailey)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

$(function()
{
  $('#test')
    .after( '<div id="option-inputs"></div>' )
    .find( 'option' ).each( function()
    {
      var $option = $(this);
      $option
        .data( '$input', $( '<span>' + $option.text() + ': </span><input><br>').appendTo( '#option-inputs' ).hide() )
        .bind( 'toggle-input', function()
        {
          var $input  = $option.data( '$input' );
          if ( $option[0].selected )
          {
            $input.show();
          } else {
            $input.hide();
          }      
        })
        .bind( 'click', function()
        {
          $(this).siblings().andSelf().trigger( 'toggle-input' );
        })
        .trigger( 'toggle-input' )
      ;
    })
  ;
});


</script>

</head>
<body>

<select id="test" multiple="multiple">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>

</body>
</html>

I don't know jQuery so I need help with one last tweak. I need to be able to limit which options selected create new boxes. So, if an option of value -1 or 0 is selected, a new textbox is not created. Anything else does.

Also is there any way to have other select forms trigger this to one to update? In regular javascript you'd use onChange="" and a function to update it. The reason for this is that the select table is dynamically populated, based on the input of the previous select table. If you go back and make changes to the previous select table, it doesn't update the jQuery, the previous inputs remain.

Thanks for the assistance!

A: 

A quick and simple solution would be to check the value at the top of your .each function call, and if it's 0 or -1, return (which works like a break in a .each loop).

if ($option.attr('value') == 0 || $option.attr('value') == -1) return;

And for your whole code:

$(function()
{
  $('#test')
    .after( '<div id="option-inputs"></div>' )
    .find( 'option' ).each( function()
    {
      var $option = $(this);
      //new code
      if ($option.attr('value') == 0 || $option.attr('value') == -1) return;

      $option
        .data( '$input', $( '<span>' + $option.text() + ': </span><input><br>').appendTo( '#option-inputs' ).hide() )
        .bind( 'toggle-input', function()
        {
          var $input  = $option.data( '$input' );
          if ( $option[0].selected )
          {
            $input.show();
          } else {
            $input.hide();
          }      
        })
        .bind( 'click', function()
        {
          $(this).siblings().andSelf().trigger( 'toggle-input' );
        })
        .trigger( 'toggle-input' )
      ;
    })
  ;
});
tj111
A: 

You'll need to set up a "initilization" routine for the <select>, so that when it receives new options it can re-setup the linked inputs.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

$(function()
{
  //  How you manage this data is up to you, this is just an example
  var optionData = {
      1: { 1: "1.1", 2: "1.2", 3: "1.3" }
    , 2: { 1: "2.1", 2: "2.2", 3: "2.3" }
  }
  var $test = $('#test');

  $test.bind( 'init', function()
  {
    $optionInputs = $( '#option-inputs' );
    if ( !$optionInputs.length )
    {
      $optionInputs = $( '<div id="option-inputs"></div>' ).insertAfter( $test );
    }
    $optionInputs.children().remove();
    $test.find( 'option' ).each( function()
    {
      var $option = $(this);
      $option
        .data( '$input', $( '<span>' + $option.text() + ': </span><input><br>').appendTo( $optionInputs ).hide() )
        .bind( 'toggle-input', function()
        { 
          var $input  = $option.data( '$input' );
          if ( $option[0].selected )
          {
            $input.show();
          } else {
            $input.hide();
          }      
        })
        .bind( 'click', function()
        {
          $(this).siblings().andSelf().trigger( 'toggle-input' );
        })
        .trigger( 'toggle-input' )
      ;
    });
  });

  $('#changer').bind( 'change', function()
  {
    var $this = $(this)
      , options = optionData[$this.val()]
      , optionHtml = '';
    ;

    for ( var i in options )
    {
      if ( options.hasOwnProperty( i ) )
      {
        optionHtml += '<option value="' + i + '">' + options[i] + '</option>';
      }
    }
    $test.html( optionHtml ).trigger( 'init' );
  }).trigger( 'change' );
});


</script>

</head>
<body>

<select id="changer">
  <option value="1">Set 1</option>
  <option value="2">Set 2</option>
</select>

<select id="test" multiple="multiple">
</select>

</body>
</html>
Peter Bailey
I think this is a little more than I wanted. All I want is for the "changer" select to clear the newly created inputs if there is a change made to it.For example, if I select something in the test select, and a new input is created, going back and selecting something in the changer will remove that new input, then create it again if I select something again in the test select.
Dave Hunt
I'm really missing something, because as best I can tell from your description, that's exactly what this does.
Peter Bailey