更新任何选择旁边的输入

时间:2013-05-17 07:48:35

标签: php javascript jquery

我有这个生成表单的PHP脚本:

for ($i = 1; $i <= 10; $i++) {
    echo "<tr class='vraagrij'><td><select name='select" . $i . "'><option>1</option>  <option>2</option></select></td><td><input type='text' value='Test' name='select" . $i . "'></td><td><select name='selectdos" . $i . "'><option>A</option><option>B</option></select></td></tr>";
}

我需要的是在该行中的任何元素发生更改时更新特定行ONCE的输入字段中的文本。到目前为止,我想出了这个(我使用css('color','yellow')以方便和轻松看到行为)。但它只更新了更改的元素,并且只更新一次(因为更改设置为1,所以我需要每行新的'更改',但我不知道将会有多少行。)

 $( document ).ready(function() {
    var changed = 0;

    $('.vraagrij').children().change(function(e) {
        if(clicked = 0)
        {
            var $parent = $(e.target).parent();
            var $kids = $parent.children("input");
            $kids.css('color', 'yellow');
            changed = 1;
        }
    });
});

4 个答案:

答案 0 :(得分:3)

方法1:每行关闭

Here is a fiddle

你可以做的是使用each function为每一行创建一个闭包,在这种情况下,每一行都有自己的变化变量。

此外,您可以使用on() jQuery function间接绑定事件侦听器,而不是直接绑定到input元素。

注意:输入不是直接在行元素之外的子项,因此也会children()交换find()

$( document ).ready(function() {

  // Using the each function to create
  // a row specific closure
  $('.vraagrij').each(function() {

    // Track the state per row
    var changed = false

        // Create a variable to reference the
        // row directly in the change listener
      , $row = $(this);

    // Use event delegation to bind to all
    // descendant selects of the row efficiently
    $row.on("change", "select", function(e) {

      // Make sure the following only runs once
      // per row
      if(!changed) {
        changed = true;

        // Do something to the input, changing
        // color for testing purposes
        var $kids = $row.find("input");
        $kids.css('color', 'yellow');

      }
    });

  });

});

方法2:DOM查询/遍历

Another fiddle

此方法使用DOM的状态来跟踪已更改的状态:

$(document).ready(function() {

  // Again using event delegation to bind events
  // efficiently
  $(".vraagrij").on("change", "select", function(e) {

    // Collect the parent row
    var $row = $(this).closest("tr");

    // Check if it has already got the
    // changed class
    if(!$row.hasClass("changed")) {

      // Add the changed class in to track
      // the state and prevent this being
      // run again for the same row
      $row
        .addClass("changed")

        // Perform the action for the changed
        // select
        .find("input")
          .css("color", "yellow");
    }
  });

});

方法3:使用一种方法

Another fiddle

one method处理事件一次。

更新,包括billyonecan使用closest("tr")代替parents("tr:eq(0)")parents("tr").first()

的好建议
$(document).ready(function() {

  // Again using event delegation to bind events
  // efficiently, this time using the one method
  $(".vraagrij").one("change", "select", function(e) {

    // Perform the action for the changed
    // select
    $(this).closest("tr").find("input").css("color", "yellow");
  });

});

答案 1 :(得分:2)

只需在每个更改的tr上添加一个新类:

$('.vraagrij').on("change","input,select",function(e){
    $parent_tr=$(this).closest('tr');
    if (!$parent_tr.hasClass('changed'))
    {
      $parent_tr.addClass('changed');
      $parent_tr.find("input").css('color', 'yellow');
    }
});

fiddle

答案 2 :(得分:0)

if(clicked = 0)

应该是

if(clicked == 0)

答案 3 :(得分:0)

我不知道clickedchanged的用途,但您的if语句当前设置 clicked的值0,而不是将其与0进行比较。在这种情况下,您应该使用===

if(clicked === 0)

您还应该使用jQuery的.on()事件处理程序。

你的代码做了很多不必要的事情。您应该使用CSS starts-with selector^=):

// Select with a name beginning with "select", e.g. "select3"
$('.vraagrij').on('change', 'select[name^="select"]', function() {
    if(clicked === 0)
    {
        var
            name = $(this).attr('name'), // "select3", for instance
            $input = $('input[name="' + name + '"]') // input[name="select3"]
        ;
        $input.css('color', 'yellow');
        changed = 1;
    }
});