Jquery clone function is appending twice - javascript

So i am trying to use Jquery clone function. My problem is the first clone is okay. Then then the next are always appending two times.
JS
var initpriceinquiry = function(){
$(document).on("click",".btn_addMore_unit",function () {
var cloned = $(".price_inquiry_source tbody ").html();
var oldL = $(".units").length;
cloned = cloned.replace(/\[\x\]/g,oldL);
$(cloned).insertBefore("#targetRow");
modSelect2("select[name='pi_product_id[]']","/admin/price_inquiry/get_ajax_input?type=product_id&custom_type",function(obj) {
$.ajax({url:"", type: "get", data:"get_unit=1&product_id="+obj.val(), success: function(data)
{
eval("var record = "+data+";");
obj.parent().next().html(record[0]);
obj.parent().next().next().html(record[1]);
obj.parent().next().next().next().html("<textarea name = 'remark' class = 'form-control'></textarea>");
} });
});
});
}
HTML
<table class = 'hidden price_inquiry_source'>
<tr class = 'units'>
<td >
<select name = 'pi_product_id[]' class = 'form-control unitcodes[x]' style="width:120px">
</select>
<br>
<a href='javascript:void(0)' style='' onclick="$(this).parent().parent().remove();" class=''><i class='fa fa-trash'></i></a>
</td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
{{-- To BE CLONED --}}
Cloned should be inserted here
<table class="table table-condensed table-hover" id = "tableData">
<thead>
<tr>
<th>UNIT CODE</th>
<th>DESCRIPTION</th>
<th>SELLING PRICE</th>
<th>REMARKS</th>
</tr>
</thead>
<tbody>
<tr id = 'targetRow'>
<td colspan="4"><button class="btn btn-link btn_addMore_unit"
href="javascript:void(0)" style="display: inline-block;"><i class="fa fa-
plus "></i> ADD UNIT</a></td>
</tr>
</tbody>
</table>
See Image Attached for my problem
Image
Any help would be appreciated thanks!

Try this
//add `add_field_button` to your clone button
<a class="add_field_button btn btn-xs btn-success">Click me</a>
// add this class `input_fields_wrap` to your input field div
<div class="input_fields_wrap">
<input type="text" class="form-control" name="" value="i will be clone">
</div>
$(document).ready(function() {
var max_fields = 10; //maximum input boxes allowed
var wrapper = $(".input_fields_wrap"); //Fields wrapper
var add_button = $(".add_field_button"); //Add button ID
var x = 1; //initlal text box count
$(add_button).click(function(e){ //on add input button click
e.preventDefault();
if(x < max_fields){ //max input box allowed
x++; //text box increment
$(wrapper).append("<div>"+
"<div class='form-group form-inline'>"+
"<label for=''>hello there</label>"+
"<input type='text' class='form-control' name='' value='i am cloned one'>"+
"</div>"+
"<a href='#' class='btn btn-danger btn-xs remove_field'>remove me</a></div>");
}
});
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<a class="add_field_button btn btn-xs btn-success">clone me</a>
<div class="col-md-4 input_fields_wrap">
<div class="form-group form-inline">
<label for="">sample input</label>
<input type="text" class="form-control" name="" value="i will be clone">
</div>
</div>
</div>
</div>

Related

jQuery validation on dynamic table form not working on using blur

I am creating form dynamically which has n rows (coming from array having n elements). Form fields have two type of columns (text & number) which I have given different id.
Although JQuery validation is working but "validate parts button" is not responding correctly. From the code condition it should not be enabled in case text is not valid.
Thanks..!
<div class="container-sm">
<div class="col-md-12 text-center">
<input class="btn btn-outline-primary" type="button" onclick = "buildTagPartsTable()" id="partNum" style="height:40px; width:220px" value="Enter Form Details#">
</div>
</div>
<div class="container-sm">
<div class="row">
<form id = "partsQuantForm">
<div class="col-lg-12" style="width:700px;overflow:auto; max-height:400px;">
<div class="partsTagsForm">
<table class="table table-striped" id="validTagsParts" style="width:100%;">
<thead>
<tr>
<th>Valid Row</th>
<th>Part </th>
<th># </th>
<th>Part </th>
<th># </th>
</tr>
</thead>
<tbody id="tagsPartsTable"></tbody>
</table>
</div>
<div class="col-md-12 text-center">
<input class="btn btn-outline-primary" type="button" id="tagsParts" style="height:40px; width:220px" value="Validate Parts ">
</div>
</div>
</form>
</div>
</div>
<script>
function buildTagPartsTable(){
validTagsInfo = ['Row1', 'Row2', 'Row3', 'Row4', 'Row5'];
var table = "<table>";
for (let key in validTagsInfo) {
table += `<tr>
<td>${validTagsInfo[key]}</td>
<td><input type="text" class="form-control" id = "partInfo" name="partInfo[0]" style="width:5em" minlength="5" maxlength="5" ></td>
<td><input type="number" class="form-control" id = "partQuantInfo" name="partQuantInfo[0]" style="width:3em" minlength="1" maxlength="1"></td>
<td><input type="text" class="form-control" id = "partInfo" name="partInfo[1]" style="width:5em" minlength="5" maxlength="5"></td>
<td><input type="number" class="form-control" id = "partQuantInfo" name="partQuantInfo[1]" style="width:3em" minlength="1" maxlength="1"></td>
</tr>`;
}
table += "</table>";
document.getElementById("tagsPartsTable").innerHTML = table;
}
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation#1.17.0/dist/jquery.validate.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
$('input').on('blur', function() {
if ($("#partsQuantForm").valid()) {
$('#tagsParts').prop('disabled', false);
} else {
$('#tagsParts').prop('disabled', true);
}
});
jQuery("#partsQuantForm").validate({
rules: {
'partInfo[]': {
required: true,minlength: 5,maxlength: 5
},
'partQuantInfo[]': {
required: true,minlength: 2,maxlength: 2
}
}
});
});
</script>

