-3

To create an array of inputs for test, we can do:

<input name=test[]>
<input name=test[]>
...

But how can I manipulate each input in javascript/jQuery upon change, before submission? I figure I need to pass the index of a particular input from test[].

I'm stuck at $(this).index() or $(this).parents().index(), but these are index values of the DOM, they don't give the index value of the testa[], testb[], testc[] arrays that's being triggered.

The reason for all this is because the POST values for these checkboxes aren't passed, not even set, if they aren't checked. This messes up my database rows, hence I'm adding a textbox for each row that will be passed (instead of passing the checkbox values) into the database.

Here's a working example that uses a FOR LOOP to accomplish my goal, but it seems inelegant and I'd rather not use a loop:

$(document).ready(function() {
  $("input.test").change(function() {
    rows = document.getElementsByName("LanguageLevels[]");


    // ### This is the part I would really like to change - more elegant please?!?
    var getIndex = 0;
    testaArray = document.getElementsByName("testa[]");
    testbArray = document.getElementsByName("testb[]");
    testcArray = document.getElementsByName("testc[]");

    for (var i = 0; i < testaArray.length; i++) {
      if ((this == testaArray[i]) || (this == testbArray[i]) || (this == testcArray[i])) {
        getIndex = i;
        break;
      }
    }
    // #### End of un-elegant code

    rows[getIndex].value = this.value + " " + this.checked;
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<!DOCTYPE html>


<div class="LL">
  1. <input class="test" type="checkbox" name=testa[] value="test1"> 
  2. <input class="test" type="checkbox" name=testb[] value="test2"> 
  3. <input class="test" type="checkbox" name=testc[] value="test3">

  <input name="LanguageLevels[]" id="LanguageLevels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>

<div class="LL">
  1. <input class="test" type="checkbox" name=testa[] value="test4"> 
  2. <input class="test" type="checkbox" name=testb[] value="test5"> 
  3. <input class="test" type="checkbox" name=testc[] value="test6">

  <input name="LanguageLevels[]" id="LanguageLevels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>
showdev
  • 28,454
  • 37
  • 55
  • 73
Timothy Law
  • 318
  • 3
  • 9
  • There is no array until your server-side code (PHP?) parses the inputs. See [HTML input arrays](https://stackoverflow.com/questions/1010941/html-input-arrays). Using the DOM index should work. Can you include a [working example](https://stackoverflow.com/help/mcve) of what you're trying to do and what specifically goes wrong? – showdev Feb 22 '18 at 21:45
  • 1
    Each input will have its own set of DOM events (such as [change](https://developer.mozilla.org/en-US/docs/Web/Events/change)) which will provide the input as [`event.target`](https://developer.mozilla.org/en-US/docs/Web/Events/change#Examples), so you don't need to go and find it. – jpaugh Feb 22 '18 at 21:45
  • You've mistaken PHP syntax for HTML. If you're not using PHP, `` just names the input the literal string "text[]". – Daniel Beck Feb 22 '18 at 21:46
  • @showdev If y'all are positive PHP is involved, could you retag? – jpaugh Feb 22 '18 at 21:47
  • @jpaugh I'm not positive. Thanks for pointing that out. – showdev Feb 22 '18 at 21:48
  • hey, what's with the negative voting?!? what gives – Timothy Law Feb 23 '18 at 00:19

1 Answers1

2

You can use jQuery's .index(element) to find the index of an element relative to a selection.

If a selector string is passed as an argument, .index() returns an integer indicating the position of the first element within the jQuery object relative to the elements matched by the selector. If the element is not found, .index() will return -1.

For example, passing this to index() finds the index of the element which fired the event, relative to a jQuery selection:

var index_of_this_within_selection = jQuery(selection).index(this)

So, in order to determine the "array index" of a checkbox, I've added a "group" data-attribute and class to each input. The group defines which "array" the input is a member of.

<input type="checkbox" name="testa[]" value="test1" class="test testa" data-group="testa">

Using that information, we can select all inputs with the class of that array name and find the index of this within that selection.

Here's a working example:

jQuery(function() {

  $rows = jQuery('.language_levels');

  jQuery("input.test").change(function() {

    var $this = jQuery(this);
    var group_name = $this.data('group');
    var group_index = jQuery('.' + group_name).index(this);

    $rows[group_index].value = this.value + " " + this.checked;

    console.log('Index of "' + group_name + '" = ' + group_index);

  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="LL">
  <label>1. <input type="checkbox" name="testa[]" value="test1" class="test testa" data-group="testa"></label>
  <label>2. <input type="checkbox" name="testb[]" value="test2" class="test testb" data-group="testb"></label>
  <label>3. <input type="checkbox" name="testc[]" value="test3" class="test testc" data-group="testc"></label>
  <input name="LanguageLevels[]" class="language_levels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>

<div class="LL">
  <label>1. <input type="checkbox" name="testa[]" value="test4" class="test testa" data-group="testa"></label>
  <label>2. <input type="checkbox" name="testb[]" value="test5" class="test testb" data-group="testb"></label>
  <label>3. <input type="checkbox" name="testc[]" value="test6" class="test testc" data-group="testc"></label>
  <input name="LanguageLevels[]" class="language_levels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>

Edit

If you don't really need the index and you just need to set the input for the row that was clicked, there may be a simpler method:

Use jQuery's closest() to identify the row of the clicked checkbox.
Then set the value of the .language_levels input in that row using the context selector.

jQuery(function() {

  jQuery("input.test").change(function() {

    var $row = jQuery(this).closest('.LL');
    var $input = jQuery('.language_levels', $row);

    $input.val(this.value + " " + this.checked);

  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="LL">
  <label>1. <input type="checkbox" name="testa[]" value="test1" class="test"></label>
  <label>2. <input type="checkbox" name="testb[]" value="test2" class="test"></label>
  <label>3. <input type="checkbox" name="testc[]" value="test3" class="test"></label>
  <input name="LanguageLevels[]" class="language_levels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>

<div class="LL">
  <label>1. <input type="checkbox" name="testa[]" value="test4" class="test"></label>
  <label>2. <input type="checkbox" name="testb[]" value="test5" class="test"></label>
  <label>3. <input type="checkbox" name="testc[]" value="test6" class="test"></label>
  <input name="LanguageLevels[]" class="language_levels" size="37" placeholder="<--Please Choose one of the three" readonly>
</div>
showdev
  • 28,454
  • 37
  • 55
  • 73