Adding an additional row of HTML form inputs using Javascript - javascript

I am attempting to dynamically add a new row of HTML form inputs (a new line which includes 6 inputs, namely, (Type(dropdown), Length, Width, Height, Weight and Quantity) into an existing "View" HTML form using Javascript.
The current HTML form inputs are then accessed in my controller file via PHP $_POST requests. This works fine by retrieving the "name" field in the HTML form.
So, a user completes the first line, which id for the shipment of one parcel, and they want to add a second parcel, so, they click on an add(or remove) to add or remove an extra line of inputs.
I have the code working without adding the second row. If you leave the form at default, all the $variables are retrieved for the controller to act on them.
I managed to get some Javascript code off the net which adds the second part of the input form correctly, but, I assumed the code would increment the "name" field so that the first shipment would be name=length and the second shipment would be name=length2. The code does need Bootstrap as well to work correctly.
I have PHP, HTML skills, but limited Javascript skills, hence my request please.
$(document).ready(function() {
var counter = 0;
$("#addrow").on("click", function() {
var newRow = $("<tr>");
var cols = "";
<!--cols += '<td><select class="form-control col-md-8" id="packaging_type" name="packaging_type' + counter + '"/></td>';-->
cols += '<td><input type="text" class="form-control" name="length' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="width' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="height' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="weight' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="quantity' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
});
$("table.order-list").on("click", ".ibtnDel", function(event) {
$(this).closest("tr").remove();
counter -= 1
});
});
function calculateRow(row) {
var price = +row.find('input[name^="price"]').val();
}
function calculateGrandTotal() {
var grandTotal = 0;
$("table.order-list").find('input[name^="price"]').each(function() {
grandTotal += +$(this).val();
});
$("#grandtotal").text(grandTotal.toFixed(2));
}
Ultimately, once I have clicked on the Add Row and entered all of the inputs, I would want the script to numerically increment the "name" input of the HTML form and then be able access them via PHP $_POST.
If there is a better way of doing it, I am open to suggestions.

This won't work anyway, I would suggest using a guid instead of a counter since deleting a row before the last would cause the counter to set itself to the same number as the current last row.

function myFunction() {
var table = document.getElementById("myTable");
var row = table.insertRow(3);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = "NEW CELL1";
cell2.innerHTML = "NEW CELL2";
}

I have managed to find a script that with customisation appears that it will resolve my problem. I will post the outcome once completed so that it may help any future users. The script link is found at :- https://www.jqueryscript.net/demo/Duplicate-Input-Fields-jQuery-Repeatable/
Basically what this script does it it allows you to duplicate DIVs in a table or form, and increments the indexes, "name" "id" etc.
I will be using it to dynamically add additional "inputs" on a form.

Related

How to add new lines after HTML elements

I have a simple method for adding input boxes after a button is clicked. The goal of this method is to generate a set of input boxes with a newline inserted after each div.
In the screenshot above you can see that the divs are spaced properly. However, when the add_more button is clicked the generated inputs do not come out properly.
Expected:
The code should generate new input boxes like so:
<div>
Key Term 2: <input id="el2" type="text" value=""> <br>
</div>
<br>
Actual:
function add_more() {
// we've added more inputs.
addMore = true;
// set html generated to false, because new inputs have been added.
htmlGenerated = false;
// increment the number of inputs.
numberOfInputs++;
//fetch the input boxes.
inputs = document.getElementById("inputBoxes");
// create newline
br_key = document.createElement("br");
// create newline
br_description = document.createElement("br");
//create a new row for a key term.
row = document.createElement("div");
// set the key term text.
row.innerHTML = "Key Term ";
row.innerHTML += numberOfInputs;
row.innerHTML += " :";
// create the input for the key.
key = document.createElement("input");
key.setAttribute("id", "el" + numberOfInputs);
//add the key to the row.
row.appendChild(key);
row.after(br_key);
//create a row for the new description.
row2 = document.createElement("div");
// set the description text.
row2.innerHTML = "Description "
row2.innerHTML += numberOfInputs;
row2.innerHTML += " :";
// create the description input
description = document.createElement("input");
description.setAttribute("id", "dl" + numberOfInputs);
// add the description to the row.
row2.appendChild(description);
row2.after(br_description);
// add the rows for the key and the description to the inputBoxes.
inputs.appendChild(row);
inputs.appendChild(row2);
}
<div>Key Term 5 :<input id="el5"></div>
Any help figuring out this issue would be greatly appreciated. Thanks.
Your issue here is essentially incorrect HTML, CSS. I'd implement your inputs, etc. like this:
.full-width-label {
display:block;
}
<label class="full-width-label" for="1">Label</label>
<input type="text" id="1"/>
There are multiple ways to achieve the above, this is just one of your options but now you no longer need to embed the look into the HTML and the format of your HTML (line breaks) is independent of your look.
You might want to look into an off the shelf solution for these kinds of things, like Bootstrap or Tailwind
You can use make it in a simple way
HTML
add this jquery cdn
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<button type="button">Click Here</button>
<div class="appendDiv">
</div>
Js
$(document).ready(function (){
var button = document.getElementsByTagName('button');
var appendDiv = document.getElementsByClassName('appendDiv');
var key = 1;
var descKey = 1;
$('button').click(function(event){
event.preventDefault();
$(appendDiv).append('<div class="child"><div class="grand-child"><label>Key Form :'+ ' '+(++key)+'</label><input type="text" value=""/></div><div class="grand-child"></div><label>Description :'+ ' '+(++descKey )+'</label><input type="text" value=""/></div>');
})
})

Why is the data being displayed many times over the loop?

I have been trying to set up a kind of search engine connected to an API. It takes the user input and gives back the information from the API. In the future there should be a "dynamic" amount of input fields but for the moment I am working with a fixed amount of five. The loop takes the amount of fields and calls the API that amount of times with that input.
I tried placing a constant (i.e. 5) in the loop but still, the funny part is that with 3 it of course calls the app three times but outputs 6 fields, and with 2 it calls the API 2 times but outputs three rows so it seems that it does not obey the loop but something else. Meanwhile in the console (with log) I can see that the API is properly called only the times defined by the loop so I believe something goes wrong at the $.getJSON level
The problem is at the end a table is created with 15 rows instead of the expected 5 (one row for every input). Why do you think this is happening?
Thanks in advance
<form name="inputform" method="get" width="50">
<input type="text" name="field0" id="field0" size="50">
<input type="text" name="field1" id="field1" size="50">
<input type="text" name="field2" id="field2" size="50">
<input type="text" name="field3" id="field3" size="50">
<input type="text" name="field4" id="field4" size="50">
</form>
<table id="table">
<tr>
<th>id</th>
<th>Name</th>
<th>Age</th>
<th>Preference</th>
</tr>
</table>
<input id="getInfo" type="button" value="Submit" /><br/>
var customURL = "http://apitest.com/test/";
var customURL1 = '';
$('#getInfo').click(function() {
$('#table tr').not(':first').remove();
var fields = document.getElementsByTagName('input');
var table = document.getElementById('table');
if (localStorage.myJSON !== undefined) {
var myJSON = JSON.parse(localStorage.myJSON);
}
var html = '';
for (var i = 0; i < elements.length - 1; i++) {
customURL1 = customURL + document.getElementById('field' + i + '').value;
console.log(customURL1);
$.getJSON(customURL1, function(data) {
console.log(data);
html += '<tr><td>' + data.sample_list.id + '</td><td>' + data.sample_list.name + '</td><td>' + data.sample_list.age + '</td><td>' + data.sample_list.preference + '</td></tr>';
$('#table tr').first().after(html);
Each time you get an AJAX response, you're appending the response to the html variable, and then adding that after the first row of the table. Since the html variable already contains the results from the previous responses, and they were insert into the table already, you get duplicates.
Instead of concatenating the new row to html, just insert the new row directly into the table.
$.getJSON(customURL1, function(data) {
console.log(data);
$('#table tr').first().after('<tr><td>' + data.sample_list.id + '</td><td>' + data.sample_list.name + '</td><td>' + data.sample_list.age + '</td><td>' + data.sample_list.preference + '</td></tr>');

Passing values to multiple dynamically created controls base on bootstrap-3-typeahead dropdown list using JQuery

I am creating an invoice system using Laravel, JQuery and Bootstrap-3-typeahead and have created a button that dynamically adds new table row with text inputs in each table data on selection of a list item using JQuery. The first text input in each row has bootstrap-3-typeahead functionality: After selecting an item like this
creating invoice tutorial.
After selecting from the autocomplete text-input dropdown list, it automatically populates the price, quantity and assign a default value of "1" to the quantity input using the below Typeahead(afterSelect method) implementation using JQuery and Ajax GET method.
This is my
html markup screenshot.
My JQuery implementation of boostrap-3-typeahead and generation of auto price, quantity, and total values base on selected item from typeahead dropdown list.
var typeaheadSettings = {
source: function (query, process) {
return $.get(url, { query: query }, function (data) {
console.log(data)
return process(data);
});
},
afterSelect: function (data) {
console.log(data.sellPrice);
$('#itemPrice').val(data.sellPrice);
$('#itemQuantity').val('1');
var price = $('#itemPrice').val();
var quantity = $('#itemQuantity').val();
var subtotal = price * quantity;
$('#itemSubtotal').val(subtotal);
}
};
The JS code that adds new row on button click:
// Add Row
$(document).on('click', '#btnAddRow', function(event) {
var i=$('#invoiceTable tbody tr').size();
html = '<tr>';
html += '<td><p class="text-center pt-xs"><input type="radio" name="sn" id="sn" value=""></p></td>';
html += '<td><input type="text" name="productName[]" id="itemName'+ i +'" class="form-control typeahead twitter-typeahead" placeholder="Item name" autocomplete="off" data-fit-to-element="true" data-provide="typeahead"></td>';
html += '<td><input type="text" name="price[]" id="itemPrice'+i+'" class="form-control text-right" placeholder="Item price" autocomplete="off" readonly></td>';
html += '<td><input type="number" name="quantity[]" id="itemQuantity'+ i +'" class="form-control text-right" placeholder="Quantity"></td>';
html += '<td><input type="text" name="subtotal[]" id="itemSubtotal'+ i +'" class="form-control text-right" placeholder="Subtotal" readonly></td>';
html += '<td class="actions-hover actions-fade text-center"><p><a id="btnDelRow"><i class="fa fa-minus-circle fa-lg text-warning" id="iconDelRow"></i></a></p></td>';
html += '</tr>';
$('#invoiceTable tbody').append(html);
i++;
$('.typeahead').trigger('added');
});
This is what the markup of the dynamically added row looks like, with integer "1,2" suffixed to the ID.The integer increments if another row is added dynamically, giving all duplicate controls a unique ID.
dynamically added tr screenshot
The problem is that when i add a second control dynamically by clicking the "Add New Row" button shown on the image above, the dynamically added price and quantity input controls don't get the newly generated values. Instead, the values appear on the first already defined row. The same thing happens when i add the 3rd row and more.
I'd be glad if someone can help me out with a way i can pass the values generated after dropdown list item is selected to the right or appropriate inputs.
The HTML selector you are using seems to be an ID selector which should be unique per document. This may explain why this is happening.
It seems the values appear on the first defined row because you have coded only their IDs into the typeaheadSettings.afterSelect(...) function:
$('#itemPrice').val(data.sellPrice);
$('#itemQuantity').val('1');
var price = $('#itemPrice').val();
var quantity = $('#itemQuantity').val();
var subtotal = price * quantity;
$('#itemSubtotal').val(subtotal);
You should probably refactor the function so it can use the other auto-generated IDs like #itemPrice1, #itemSubtotal2, ...

JQuery Get Value from Select Option not working

I dont know why my jquery code does not works to get value from select option.
I have created a function where when I click on "Add New Row" button then it will create a new row to my table.
Here's my JS code to add new row
$(".tambah_sofa").on('click',function(){
html = '<tr id="row_'+i+'">';
html += '<td><button type="button" id="delete-button" data-row-delete="row_'+i+'">X</button></td>';
html += '<td><select name="sofa[]" id="sofa"> <option value="'+sofa_rumah+'">Sofa rumah</option><option value="'+sofa_pejabat+'">Sofa Pejabat</option><option>Sofa Kedai</option><option>Tilam Tak Bujang</option> </select> </td>';
html += '<td>X</td>';
html += '<td><input type="number" name="quantity[]" id="quantity_'+i+'" value="1" disabled="disabled"></td>';
html += '</tr>';
sidebar = '<tr id="row_'+i+'">';
sidebar += '<td><input style="width:50%;" type="text" id="price_sofa" value="" disabled="disabled"></td>';
sidebar += '</tr>';
$('#table_item').append(html);
$('#table_sidebar').append(sidebar);
i++;
});
Below is my code to get select option values into textbox :
$('#sofa').on('change', function () {
$('#price_sofa').val(this.value);
}).trigger('change');
I try to follow this JSfiddle demo : http://jsfiddle.net/JwB6z/2/
The code is working but when I try implement to my "add new row" function, it's not working.
I believe this is because any new row is not being recognised. I think you should bind the change to body...
example:
$('body').on('change', '#sofa', function () {
you can always use this:
$('#sofa').on('change', function () {
$('#price_sofa').find(':selected').val();
}).trigger('change');
EDIT: The above one is used to get the value you entered if you want to add the text and not value you can always put
$('#price_sofa).find(':selected').text();
EDIT2: When you use $('#price_sofa').val(this.value); you are not taking the selected option and a you can see in the fiddle here that you added they didn't use the function that you used.
Hope this helps

Javascript function for form created using Javascript

I have a script which adds a new form when a button is clicked to a HTML page with the code as following:
<script>
var counter = 1;
var limit = 10;
function addInput(divName){
if (counter == limit) {
alert("Max number of forms, " + counter );
}
else
{
var newdiv = document.createElement('div');
newdiv.innerHTML = "<form name='frmMain' action='prelucrare.php' method='POST'><div class='slot' id='dynamicInput' align='center'> Masina " + (counter +1 ) + "<table border='1'><tr><td align='right'><label for='marca'>Marca:</label></td><td colspan='2' align='left'>"
+ "<select id='marc' name='marc'><option selected value=''></option>"
+ "<tr><td align='right'><label for='motorizare1'> Motorizare:</label></td> <td><input type='range' name='motorizare1[]Input' min='0.6' max='5' step='0.1' value=2 id=motor1 oninput='outputUpdate1(value)'></td><td><output for=motorizare1 id=moto1>2</output></td></tr>"
+ "</div></form>"
;
}
document.getElementById(divName).appendChild(newdiv);
counter++;
}
</script>
<input type="button" value="Adauga" onClick="addInput('dynamicInput');">
And I have the script bellow which changes the value from the slider.
<script>
function outputUpdate1(mot1) {
document.querySelector('#moto1').innerHTML = mot1;
}
</script>
My problem is that the JS code only changes the input for the first form, even if the slider is activated from another form. In short, the slider should return the value in the form from which it is activate; not only in the first form added.
Thank you!
Going along with my comment, the problem is stemming from the id value being the same across all of your output elements (moto1). You've actually got all the variables you need to make them unique since you're tracking a count of the number of forms on the page (your counter variable). You can use this in place of your current output HTML:
"<input type='range' name='motorizare1[]Input' min='0.6' max='5' step='0.1' value=2 id='motor_" + counter + "' oninput='outputUpdate1(value)'/>"
"<output for=motorizare1 id='moto_" + counter + "'>"
You can update your function to parse out the correct index for the output you want to update since they should be in sync if you use the HTML above:
function outputUpdate1(mot) {
// Get the counter part of the range element's id
var index = mot.id.split('_')[1];
document.querySelector('#moto_' + index).innerHTML = mot;
}
You may need to make some tweaks to code you haven't provided in the question, but that's one way of making the id values unique and how to access them without knowing the exact id ahead of time.

Categories