Javascript, pass values to new added table row/cell

basically the objective of this request is to have a modal table that adds new table row/cells and pass the value of "var OBGyneID = $(this).attr("id"); " to first cell and value of "var billing_id = newID;" to second cell whenever new rows/cells is/are added. Seeking your help, thanks!
* MY MODAL*
<div id="myModal" class="modal fade card new-contact myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="card profile">
<div class="profile__img">
<img src="img/profile2.jpg" alt="">
</div>
<div class="profile__info">
<h3 style="text-transform:capitalize;" id="pxname" name="pxname"></h3>
<ul class="icon-list">
<li>LAST <p name="consdates" id="consdates"></p></li>
<li>Last visit: </li>
<li><i class="zmdi zmdi-twitter"></i> #mallinda-hollaway</li>
</ul>
</div>
</div>
<div>
<div class="table-responsive">
<table id="billingTable" class="table table-inverse table-sm table-hover table-condensed" style="font-size:120%">
<thead>
<th>OBDYID</th>
<th>CK</th>
<th>PROCEEDURE</th>
<th>AMOUNT</th>
</thead>
<tbody id="billing_body" style="text-transform:capitalize;">
<form method="get" id="insert_form">
<tr>
<td width="10%"><input type="text" style="width:100%;" id="OBGyneID" name="OBGyneID"></td>
<td width="10%"><input type="text" style="width:100%;" id="AssessMentEntryID" name="AssessMentEntryID"></td>
<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" id="ExamDesc" name="ExamDesc"></td>
<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" id="Price" name="Price"></td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<input type="submit" name="insert" id="insert" value="Insert" class="btn btn-success" />
<input type="submit" id="addRow" value="add" name="add" class="btn btn-info" />
<button type="button" class="btn btn-link" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
* MY JS to add new rows/cells*
$(document).ready(function () {
$("#addRow").click(function () {
$("#billingTable").append('<tr><td width="10%"><input type="text" style="width:100%;" id="OBGyneID" name="OBGyneID" ></td>'+
'<td width="10%"><input type="text" style="width:100%;" id="AssessMentEntryID" name="AssessMentEntryID"></td>'+
'<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" id="ExamDesc" name="ExamDesc"></td>'+
'<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" id="Price" name="Price"></td></tr>');
jQuery(".ExamDesc").autocomplete({
source: 'php/billingentry.php'
});
});
});
* Pass values to Modal * this will only pass value when modal pops-up but cant pass value whenever new rows/cells are added.
$(document).on('click', '.billing_data', function(){
var OBGyneID = $(this).attr("id");
var newID = new Date().getUTCMilliseconds();
var billing_id = newID;
$.ajax({
url:"php/billing_fetch.php",
method:"GET",
data:{OBGyneID: OBGyneID},
dataType:"json",
success:function(data){
$('#AssessMentEntryID').val(data.AssessMentEntryID);
$('#ExamDesc').val(data.ExamDesc);
$('#Price').val(data.Price);
$('#pxservice').val(data.pxservice);
$('#companyname').val(data.companyname);
$('#chiefcomplain').val(data.chiefcomplain);
document.getElementById("OBGyneID").value = OBGyneID;
document.getElementById("AssessMentEntryID").value = billing_id;
document.getElementById("pxname").innerHTML = (data.fname)+" "+(data.mi)+" "+(data.lname);
document.getElementById("consdates").innerHTML = (data.obgyneDate);
$('#myModal').modal('show');
}
});
});
whenever you are adding a new row HTML in billing table, you are using the same id for OBGyneID, AssessMentEntryID,ExamDesc and Price. And if you added two rows, DOM will not be able to work properly as there are multiple same ids out there. So I will suggest you to replace that with class and use class name to set values. Check below code:
$(document).ready(function () {
$("#addRow").click(function () {
$("#billingTable").append('<tr><td width="10%"><input type="text" style="width:100%;" class="OBGyneID" name="OBGyneID" ></td>'+
'<td width="10%"><input type="text" style="width:100%;" class="AssessMentEntryID" name="AssessMentEntryID"></td>'+
'<td width="60%"><input type="text" style="width:100%;" class="ExamDesc" type="text" name="ExamDesc"></td>'+
'<td width="20%"><input type="text" style="width:100%;" class="Price" type="text" name="Price"></td></tr>');
jQuery(".ExamDesc").autocomplete({
source: 'php/billingentry.php'
});
});
});
One you have added HTML code, then you can find out last row of billingTable and can set vales in that. Check below code:
$(document).on('click', '.billing_data', function(){
var OBGyneID = $(this).attr("id");
var newID = new Date().getUTCMilliseconds();
var billing_id = newID;
$.ajax({
url:"php/billing_fetch.php",
method:"GET",
data:{OBGyneID: OBGyneID},
dataType:"json",
success:function(data){
$("#billingTable").find(".AssessMentEntryID:last").val(data.AssessMentEntryID);
$("#billingTable").find(".ExamDesc:last").val(data.ExamDesc);
$("#Price").find(".Price:last").val(data.Price);
$("#billingTable").find(".consdates:last").html(data.obgyneDate);
//and so on
$('#myModal').modal('show');
}
});
});
Also, I would suggest you to use HTMl template tag for making clone for row. Appending HTML in JS is not a recommended way. Hope it helps you.

