good day to all of you. I am having trouble on how can I implement the logic of summing up the value of my indexed variable which changes on an event.
When the user has selected a value in select (the quantity is declared and has a default value of 1) the update() will trigger and will compute the total_amount.
The problem I encountered is when I clicked addNewField() and new input has been created an input a new value to the added field, the total_amount is computing only that specific index field and not summing up all the indexed fields.
JS file
vm.update = function(index) {
vm.amount[index] = vm.quantity[index] * vm.selectedItem[index].price;
for(var i=0; i <= index; i++){
var sum = 0;
sum += parseInt(vm.amount[i]);
}
vm.total_amount = sum;
}
vm.addNewField = function(){
if(checkValue() == true){
var index = vm.fields.length;
vm.fields.push({'id': index });
vm.quantity[index] = 1;
}
}
HTML file
<div class="row" ng-repeat="field in vm.fields track by $index">
<div class="form-group col-sm-8">
<label>Item Name</label>
<select ng-model="vm.selectedItem[$index]" ng-options="item as item.item_name for item in vm.items" ng-change="vm.update($index)" class="form-control">
</select>
</div>
<div class="col-sm-3">
<div class="form-group">
<label>Quantity</label>
<input type="number" class="form-control" ng-change="vm.update($index)" ng-model="vm.quantity[$index]" placeholder="123">
</div>
</div>
<div class="col-sm-1">
<div class="form-group">
<a ng-show="$index != '0'" href="" ng-click="vm.removeField($index)" class="button"><i class="fa fa-lg fa-trash"></i>
</a>
</div>
</div>
</div>
<div class="card-footer">
<button type="button" ng-click="vm.addNewField()" class="btn btn-sm btn-primary "><i class="fa fa-plus-circle"></i> Add Field</button>
</div>
<div class="row">
<div class="col-sm-6">
<label><strong>Total Amount:</strong></label>
</div>
<div class="col-sm-6" >
<label><strong>{{ vm.total_amount }}</strong></label>
</div>
</div>
var sum = 0;
for(var i=0; i <= index; i++){
sum += parseInt(vm.amount[i]);
}
Sum should be outside loop
Related
I have a form whose results(a list of links) are displayed in a table right below the form. However, I want to add a functionality that if the checkbox is checked, then all the links in the results should be opened on different tabs. Given below is my code:
<div class="card" id="emulstatform">
<div class="card-header">
<div class="card-title">
<div style="font-size: 25px"Filter</div>
</div>
</div>
<br>
<div class="card-body">
<div class="row">
<div class="col-xs-6">
<label name="start_date" class="control-label" style="width:35%;padding-left:15px">Start date</label>
<input type="date" id="start_date" style="color:black;width:100px" ></input>
</div>
<div class="col-xs-6">
<label name="end_date" class="control-label" style="width:35%">End Date(Default: Current Date)</label>
<input style="color:black;width:100px" id="end_date" type="date"></input>
</div>
</div>
<br>
<div class="row">
<div class="col-xs-6">
<label name="fruit_name" class="control-label" style="width:35%; padding-left:15px">Select a fruit</label>
<select class="js-example-placeholder-single1 js-example-basic-multiple form-control" id="fruit_name" placeholder="Select" style="width:210px" multiple="multiple">
</select>
</div>
<div class="col-xs-6">
<label name="fruit_test" class="control-label" style="width:35%">Select fruit_TEST</label>
<select class="js-example-placeholder-single2 js-example-basic-multiple form-control" style="width:210px" id="fruit_test" multiple="multiple">
</select>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<label name="fruit_version" class="control-label" style="width:35%; padding-left:15px">Select fruit message</label>
<select class="js-example-placeholder-single3 js-example-basic-multiple form-control" style="width:210px" id="fruit_message1" multiple="multiple">
</select>
</div>
</div>
<div class="text-center">
<div class="checkbox">
<label><input type="checkbox" value="0" id="newTabs" ><em>Open on Different tabs</em></label>
</div>
<button class="btn btn-md btn-default" v-on:click="loadResults">
<i class="fa fa-arrow-circle-right"></i> Submit
</button>
<button class="btn btn-md btn-default" type="reset" name="searchreset" value="reset">
<i class="fa fa-arrow-circle-right"></i> Reset
</button>
</div>
</div>
</div>
Here is the AJAX through which I fetch my data from backend:
document.onload(getformdata())
function getformdata() {
var self = this;
$.ajax({
url : window.location.href,
type:'GET',
cache:false,
data:{type:'formdata'},
success:function(res){
if(res.message){
alert("Error getting data for the form")
}
ele1 = document.getElementById('fruit_name');
ele2 = document.getElementById('fruit_test');
ele4 = document.getElementById('fruit_message1');
for (var i = 0; i<res.options.fruit_name.length; i++){
var opt = document.createElement('option');
opt.value = res.options.fruit_name[i];
opt.innerHTML = res.options.fruit_name[i];
ele1.appendChild(opt);
};
for (var i = 0; i<res.options.fruit_test.length; i++){
var opt = document.createElement('option');
opt.value = res.options.fruit_test[i];
opt.innerHTML = res.options.fruit_test[i];
ele2.appendChild(opt);
}
var start_date = document.getElementById('start_date')
var end_date = document.getElementById('end_date')
start_date.innerHTML = res.options.start_date
end_date.innerHTML = res.options.end_date
},
error : function(err){
self.message = "Error getting data for the form";
}
});
}
The url of each link is of the form fruitdata/?id=1000 , where id is the only parameter that changes for a different fruit. How do I achieve this functionality of opening these links on different pages??
If I understood your question correctly you need something like below to open new tab:
<button onclick="myFunc()">open google in new tab</button>
<script>
function myFunc() {
window.open("https://www.google.com");
}
</script>
for opening multiple tab you can use this code but If the end-user is running Popup Blocking software (like that built into Chrome) then it may automatically stop those other windows/tabs from opening.
let urls = ["https://stackoverflow.com", "https://stackexchange.com/"];
for (var i = 0; i<2; i++){
window.open(urls[i]);
}
for find out when your check box is checked this code can help:
$("input[type=checkbox]").on('change',function(){
if($("input[type=checkbox]").is(':checked'))
alert("checked");
else{
alert("unchecked");
}
}
I hope this code help you.
Good morning, I want to get all the records in a table and add them to an array and then register them to the database using ajax.
The problem I have is that using .each I get the values of the first row correctly, but when adding another row, the array ends up duplicated.
I share some images so that my problem is better understood
debugging the first row of the table
duplicates
all duplicate table rows
Javascript
function AgregarLista() {
const TD = $('<td></td>');
const TR = $('<tr></tr>');
const TABLE_VENTA = $('#dtVenta');
const PRODUCT_TOTAL = $('#TotalPagar');
let item = 0;
$('#btnAgregarTabla').click(function () {
item++;
let id_cliente = $('#id_cliente').val();
let id_producto = $('#id_producto').select2('val');
let precio_producto = $('#precio').val();
let stock_producto = $('#stock').val();
let cantidad_producto = $('#cantidad').val();
let subtotal_producto = parseInt(precio_producto) * parseInt(cantidad_producto);
let nro_venta = TD.clone().html(item).addClass('nro_sale');
let cliente = TD.clone().html(id_cliente).addClass('td_customer');
let producto = TD.clone().html(id_producto).addClass('td_product');
let precio = TD.clone().html(precio_producto).addClass('td_price');
let stock = TD.clone().html(stock_producto).addClass('td_stock');
let cantidad = TD.clone().html(cantidad_producto).addClass('td_quantity');
let preciototal = TD.clone().html(subtotal_producto).addClass('subtotal');
let newRow = TR.clone().append(nro_venta, cliente, producto, precio, stock, cantidad, preciototal);
let total = subtotal_producto;
$('.subtotal').each(function (index, tr) {
total = total + parseInt($(this).text());
});
TABLE_VENTA.find('tbody').append(newRow);
PRODUCT_TOTAL.find('#total_pagar').val(total);
//*===========================================================
//* here I call the method I use to get the array
//* ==========================================================
loopDetailTable();
});
}
With this code I get the values of the table rows
// * ==============================================
//* With this code I get the values of the table rows
// * ==============================================
function loopDetailTable(params) {
let index = 0;
var obj = new Object();
obj.DetailsList = [];
$('#dtVenta').each(function () {
let item_detalle = new Object();
item_detalle.vNumero = $('.nro_sale').text();
item_detalle.cID = $('.td_customer').text();
item_detalle.pID = $('.td_product').text();
item_detalle.pPrice = $('.td_price').text();
item_detalle.pStock = $('.td_stock').text();
item_detalle.pQuantity = $('.td_quantity').text();
item_detalle.pSubtotal = $('.subtotal').text();
obj.DetailsList[index] = item_detalle;
index++;
console.log(obj);
});
return obj;
}
HTML form
<div class="d-flex">
<div class="col-md-5">
<form role="form">
<div class="card">
<div class="card-body">
<h5>Datos del cliente:</h5>
<div class="form-group d-flex">
<div class="col-md-6 d-flex">
<input type="text" name="dni" id="dni" class="form-control" placeholder="dni cliente">
<input type="button" id="btnBuscarCliente" value="Buscar" class="btn btn-outline-danger">
</div>
<div class="col-md-6">
<input type="hidden" name="id_cliente" id="id_cliente" value="">
<input type="text" name="nombre_cliente" id="nombre_cliente" value="" class="form-control" placeholder="Cliente" disabled>
</div>
</div>
<h5>Datos del producto:</h5>
<div class="form-group d-flex">
<div class="col-md-6 d-flex">
<!-- <input type="text" name="id_producto" id="id_producto" class="form-control" placeholder="codigo producto"> -->
<select name="id_producto" id="id_producto" class="id_producto js-states form-control"></select>
<input type="button" id="btnBuscarProducto" value="Buscar" class="btn btn-outline-danger">
</div>
<div class="col-md-6">
<input type="text" name="nombre_producto" id="nombre_producto" class="form-control" placeholder="Producto" disabled>
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<input type="text" name="precio" id="precio" class="form-control" placeholder="s/.0.00" disabled>
</div>
<div class="col-md-4">
<input type="number" name="stock" id="stock" class="form-control" placeholder="stock" disabled>
</div>
<div class="col-md-4">
<input type="number" name="cantidad" id="cantidad" value="1" class="form-control" placeholder="cantidad">
</div>
</div>
</div>
<div class="card-footer">
<input type="button" id="btnAgregarTabla" value="Agregar" class="btn btn-primary float-right">
</div>
</div>
</form>
</div>
<div class="col-md-7">
<div class="card">
<div class="card-body">
<div class="d-flex col-md-6 ml-auto">
<label class="mx-3 mt-1">Nro.serie:</label>
<input type="text" name="nro_serie" id="nro_serie" th:value="${serie}" class="form-control">
</div>
<table id="dtVenta" class="table mt-4" style="width: 100%;">
<thead>
<tr>
<th>Nro.Venta</th>
<th>Cliente</th>
<th>Producto</th>
<th>Precio</th>
<th>Stock</th>
<th>Cantidad</th>
<th>SubTotal</th>
<tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div id="TotalPagar" class="card-footer">
<div class="row">
<input type="button" id="btnCancelarVenta" value="Cancelar" class="btn btn-danger">
<input type="button" id="btnGenerarVenta" value="Generar" class="btn btn-success mx-1">
<div class="d-flex ml-auto">
<label for="" class="mx-2 mt-1">Total:</label>
<input type="text" name="total_pagar" id="total_pagar" class="form-control">
</div>
</div>
</div>
</div>
</div>
</div>
Thank you all for your help, greetings.
You get 'duplicates' because of the selector. You select using the class names, which are not unique. For example $('.td_customer').text(); select all customer cells.
Which you don't want. You want only the customer cell of a certain row.
I think you can solve your problem with iterating over the table rows (you iterate over the tables with id dtVenta, that's only one table).
So try something like:
$('#dtVenta tr').each(function () {
// $(this) is the 'current' row of the table
let item_detalle = new Object();
item_detalle.vNumero = $(this).find('.nro_sale').text(); // find all child .nro_sale cells and get it's text
item_detalle.cID = $(this).find('.td_customer').text();
item_detalle.pID = $(this).find('.td_product').text();
item_detalle.pPrice = $(this).find('.td_price').text();
item_detalle.pStock = $(this).find('.td_stock').text();
item_detalle.pQuantity = $(this).find('.td_quantity').text();
item_detalle.pSubtotal = $(this).find('.subtotal').text();
obj.DetailsList[index] = item_detalle;
index++;
console.log(obj);
});
I've a razor form that I want to clone on button click such that I get unique ID for all the form fields. I'm able to do this if do not put any of the input elements in div or table. But when I do that, I do not get unique IDs. I've tried various solutions but nothing seems to work.
This is my razor code of form to be cloned
<div id="bookingForm" style="display:none; color:#fff;" class="container">
#{
int index = 0;
int hall = 0, slot = 0, requirement = 0;
<div style="font-family: 'Roboto', sans-serif;margin-bottom:30px;" class="row">
<div class="col-md-4 col-sm-4 col-4">
<label><h2>Starting Date</h2></label><br>
</div>
<div class="col-md-7 col-sm-7 col-7">
<input type="date" name="detailsObjList[#index].date" id="date" required onchange="datechosen();" style="width: 100%;" class="form-control start" />
</div>
#foreach (var item in ViewBag.HallDetail)
{
slot = 0;
<hr />
<span id="invalidDate" style="color:indianred;"></span>
<br />
<div style="font-family: 'Montserrat', sans-serif;" class="col-4">
<input type="hidden" name="detailsObjList[#index].hallsArray[#hall].hallID" value="#(item.hallID)" id="hiddenhall#(hall)_" />
<input type="hidden" name="detailsObjList[#index].hallsArray[#hall].hallName" value="#item.hallName" id="hiddenhallname#(hall)_" />
<label>#item.hallName :</label>
</div>
<div style="align-content: center;" class="col-8">
<table class="table table-responsive table-striped">
<tbody>
<tr>
<!--SLOTS-->
#foreach (var slotItem in item.slotsArray)
{
<th>
<input type="hidden" name="detailsObjList[#index].hallsArray[#hall].slotsArray[#slot].slotID" value="#(slotItem.slotID)" id="hiddenslot#(slot + 1)_#(hall + 1)_" />
<label class="custom-control custom-checkbox" id="lblSlot#(slot+1)_#(hall + 1)_" onmouseover="seeDetails(#(slot+1),#(hall+1))" style="color:#fff;">
<input type="checkbox" class="custom-control-input" data-toggle="tooltip" name="detailsObjList[#index].hallsArray[#hall].slotsArray[#slot].isSelected" id="slotcheck#(slot + 1)_#(hall + 1)_" onchange="slotcheckchange(#(slot + 1), #(hall + 1));" />
<span class="custom-control-indicator"></span><span class="custom-control-description">#slotItem.slot</span>
</label>
<span id="span#(slot+1)_#(hall + 1)_" style="color:indianred;"></span>
</th>
slot = slot + 1;
}
</tr>
</tbody>
</table>
</div>
hall = hall + 1;
}
</div>
hall = 0;
slot = 0;
}
</div>
I'm cloning this form below
#using (Html.BeginForm("Testing", "BookUtility", FormMethod.Post))
{
<span id="writeroot"></span>
<button class="btn btn-success"><i class="fa fa-check-circle" aria-hidden="true"></i> Submit</button>
}
<button id="btnAddMore" class="btn btn-danger" onclick="addMore(#index, #hall, #slot);"><i class="fa fa-plus-circle" aria-hidden="true"></i> Add more</button>
JavaScript Code:
var click = 0;
var addMore = function (index, hall, slot) {
click = click + 1;
var newFields = document.getElementById('bookingForm').cloneNode(true);
newFields.id = '';
newFields.style.display = '';
var newField = newFields.childNodes;
for (var i = 0; i < newField.length; i++) {
var newId = newField[i].id
if (newId)
newField[i].id = newId + click;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields, insertHere);
}
I have three cascading select lists. When I try to reset them with this code:
function resetSearch(advancedSearch){
document.getElementById("advancedSearch").reset();
submitQuery();
};
It resets the select lists, but because the select lists are cascading, so one depends on another to fill the select list with the correct values, it sets the values of the lists that are selected at that moment to the default.
So in my case I have three selectlists, one for the table names, one for the field names and one for the attributes. When I select a table it gives me the matching column names and attributes. If I than push teh reset button, it resets the table name to default, but the fieldnames and attribute select lists are set to the default of the other table.
Here is a picture to clarify my question:
This is my form with the select lists in it and the reset button;
<form action="javascript:submitQuery()" id="advancedSearch">
<!-- Search by name input field -->
<div class="form-group">
<div id= "selectListContent">
<div class="row">
<div id="content-a">
<div class='content-row'>
<div class="select_table col-md-6">
<label for="invoerTabelNaam">Select table:</label>
<span>
<select class="form-control" name="table_names" id="slctTable">
</select>
</span>
</div>
<div class="select_column col-md-6">
<label for="invoerColumnNaam">Select column:</label>
<span>
<select class="form-control" name="column_names" id="slctField">
</select>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="select_attribute col-md-9">
<label for="invoerAttribuutNaam">Select attribute:</label>
<span>
<select class="form-control" name="attribute_names" id="slctAttribute">
</select>
</span>
</div>
</div>
</div>
</div>
<!-- Buttons search en reset voor tab advanced search -->
<div class="form-group">
<div class="col-md-6">
<button type="reset" class="btn btn-block btn-primary" onclick="resetSearch()">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>   Reset
</button>
</div>
</div>
</div>
I assume that you have some event which populates other selects when value in first select is chosen. In that case you need to trigger it after form is reset.
For e.g.:
function resetSearch() {
$('#slctTable').closest('form')[0].reset();
$('#slctTable').trigger('change');
}
To clarify: how reset could 'know' that for 'table 1' correct list of fields is 'field1' and 'field2' and for 'table 2' it is 'other1' and 'other2'? It can just set selection to first items of lists.
var data = {
'table1': {
'tab1_column1': ['tab1_col1_attr_1', 'tab1_col1_attr_2'],
'tab1_column2': ['tab1_col2_attr_1', 'tab1_col2_attr_2']
},
'table2': {
'tab2_column1': ['tab2_col1_attr_1', 'tab2_col1_attr_2'],
'tab2_column2': ['tab2_col2_attr_1', 'tab2_col2_attr_2']
}
}
function resetSearch() {
$('#slctTable').closest('form')[0].reset();
$('#slctTable').trigger('change');
}
$(function() {
var table = $('#slctTable'),
field = $('#slctField'),
attr = $('#slctAttribute');
table.on('change', function() {
field.html('').val('');
$.each(data[$(this).val()], function(k, v) {
field.append($("<option />").val(k).text(k))
});
field.trigger('change');
});
field.on('change', function() {
attr.html('').val('');
$.each(data[table.val()][$(this).val()], function(k, v) {
attr.append($("<option />").val(v).text(v))
});
});
$.each(data, function(k, val) {
table.append($("<option />").val(k).text(k))
});
//populate fields for the first time
table.trigger('change');
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="javascript:submitQuery()" id="advancedSearch">
<!-- Search by name input field -->
<div class="form-group">
<div id="selectListContent">
<div class="row">
<div id="content-a">
<div class='content-row'>
<div class="select_table col-md-6">
<label for="invoerTabelNaam">Select table:</label>
<span>
<select class="form-control" name="table_names" id="slctTable">
</select>
</span>
</div>
<div class="select_column col-md-6">
<label for="invoerColumnNaam">Select column:</label>
<span>
<select class="form-control" name="column_names" id="slctField">
</select>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="select_attribute col-md-9">
<label for="invoerAttribuutNaam">Select attribute:</label>
<span>
<select class="form-control" name="attribute_names" id="slctAttribute">
</select>
</span>
</div>
</div>
</div>
</div>
<!-- Buttons search en reset voor tab advanced search -->
<div class="form-group">
<div class="col-md-6">
<button type="reset" class="btn btn-block btn-primary" onclick="resetSearch()">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>   Reset
</button>
</div>
</div>
function resetSearch(advancedSearch){
change for this:
function resetSearch(){
I have create from your initial HTML and description this Codepen with cascading population of field. I do not see your problem. Could you provide more explaination or to say if this resolve your problem?
Codepen: http://codepen.io/anon/pen/ezmErd
HTML
<form class="container" action="javascript:submitQuery()" id="advancedSearch">
<div class="form-group">
<div id="selectListContent">
<div class="row">
<div id="content-a">
<div class='content-row'>
<div class="select_table col-md-6">
<label for="invoerTabelNaam">Select table:</label>
<span>
<select class="form-control" name="table_names" id="slctTable">
</select>
</span>
</div>
<div class="select_column col-md-6">
<label for="invoerColumnNaam">Select column:</label>
<span>
<select class="form-control" name="column_names" id="slctField">
</select>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="select_attribute col-md-9">
<label for="invoerAttribuutNaam">Select attribute:</label>
<span>
<select class="form-control" name="attribute_names" id="slctAttribute">
</select>
</span>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-3">
<button type="reset" class="btn btn-block btn-primary" onclick="resetSearch('advancedSearch')">
<span class="glyphicon glyphicon-repeat" aria-hidden="true"></span>   Reset
</button>
</div>
</div>
</form>
JS
var table = document.getElementById("slctTable"),
field = document.getElementById("slctField"),
attrib = document.getElementById("slctAttribute"),
populate = function (dropdown, name) {
for (var i = 0, temp; i < 4; i++) {
temp = document.createElement("option")
temp.value = i + 1;
temp.textContent = name + " " + +(i + 1);
dropdown.appendChild(temp);
}
},
submitQuery = function () {
console.log("Submit !");
},
resetSearch = function (advancedSearch) {
document.getElementById(advancedSearch).reset();
submitQuery();
};
// Populate dynamicly the first Dropdown.
populate(table, "Table");
// When you select an item of first Dropdown...
table.addEventListener("change", function() {
field.innerHTML = "";
// ...populate dynamicly the second Dropdown.
populate(field, "Field");
});
// When you select an item of second Dropdown...
field.addEventListener("change", function() {
attrib.innerHTML = "";
// ...populate dynamicly the last Dropdown.
populate(attrib, "Attribute");
});
When I click duplicate it duplicates the row fine, but when I click it again I get another 2, then 4 etc, how can I stop this from happening and just clone one div on each click...
Jquery:
<script>
$(".clonable-button").bind('click', function(e){
e.preventDefault();
var section = $(this).data('clone');
var parent = $('[data-id="' + section + '"]');
var sequence = 0;
if(!$(this).data('last')) {
sequence = $(parent).find('.cloneable').last().data('id');
} else {
sequence = $(this).data('last');
}
$(this).data('last', ++sequence);
$(parent).append(parent.html());
});
$('.clone-wrapper').on('click', '.clone-remove',function(){
var parent = $(this).parents('.cloneable');
$(parent).remove();
});
</script>
html:
<div class="clone-wrapper" data-id="skill">
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>
</div>
<div class="white-space-20"></div>
<div class="row text-right">
<div class="col-md-12">
<div class="btn btn-default btn-sm clonable-button" id="skill">
<i class="fa fa-plus"></i> Add Skill </div>
</div>
</div>
I just want the following code duplicated once on each click
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>
The problem is in this line:
var parent = $('[data-id="' + section + '"]');
Each time you append new block with the same data-id number of elements that match this selector increases. So to avoid this you have make the selector more specific. Like:
var parent = $('[data-id="' + section + '"]:last');
Also there is a jQuery method to clone the element. So change your line from:
$(parent).append(parent.html());
to:
parent.append(parent.clone());
That will fix the issue.
You are binding the click event multiple times somehow, You should either use a delegated event handler or use the off method like below.
$(".clonable-button").off('click').on('click', function(e){