Javascript Add row to HTML table and zoom index

This is my first post on this site, so I hope you can easily understand me. I am trying to create an HTML / PHP form and use a small piece of Javascript to add extra rows to the table when I click the button and increment the identifier for the two fields.

The button works when adding lines, however, it does not seem to increase the identifier, just use the same identifier as the previous line. Hope someone can help?

$(window).load(function(){ var table = $('#productanddates')[0]; var newIDSuffix = 2; $(table).delegate('#button2', 'click', function () { var thisRow = $(this).closest('tr')[0]; var cloned = $(thisRow).clone(); cloned.find('input, select').each(function () { var id = $(this).attr('id'); id = id.substring(0, id.length - 1) + newIDSuffix; $(this).attr('id', id); }); cloned.insertAfter(thisRow).find('input:date').val(''); newIDSuffix++; }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="blue-bar ta-l"> <div class="container"> <h1>Submit Your Insurance Renewal Date(s)</h1> </div> </div> <div class="grey-bar"> <div class="container"> <div class="rounded-box"> <div> <label for="name">Name</label> <input type="text" id="name" name="name" autocomplete="off" required /> </div> <div> <label for="name">Renewal Dates</label> </div> <table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border"> <tr> <td> <select name="insurance_type1" id="insurance_type1"> <option></option> <option>Car</option> <option>Home</option> <option>Van</option> <option>Business</option> <option>GAP</option> <option>Travel</option> </select> </td> <td> <input type="date" name="renewal_date1" id="renewal_date1" /> </td> <td> <input type="button" name="button2" id="button2" value="+" /> </td> </tr> </table> <div> <label for="telephone_number">Contact Number</label> <input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required /> </div> <div> <label for="email">Email Address</label> <input type="email" id="email" name="email" autocomplete="off" required /> </div> <div> <input name="submit" type="submit" value="Submit" class="btn"> </div> </div> 
+6
source share
3 answers

I went ahead, taking a hit in a cleaner version of what I think you are trying to accomplish. I will go through major updates:

  • Updated id and name button from "button2" to "button1" . I suggested that you want indexes to sync across inputs on each row.
  • Changing $(window).load(function() { to $("document").ready(function() { . While both will work, the former will wait until all images have finished loading, and the latter in case of fire when the DOM finishes building, if you don’t want the images to load first, I would recommend $("document").ready() to run the code faster.
  • Removing [0] links is the main reason for using [0] after the jQuery selectors collection must reference the DOM version of the selected jQuery element so that we have a “vanilla” JavaScript method on it. In all cases, you rewound the variables in $(...) that just converted the DOM element back to a jQuery object, so an extra step was not needed.
  • Changed the .delegate() method to .on() , as Howard Renolette noted, this is the correct method to use in modern versions of jQuery. Note that the "event" and "target" parameters replace the places in on from where they were in the delegate .
  • Changed the target from #button2 to :button - this will make sure that all buttons in new lines will also allow you to add additional lines, not just the first one.
  • Switch the clone target from the clicked row to the last row in the table . This will help keep the string order in sequence and in ascending order. The cloned line will always be the last, regardless of which one was pressed, and the new line will always be placed at the end, after it.
  • Indexing has been changed to use the index of the last row as the base for the new row and use the regular expression to determine it - now that the ordered table is always taken into account in the last row to have the highest index. Using the regular expression /^(.+)(\d+)$/i , you can divide the index value into "everything before the index" and "index (that is, one or more digits at the end of the value)." Then you simply increment the index by 1 and reattach it for the new value. Using the regex approach also makes it easy to adapt; it can always be more than 9 lines (i.e., double-digit indexes).
  • Updated id and name attributes for each input . I suggested that you want the id and name attributes to be the same for each individual element, based on the initial line, and you only update the id in your code, which would cause problems when sending data.
  • Changed $("input:date") to $("input[type='date']) - as Myshelov noted, this was the main reason your code was unsuccessful, initially. All other changes will help you avoid additional problems in future or simply related to a change in the quality of the code.

So., Those were the major updates. :) Let me know if I misunderstood what you are trying to do, or if you have any questions.

 $("document").ready(function() { $('#productanddates').on('click', ':button', function () { var lastRow = $(this).closest('table').find("tr:last-child"); var cloned = lastRow.clone(); cloned.find('input, select').each(function () { var id = $(this).attr('id'); var regIdMatch = /^(.+)(\d+)$/; var aIdParts = id.match(regIdMatch); var newId = aIdParts[1] + (parseInt(aIdParts[2], 10) + 1); $(this).attr('id', newId); $(this).attr('name', newId); }); cloned.find("input[type='date']").val(''); cloned.insertAfter(lastRow); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="blue-bar ta-l"> <div class="container"> <h1>Submit Your Insurance Renewal Date(s)</h1> </div> </div> <div class="grey-bar"> <div class="container"> <div class="rounded-box"> <div> <label for="name">Name</label> <input type="text" id="name" name="name" autocomplete="off" required /> </div> <div> <label for="name">Renewal Dates</label> </div> <table width="100%" border="0" cellspacing="0" cellpadding="5" id="productanddates" class="border"> <tr> <td> <select name="insurance_type1" id="insurance_type1"> <option></option> <option>Car</option> <option>Home</option> <option>Van</option> <option>Business</option> <option>GAP</option> <option>Travel</option> </select> </td> <td> <input type="date" name="renewal_date1" id="renewal_date1" /> </td> <td> <input type="button" name="button1" id="button1" value="+" /> </td> </tr> </table> <div> <label for="telephone_number">Contact Number</label> <input type="tel" id="telephone_number" name="telephone_number" pattern="\d{11}" autocomplete="off" required /> </div> <div> <label for="email">Email Address</label> <input type="email" id="email" name="email" autocomplete="off" required /> </div> <div> <input name="submit" type="submit" value="Submit" class="btn"> </div> </div> 
+1
source
 cloned.insertAfter(thisRow).find('input:date').val(''); 

This line is incorrect. It throws an invalid selector error.

You need to change it to:

 cloned.insertAfter(thisRow).find('input[type="date"]').val(''); 

jQuery actually supports :INPUT-TYPE format in selectors, but not new HTML5 input types (for now): so using input[type="date"] here is the right way to select an element with type HTML5. Pay attention to the quotes around the meaning. If you want to select an attribute with a specific value.

An overview of css selector selectors is here: W3schools .

Since this line throws an error, your newIDSuffix never updated, because the script stops in the line before that due to a script error.


@ Charlietfl raises the actual moment to learn more about classes and DOM traversal. However, this will not fix this code. Or explain why your code is not working. However, this is good advice.

+2
source
 cloned.insertAfter(thisRow).find('input[type="date"]').val(''); 
0
source

Source: https://habr.com/ru/post/983610/


All Articles