Javascript add / remove textbox

I have the below javascript and I cannot take the values from the textbox that code generates to the html
("#btnAdd").bind("click", function () {
var div = $("<tr />");
div.html(GetDynamicTextBox(""));
$("#TextBoxContainer").append(div);
});
$("body").on("click", ".remove", function () {
$(this).closest("tr").remove();
});
});
function GetDynamicTextBox(value) {
return '<td><textarea name = "prodcut_name" type="text" value = " ' + value + '" class="form-control" /></td>' + '" /></td>'+ '<td><textarea name = "product_directions" type="text" value = "' + value + '" class="form-control" /></td>' + '<td><button type="button" class="btn btn-danger remove">X</button></td>'
my html form that I need to take the values
<form action="{{action('ProductController#store', $id)}}" method="post">
<h5 class="text-center">Product</h5>
<section class="container">
<div class="table table-responsive">
<table class="table table-responsive table-striped table-bordered">
<thead>
<tr>
<td>Product Name</td>
<td>Details</td>
<td>Remove</td>
</tr>
</thead>
<tbody id="TextBoxContainer" >
</tbody>
<tfoot>
<tr>
<th colspan="5">
<button id="btnAdd" type="button" class="btn btn-primary" data-toggle="tooltip" data-original-title="Add more controls"></i>+ Add </button></th>
</tr>
</tfoot>
</table>
</div>
</section>
This is how you add text area using pure javascript.
let textAreaDiv = document.getElementById("textAreaDiv");
addButton.onclick = addTextArea;
function addTextArea() {
let textArea = document.createElement("TEXTAREA");
textArea.value = "Nice to see you";
textAreaDiv.appendChild(textArea);
}
<button id="addButton">
Add text Area
</button>
<div id="textAreaDiv">
</div>
body
<form action="server.php" method="post">
<div id="fields"></div>
<button id="btnAdd">Add</button>
<input type="submit" value="Submit">
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script>
(function() {
let fieldIndex = 0
$('#btnAdd').click(() => {
// Create every textarea with different name
let field = $('<textarea>', {
name: `field${fieldIndex++}`
})
$('#fields').append(field)
return false
})
})()
</script>
Get values on server side
server.php
<?php echo json_encode($_POST) ?>

Make static functions to be dynamic

I am doing an exercise to learn JavaScript. I am having issues making my program dynamic. What I want to do here is:
Create two input to let the user set up the new product data.
Create a button. This button will have assigned a click event that will: 1- Get the data from the inputs. 2- Create a new product row with the data we stored.
Be able to delete all items and decrease total price based on the price of reminding item. In case there is no item, total price should be 0.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Shoping</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/index.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<header>
<h1 class="h1 text-center mb">Shoping<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span></h1>
</header>
<table class="table mb">
<thead>
<tr>
<th>Products:</th>
<th>Price:</th>
<th>Quantity:</th>
<th>Total:</th>
<th>
</th>
</tr>
</thead>
<tbody id="soyTBody">
<tr id="itemSubject">
<th scope="row"><span id="productName">T-Shirts</span></th>
<td class="price1"> <span class="dolar">$</span><span id="product">15</span></td>
<td class="qty1">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem1">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<tr id="itemSubject2">
<th scope="row"><span id="productName">Stickers</span></th>
<td class="price2"> <span class="dolar">$</span><span id="product2">2</span></td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputQty">QTY</label>
<input type="text" id="qty2" class="form-control mx-sm-3" maxlength="3" aria-describedby="qtyItem2">
</div>
</form>
</td>
<td <span class="dolar">$</span><span id="total2">0.00</span></td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" onclick="removeItem2()" value="delate">
<input id ="delateButton" class="delateItem" type="button" value="Delate">
</button>
</td>
</tr>
<!-- <tr>
<th scope="row">Stickers</th>
<td class="price2">$1</td>
<td class="qty2">
<form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty2text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total-2">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
<!-- <tr>
<th scope="row">Flags</th>
<td class="price3">$2</td>
<td class="qty3"><form class="form-inline">
<div class="form-group">
<label for="inputPassword4">QTY</label>
<input type="text" id="qty3text" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
</div>
</form>
</td>
<td class="total3">$0.00</td>
<td class="text-right">
<button class="delate btn btn-danger" type="button" value="delate">
<span class="delateButton"><strong>Delate</strong></span>
</button>
</td>
</tr> -->
</tbody>
</table>
<div class="row text-right">
<button class="delate btn btn-success" onclick="getPrice();getPrice2();totalPrice2()" type="submit" value="calculatePriceButton" >
<input id ="calc-prices-button" class="calculator" type="button" value="Calculate Prices">
<!-- <span class="delateButton"><strong>Calculate Prices</strong></span> -->
</button>
</div>
<h2 class="text-center">Total Price: $<span id="totalPrice"></span></h2>
</div>
</body>
</html>
JS:
// qty
function getQty() {
var qty = document.querySelector("#qty").value;
document.querySelector("#total").innerHTML = qty;
return qty;
}
getQty();
// qty2
function getQty2() {
var qty2 = document.querySelector("#qty2").value;
document.querySelector("#total2").innerHTML = qty2;
return qty2;
}
getQty();
// Price
function getPrice() {
var price = parseInt(document.querySelector("#product").innerHTML);
document.querySelector("#total").innerHTML = price * getQty();
}
getPrice();
// Price 2
function getPrice2() {
var price2 = parseInt(document.querySelector("#product2").innerHTML);
document.querySelector("#total2").innerHTML = price2 * getQty2();
}
getPrice2();
// total Price
function totalPrice2() {
var total = parseInt(document.querySelector("#total").innerHTML);
var total2 = parseInt(document.querySelector("#total2").innerHTML);
document.querySelector("#totalPrice").innerHTML = total + total2;
}
totalPrice2();
//Romove Item
function removeItem() {
var remove = document.querySelector("#itemSubject").remove("itemSubject");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem();
function removeItem2() {
var remove = document.querySelector("#itemSubject2").remove("itemSubject2");
// setTimeout(function() { alert("Your shopping cart is empty"); }, 1000);
}
removeItem2();
For your getPrice() and getPrice2() functions, we can make them dynamic by changing the following:
var price = parseInt(document.querySelector("#product").innerHTML);
and
var price2 = parseInt(document.querySelector("#product2").innerHTML);
These lines looks for elements with static names, instead we should give all inputs a common class name and loop through them. That way, we don't have to rely on static element IDs. For example, if we gave each input the class 'quantityinput', we can do the following:
var elements = document.getElementsByClassName("quantityinput");
for(var i=0; i<elements.length; i++) {
// Select this element and get its quantity
var this_total = elements[i].value;
// Get the price for this element by selecting the price td, then its second child
var this_price = elements[i].parentElement.parentElement.parentElement.previousSibling.childNodes[2].value;
// Select the total label for this row
var this_total_label = elements[i].parentElement.parentElement.parentElement.childNodes[1];
// Now update the total label for this row by multiplying the price and the quantity
this_total_label.value = this_total * this_price;
}
Now we don't have to worry about a certain row missing, since we iterate through all existing rows. A similar approach can be taken when calculating the total price for all rows, just loop through each rows total price, add them together then assign the total to the total price label.

Saving multiple rows with jQuery

I have a form with 2 fields with an add row button. When this button is clicked it simply clones the row and adds another row consisting of the 2 form fields. How do I save these newly added fields in my ajax post? Right now, it only ever saves the last row in my form.
<form action="." method="post">
<table class="table table-condensed" id="pa">
<thead>
<tr>
<th class="col-xs-2">Description</th>
<th class="col-xs-2">Expected %</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-group">
<input class="text-box single-line" data-val="true" data-val-required="The Description field is required." id="Description" name="Description" value="" type="text">
</div>
</td>
<td>
<div class="form-group">
<div class="input-group">
<input class="text-box single-line" data-val="true" data-val-number="The field Expected must be a number." id="Expected" name="Expected" value="100" type="number">
</div>
</div>
</td>
<td class="vert-align"> <a class="btn btn-danger btn-xs remove-row-pa">x</a>
</td>
</tr>
</tbody>
</table>
<div class="pull-right">
<p> <a href="#" id="add-pa-row" class="btn btn-success btn-xs">
<i class="fa fa-plus-circle"></i> Add row
</a>
</p>
</div>
<div class="form-group">
<p>
<input value="Save" class="btn btn-success" type="submit">
</p>
</div>
</form>
function Qs2Dict(qs) {
var pairs = qs.split('&');
var dict = {};
pairs.forEach(function (pair) {
var kv = pair.split('=');
dict[kv[0]] = decodeURIComponent(kv[1].replace(/\+/g, "%20"));
});
return dict;
}
// Add row
$("#add-row").click(function () {
$('#pa tbody>tr:last').clone(true).insertAfter('#pa tbody>tr:last');
$('#pa tbody>tr:last #Description').val('');
$('#pa tbody>tr:last #Expected').val('');
return false;
});
$('#modal').click(function (e) {
e.preventDefault();
var url = $(this).data('url');
var data = $('form').serialize();
var dict = Qs2Dict(data);
$.ajax({
type: "POST",
url: url,
data: {
"Description": dict.Description,
"EffectiveDate": dict.EffectiveDate,
"Expected": dict.Expected,
},
success: function (result) {},
});
});
Change their name attribute, since it defines/enumerates the fields to save.
If they are equal, which they are if you clone, only the last one is taken.
Or use arrays i.e. name="Expected[]"
EDIT: more specifically: I assume they get "lost" due to above reason during $('form').serialize();

Categories

Resources