I'm trying to figure out how to store the data from a dynamic table to the database.
Here's the idea: I'm developing a system to control the drivers journey. It basically will store the day work of the driver, spliting it on differente intervals, such as: Driving time, meal time, waiting time, etc (all of them in HH:MM). They will be adding in different tables, as the following picture shows.
Journey Control
The input data (hour), for each table, can be different. It will depend on the driver's day journey. I need to catch and store those hours on a database.
My best idea is to get all those hours after the user ends the input, but how do I store that if I don't have the field's name?
Additional information: I'm using Java, SpringBoot and Thymeleaf to develop it.
JourneyControl.RegisterHourJourney = (function() {
var counterDriving = 0;
var counterInterval = 0;
var counterMeal = 0;
var counterWaiting = 0;
var counterRest = 0;
function RegisterJourneyHour() {
this.novaDrivingBtn = $('.js-add-new-direcao');
this.novoIntervalBtn = $('.js-add-new-intervalo');
this.novaMealBtn = $('.js-add-new-refeicao');
this.novaWaitingBtn = $('.js-add-new-espera');
this.novoRestBtn = $('.js-add-new-pernoite');
this.deleteDrivingBtn = $('#direcaot');
this.deleteIntervalBtn = $('#intervalot');
this.deleteMealBtn = $('#refeicaot');
this.deleteWaitingBtn = $('#esperat');
this.deleteRestBtn = $('#pernoitet');
}
RegisterHourJourney.prototype.start = function() {
this.novaDrivingBtn.on('click', onAdicionarHourDriving.bind());
this.novoIntervalBtn.on('click', onAdicionarHourInterval.bind());
this.novaMealBtn.on('click', onAdicionarHourMeal.bind());
this.novaWaitingBtn.on('click', onAdicionarHourWaiting.bind());
this.novoRestBtn.on('click', onAdicionarHourRest.bind());
this.deleteDrivingBtn.on('click', '.js-delete-btn',
onDeleteHourDriving.bind());
this.deleteIntervalBtn.on('click', '.js-delete-btn',
onDeleteHourInterval.bind());
this.deleteMealBtn.on('click', '.js-delete-btn',
onDeleteHourMeal.bind());
this.deleteWaitingBtn.on('click', '.js-delete-btn',
onDeleteHourWaiting.bind());
this.deleteRestBtn.on('click', '.js-delete-btn',
onDeleteHourRest.bind());
}
function onAdicionarHourDriving() {
/*var newRow = $("<tr id=\" " + + counterDriving + " \">");*/
var newRow = $("<tr>");
var cols = "";
var inputInicio = $('#inicioDirecao').val();
var inputFim = $('#fimDirecao').val();
var direcao = $('#direcao').val();
if (!inputInicio || !inputFim) {
alert('Os campos início e fim devem ser preenchidos.');
} else if (inputInicio.length != 5 || inputFim.length != 5) {
alert('Preencha as horas corretamente (HH:MM).');
} else {
cols += '<td>' + inputInicio + '</td>';
cols += '<td>' + inputFim + '</td>';
cols += '<td class="text-center"><a class=" btn btn-link btn-xs js-tooltip js-delete-btn" title="Delete" href="#" ><i class="glyphicon glyphicon-remove"></i></a></td>';
newRow.append(cols);
$("#direcaot").append(newRow);
counterDriving++;
$('#inicioDirecao').val('');
$('#fimDirecao').val('');
}
}
function onAdicionarHourInterval() {
var newRow = $("<tr>");
var cols = "";
var inputInicio = $('#inicioIntervalo').val();
var inputFim = $('#fimIntervalo').val();
if (!inputInicio || !inputFim) {
alert('Os campos início e fim devem ser preenchidos.');
} else if (inputInicio.length != 5 || inputFim.length != 5) {
alert('Preencha as horas corretamente (HH:MM).');
} else {
cols += '<td>' + inputInicio + '</td>';
cols += '<td>' + inputFim + '</td>';
cols += '<td class="text-center"><a class="btn btn-link btn-xs js-tooltip js-delete-btn" title="Delete" href="#" ><i class="glyphicon glyphicon-remove"></i></a></td>';
newRow.append(cols);
$("#intervalot").append(newRow);
counterInterval++;
$('#inicioIntervalo').val('');
$('#fimIntervalo').val('');
}
}
function onAdicionarHourMeal() {
var newRow = $("<tr>");
var cols = "";
var inputInicio = $('#inicioRefeicao').val();
var inputFim = $('#fimRefeicao').val();
if (!inputInicio || !inputFim) {
alert('Os campos início e fim devem ser preenchidos.');
} else if (inputInicio.length != 5 || inputFim.length != 5) {
alert('Preencha as horas corretamente (HH:MM).');
} else {
cols += '<td>' + inputInicio + '</td>';
cols += '<td>' + inputFim + '</td>';
cols += '<td class="text-center"><a class="btn btn-link btn-xs js-tooltip js-delete-btn" title="Delete" href="#" ><i class="glyphicon glyphicon-remove"></i></a></td>';
newRow.append(cols);
$("#refeicaot").append(newRow);
counterMeal++;
$('#inicioRefeicao').val('');
$('#fimRefeicao').val('');
}
}
function onAdicionarHourWaiting() {
var newRow = $("<tr>");
var cols = "";
var inputInicio = $('#inicioEspera').val();
var inputFim = $('#fimEspera').val();
if (!inputInicio || !inputFim) {
alert('Os campos início e fim devem ser preenchidos.');
} else if (inputInicio.length != 5 || inputFim.length != 5) {
alert('Preencha as horas corretamente (HH:MM).');
} else {
cols += '<td>' + inputInicio + '</td>';
cols += '<td>' + inputFim + '</td>';
cols += '<td class="text-center"><a class="btn btn-link btn-xs js-tooltip js-delete-btn" title="Delete" href="#" ><i class="glyphicon glyphicon-remove"></i></a></td>';
newRow.append(cols);
$("#esperat").append(newRow);
counterWaiting++;
$('#inicioEspera').val('');
$('#fimEspera').val('');
}
}
function onAdicionarHourRest() {
var newRow = $("<tr>");
var cols = "";
var inputInicio = $('#inicioPernoite').val();
var inputFim = $('#fimPernoite').val();
if (!inputInicio || !inputFim) {
alert('Os campos início e fim devem ser preenchidos.');
} else if (inputInicio.length != 5 || inputFim.length != 5) {
alert('Preencha as horas corretamente (HH:MM).');
} else {
cols += '<td>' + inputInicio + '</td>';
cols += '<td>' + inputFim + '</td>';
cols += '<td class="text-center"><a class="btn btn-link btn-xs js-tooltip js-delete-btn" title="Delete" href="#" ><i class="glyphicon glyphicon-remove"></i></a></td>';
newRow.append(cols);
$("#pernoitet").append(newRow);
counterRest++;
$('#inicioPernoite').val('');
$('#fimPernoite').val('');
}
}
function onDeleteHourDriving() {
var item = document.activeElement;
item.closest("tr").remove();
counterDriving -= 1;
}
function onDeleteHourInterval() {
var item = document.activeElement;
item.closest("tr").remove();
counterInterval -= 1;
}
function onDeleteHourMeal() {
var item = document.activeElement;
item.closest("tr").remove();
counterMeal -= 1;
}
function onDeleteHourWaiting() {
var item = document.activeElement;
item.closest("tr").remove();
counterWaiting -= 1;
}
function onDeleteHourRest() {
var item = document.activeElement;
item.closest("tr").remove();
counterRest -= 1;
}
return RegisterHourJourney;
}());
$(function() {
var RegisterHourJourney = new JourneyControl.RegisterHourJourney();
RegisterHourJourney.start();
});
<body>
<section layout:fragment="conteudo">
<div class="page-header">
<div class="container-fluid">
<div class="row">
<div class="col-xs-10">
<h1>Journey Control</h1>
<!-- <h1 th:if="${empresa.nova}">Cadastrar jornada</h1> -->
<!-- <h1 th:unless="${empresa.nova}" th:text="|Editar empresa - ${empresa.razaoSocial}|">Editar jornada</h1> -->
</div>
<div class="col-xs-2">
<div class="aw-page-header-controls">
<!-- <a class="btn btn-default" th:href="#{/empresas}"> -->
<a class="btn btn-default">
<i class="glyphicon glyphicon-plus-sign"></i>
<span class="hidden-xs hidden-sm">Search Journey</span>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<!-- <form method="POST" th:object="${jornada}" class="form-vertical js-form-loading"
th:action="${empresa.nova} ? #{/empresas/nova} : #{/empresas/{codigo}(codigo=${empresa.codigo})}"> -->
<form class="form-vertical js-form-loading">
<!-- <cj:message/> -->
<!-- <input type="hidden" th:field="*{codigo}" /> -->
<div class="row">
<div class="col-sm-2 form-group field-required">
<label for="data" class="control-label">Date</label>
<input id="data" type="text" class="form-control js-date" />
</div>
<div class="col-sm-5 form-group field-required">
<label for="motorista" class="control-label">Driver</label>
<input id="motorista" type="text" class="form-control" autofocus="autofocus" />
</div>
<div class="col-sm-1 form-group">
<label class="control-label">Day off</label>
<div>
<input type="checkbox" class="js-status" data-size="small" data-off-color="danger"
data-on-text="Yes" data-off-text="No" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-7 form-group">
<fieldset class="fieldset-border">
<legend class="legend-border">Driving Time</legend>
<div class="form-group row">
<!-- <label for="inicioDirecao" class="col-sm-1 col-form-label">Start</label> -->
<label for="inicioDirecao" class="col-sm-1 col-form-label">Start</label>
<div class="col-sm-3">
<input id="inicioDirecao" type="text" class="form-control js-hora">
<input type="hidden" value="DIRECAO"/>
</div>
<label for="EndDirecao" class="col-sm-1 col-form-label">End</label>
<div class="col-sm-3">
<input id="EndDirecao" type="text" class="form-control js-hora">
<input type="hidden" value="DIRECAO"/>
</div>
<div class="form-group col-sm-2">
<button type="button" class="btn btn-primary js-add-new-direcao">Add</button>
</div>
</div>
<div class="form-group row">
<div class="table-responsive bw-tabela-simples col-sm-10">
<table class="table table-hover">
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th></th>
</tr>
</thead>
<tbody id="direcaot">
</tbody>
</table>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-sm-7 form-group">
<fieldset class="fieldset-border">
<legend class="legend-border">Driving Interval</legend>
<div class="form-group row">
<label for="inicioIntervalo" class="col-sm-1 col-form-label">Start</label>
<div class="col-sm-3">
<input id="inicioIntervalo" type="text" class="form-control js-hora">
<input type="hidden" value="INTERVALO"/>
</div>
<label for="EndIntervalo" class="col-sm-1 col-form-label">End</label>
<div class="col-sm-3">
<input id="EndIntervalo" type="text" class="form-control js-hora">
<input type="hidden" value="INTERVALO"/>
</div>
<div class="form-group col-sm-2">
<button type="button" class="btn btn-primary js-add-new-intervalo">Add</button>
</div>
</div>
<div class="form-group row">
<div class="table-responsive bw-tabela-simples col-sm-10">
<table class="table table-hover">
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th></th>
</tr>
</thead>
<tbody id="intervalot">
</tbody>
</table>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-sm-7 form-group">
<fieldset class="fieldset-border">
<legend class="legend-border">Meal</legend>
<div class="form-group row">
<label for="inicioRefeicao" class="col-sm-1 col-form-label">Start</label>
<div class="col-sm-3">
<input id="inicioRefeicao" type="text" class="form-control js-hora">
<input type="hidden" value="REFEICAO"/>
</div>
<label for="EndRefeicao" class="col-sm-1 col-form-label">End</label>
<div class="col-sm-3">
<input id="EndRefeicao" type="text" class="form-control js-hora">
<input type="hidden" value="REFEICAO"/>
</div>
<div class="form-group col-sm-2">
<button type="button" class="btn btn-primary js-add-new-refeicao">Add</button>
</div>
</div>
<div class="form-group row">
<div class="table-responsive bw-tabela-simples col-sm-10">
<table class="table table-hover">
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th></th>
</tr>
</thead>
<tbody id="refeicaot">
</tbody>
</table>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-sm-7 form-group">
<fieldset class="fieldset-border">
<legend class="legend-border">Waiting Time</legend>
<div class="form-group row">
<label for="inicioEspera" class="col-sm-1 col-form-label">Start</label>
<div class="col-sm-3">
<input id="inicioEspera" type="text" class="form-control js-hora">
<input type="hidden" value="ESPERA"/>
</div>
<label for="EndEspera" class="col-sm-1 col-form-label">End</label>
<div class="col-sm-3">
<input id="EndEspera" type="text" class="form-control js-hora">
<input type="hidden" value="ESPERA"/>
</div>
<div class="form-group col-sm-2">
<button type="button" class="btn btn-primary js-add-new-espera">Add</button>
</div>
</div>
<div class="form-group row">
<div class="table-responsive bw-tabela-simples col-sm-10">
<table class="table table-hover">
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th></th>
</tr>
</thead>
<tbody id="esperat">
</tbody>
</table>
</div>
</div>
</fieldset>
</div>
</div>
<div class="row">
<div class="col-sm-7 form-group">
<fieldset class="fieldset-border">
<legend class="legend-border">Rest</legend>
<div class="form-group row">
<label for="inicioPernoite" class="col-sm-1 col-form-label">Start</label>
<div class="col-sm-3">
<input id="inicioPernoite" type="text" class="form-control js-hora">
<input type="hidden" value="PERNOITE"/>
</div>
<label for="EndPernoite" class="col-sm-1 col-form-label">End</label>
<div class="col-sm-3">
<input id="EndPernoite" type="text" class="form-control js-hora">
<input type="hidden" value="PERNOITE"/>
</div>
<div class="form-group col-sm-2">
<button type="button" class="btn btn-primary js-add-new-pernoite">Add</button>
</div>
</div>
<div class="form-group row">
<div class="table-responsive bw-tabela-simples col-sm-10">
<table class="table table-hover">
<thead>
<tr>
<th>Start</th>
<th>End</th>
<th></th>
</tr>
</thead>
<tbody id="pernoitet">
</tbody>
</table>
</div>
</div>
</fieldset>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Salvar</button>
</div>
</form>
</div>
</section>
<th:block layout:fragment="javascript-extra">
<script th:src="#{/javascripts/jornada.mascara-horas.js}"></script>
<script th:src="#{/javascripts/vendors/bootstrap-switch.min.js}"></script>
<script th:src="#{/javascripts/cadastro_jornada.js}"></script>
<script>
$('.js-status').bootstrapSwitch();
</script>
</th:block>
</body>
An example for meals:
When you add a new row, give it a name in the way of name="meal[" + nextMeal + "]", this nomenclature will map your new meal to a list of meals in the controller on form submission.
To know what's the proper value for nextMeal, do something like this:
var nextMeal = 0;
while($("tr[name='nextMeal[" + nextMeal + "]']").length){
nextMeal++;
}
Related
I would like someone to answer my question about how I can make the data typed in the Agenda fields be added to the table, with jQuery. Currently the table adds rows and also deletes them, but does not add the data entered in the form fields. Finally, I can't make the "save" button be placed below the table, or above it, static.
HTML - atv1-1:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<title>João Augusto - Agenda jQuery</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="estilos.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
</head>
<body>
<div class="p-5 text-black text-center bg-roxo">
<h1 id="titulo">João Augusto</h1>
</div>
<div class="container mt-5">
<div class="container">
<h5>Agenda</h5>
<form id="formulario">
<div class="row py-2">
<div class="col-1">
<label for="nome">Nome:</label>
</div>
<div class="col-5 ">
<input type="text" class="form-control" placeholder="Escrava o primeiro nome" name="nome">
</div>
</div>
<div class="row py-2">
<div class="col-1">
<label for="email">Email:</label>
</div>
<div class="col-5">
<input type="text" class="form-control" placeholder="email" name="email">
</div>
<div class="col-1">
<label for="cel">Celular:</label>
</div>
<div class="col-5">
<input type="text" class="form-control" placeholder="(XX)XXXX-XXXX" name="cel">
</div>
</div>
<div class="row py-2">
<div class="col-1">
<label for="insta">Instagram:</label>
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Instagram" name="insta">
</div>
<div class="col-1">
<label for="face">Facebook:</label>
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Facebook" name="face">
</div>
</div>
</form>
</div>
<!-- Tabela que conterá os dados-->
<div class="container mt-3">
<table class="table table-striped" id="myTable">
<tbody>
<tr>
<th>Nome</th>
<th>Email</th>
<th>Instagram</th>
<th>Celular</th>
<th>Facebook</th>
<th>Excluir</th>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>
<button type="button" onclick="remove(this)" class="btn btn-danger btn-xs">Excluir</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<button class='btn btn-danger excluir' onclick="AddTableRow()" type="button">Salvar</button>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="mt-5 p-4 bg-dark text-white text-center">
</div>
<script src="functions.js"></script>
</body>
</html>
jQuery (JS) - functions.js :
(function($) {
AddTableRow = function() {
var newRow = $("<tr>");
var cols = "";
cols += '<td> </td>';
cols += '<td> </td>';
cols += '<td> </td>';
cols += '<td> </td>';
cols += '<td> </td>';
cols += '<td>';
cols += '<button type="button" onclick="remove(this)" class="btn btn-danger btn-xs">Excluir</button>';
cols += '</td>';
newRow.append(cols);
$("#myTable").append(newRow);
return false;
};
})(jQuery);
(function($) {
remove = function(item) {
var tr = $(item).closest('tr');
tr.fadeOut(400, function() {
tr.remove();
});
return false;
}
})(jQuery);
This is my working solution:
View this on codepen.io
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script src="functions.js"></script>
FORM and Table, HTML: (Just replace this instead your form and your table
)
<form id="formulario">
<div class="row align-items-center py-2">
<div class="col-1">
<label for="nome">Nome:</label>
</div>
<div class="col-5 ">
<input type="text" class="form-control" placeholder="Escrava o primeiro nome" name="nome" value="JOÃO AUGUSTO">
</div>
<div class="col-1">
<label for="email">Select:</label>
</div>
<div class="col-5">
<select class="form-select" name="select">
<option value="">Not choosed</option>
<option value="Option1">Option1</option>
<option value="Option2">Option2</option>
<option value="Option3">Option3</option>
<option value="Option4">Option4</option>
</select>
</div>
</div>
<div class="row align-items-center py-2">
<div class="col-1">
<label for="email">Email:</label>
</div>
<div class="col-5">
<input type="text" class="form-control" placeholder="email" name="email">
</div>
<div class="col-1">
<label for="cel">Celular:</label>
</div>
<div class="col-5">
<input type="text" class="form-control" placeholder="(XX)XXXX-XXXX" name="celular">
</div>
</div>
<div class="row align-items-center py-2">
<div class="col-1">
<label for="insta">Instagram:</label>
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Instagram" name="instagram">
</div>
<div class="col-1">
<label for="face">Facebook:</label>
</div>
<div class="col">
<input type="text" class="form-control" placeholder="Facebook" name="facebook">
</div>
</div>
</form>
<div class="col-auto p-0 mt-3">
<button class="btn btn-success" onclick="Functions.addToTable('formulario','myTable')" type="button">Salvar</button>
</div>
</div>
<div class="container mt-3">
<table class="table table-striped text-center table-bordered my-3" id="myTable">
<tbody>
<!-- IF EMPTY ROWS :
<tr id="emptyTr"><td><i>empty</i></td></tr>
-->
<!-- IF CONST ROWS : -->
<tr id="tr_1">
<td><i>name</i></td>
<td><i>select</i></td>
<td><i>email</i></td>
<td><i>celular</i></td>
<td><i>instagram</i></td>
<td><i>facebook</i></td>
<td>
<button onclick="Functions.removeFromTable('formulario','myTable',1)" type="button" class="btn btn-sm btn-danger btn-xs">
Excluir
</button>
</td>
</tr>
<!---end Const Rows---->
</tbody>
</table>
functions.js: (just replace all this instead your functions.js)
//develope by: https://stackoverflow.com/users/3114914/
class Functions {
static trNumbers(tableId){
var table = $('#'+tableId);
var issetEmptyTr = table.find('tbody tr#emptyTr').length;
if(issetEmptyTr==1)
return 1;
else
return parseInt(table.find('tbody tr:last').attr('id').replace(/\D/g,''))+1;
}
static formData(formId){
var map = new Map();
var formInputLength = parseInt($('#'+formId+' input').length);
var formSelectLength = parseInt($('#'+formId+' select').length);
var formLength = formInputLength + formSelectLength;
for(let i=0; i < formLength; i++)
{
var inpName = $('#'+formId+' input, #'+formId+' select').eq(i).attr('name')
var inpVal = $('#'+formId+' input, #'+formId+' select').eq(i).val()
var inpMap = map.set(''+inpName+'',''+inpVal+'');
}
return inpMap;
}
constructor(formId,tableId){
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
var formData = Functions.formData(formId)
var table = $('#'+tableId);
table.prepend('<thead class="bg-light"><tr></tr></thead>')
var th = '';
var formDataKeys = formData.keys();
for(let i=0; i<formData.size; i++){th+='<th>'+capitalizeFirstLetter(formDataKeys.next().value)+'</th>'}
th += '<th>Excluir</th>';
table.find('thead tr').html(th);
table.find('tbody').find('#emptyTr td').attr('colspan',formData.size+1);
}
static addToTable(formId,tableId){
var formData = Functions.formData(formId);
var table = $('#'+tableId);
var formDataKeys = formData.values();
var td = '';
var number = Functions.trNumbers(tableId);
for(let i=0; i<formData.size; i++){td+='<td>'+formDataKeys.next().value+'</td>'}
td += '<td><button onclick=Functions.removeFromTable("'+formId+'","'+tableId+'",'+number+') type="button" class="btn btn-sm btn-danger btn-xs">Excluir</button></td>';
table.find('tbody').find('#emptyTr').remove()
table.find('tbody').append('<tr id="tr_'+number+'">'+td+'</tr>')
number++;
//SEND and RECEIVE DATA here. for add your row data.
//your MAP => formData. your MAP keys => formData.keys() and values => formData.values()
}
static removeFromTable(formId,tableId,rowId){
var formData = Functions.formData(formId)
var table = $('#'+tableId);
var td = '<td colspan='+formData.size+1+'><i>empty</i></td>';
$('#tr_'+rowId).remove()
var trLength = $('tbody tr').length;
if(trLength==0)
{
table.find('tbody').html('<tr id="emptyTr">'+td+'</tr>')
}
//for DELETE your row data, SEND and RECEIVE DATA here.
}
}
new Functions("formulario","myTable"); // "formulario" is your form id and "myTable" is your table id.
Replace the two above and leave the rest of your code unchanged.
It automatically puts the name of the input/select name="" in the table header.
And puts input/select value="" in own column.
It considers the number of your input/select correctly.
Please Look at the comment in the codes.
Your form id is "formulario" , your table id is "myTable".
and i did'nt change it.
For change this ids:
go to last line of function.js and change:
new Functions("your_new_form_id","your_new_table_id");
go to your Salvar button and Excluir button onclick=""
and change ids:
Functions.addToTable('your_new_form_id','your_new_table_id');
Functions.removeFromTable('your_new_form_id','your_new_table_id','your_table_row_number');
Good luck!
my english is not good. sorry :)
found this solution in this solution
function commaSeparateNumber(val){
while (/(\d+)(\d{3})/.test(val.toString())){
val = val.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return val;
}
in this link add commas to a number in jQuery
I am trying to apply it in my project. it works in one column but it doesn't work in price and sub total
function commaSeparateNumber(val){
while (/(\d+)(\d{3})/.test(val.toString())){
val = val.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return val;
}
var rowCount = 1;
$('#add').click(function() {
rowCount++;
$('#orders').append('<tr id="row'+rowCount+'"><td><input class="form-control product_price" type="number" data-type="product_price" id="product_price_'+rowCount+'" name="product_price[]" for="'+rowCount+'"/></td><input class="form-control" type="hidden" data-type="product_id" id="product_id_'+rowCount+'" name="product_id[]" for="'+rowCount+'"/><td><input class="form-control quantity" type="number" class="quantity" id="quantity_'+rowCount+'" name="quantity[]" for="'+rowCount+'"/> </td><td><input class="form-control total_cost" type="text" id="total_cost_'+rowCount+'" name="total_cost[]" for="'+rowCount+'" readonly/> </td><td><button type="button" name="remove" id="'+rowCount+'" class="btn btn-danger btn_remove cicle">-</button></td></tr>');
});
// Add a generic event listener for any change on quantity or price classed inputs
$("#orders").on('input', 'input.quantity,input.product_price', function() {
getTotalCost($(this).attr("for"));
});
$(document).on('click', '.btn_remove', function() {
var button_id = $(this).attr('id');
$('#row'+button_id+'').remove();
});
// Using a new index rather than your global variable i
function getTotalCost(ind) {
var qty = $('#quantity_'+ind).val();
var price = $('#product_price_'+ind).val();
var totNumber = (qty * price);
var tot = totNumber.toFixed(2);
tot = commaSeparateNumber(totNumber);
$('#total_cost_'+ind).val(tot);
calculateSubTotal();
}
function calculateSubTotal() {
var subtotal = 0;
$('.total_cost').each(function() {
subtotal += parseFloat($(this).val());
});
$('#subtotal').val(commaSeparateNumber(subtotal));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-md-12">
<div class="line line-dashed line-lg pull-in"></div>
<div class="row">
<table class="table table-bordered" id="orders">
<tr>
<th>Price</th>
<th>Quantity</th>
<th>Total Cost</th>
<th>
</th>
</tr>
<tr>
<td><input class="form-control product_price" type='number' data-type="product_price" id='product_price_1' name='product_price[]' for="1"/></td> <!-- purchase_cost -->
<td><input class="form-control quantity" type='number' id='quantity_1' name='quantity[]' for="1"/></td>
<td><input class="form-control total_cost" type='text' id='total_cost_1' name='total_cost[]' for='1' readonly/></td>
<td><button type="button" name="add" id="add" class="btn btn-success circle">+</button></td>
</tr>
</table>
<input class="form-control" type='hidden' data-type="product_id_1" id='product_id_1' name='product_id[]'/>
</div>
</div>
<div class="line line-dashed line-lg pull-in" style="clear: both;"></div>
<div class="col-md-12 nopadding">
<div class="col-md-4 col-md-offset-4 pull-right nopadding">
<div class="col-md-8 pull-right nopadding">
<div class="form-group">
<td><input class="form-control subtotal" type='text' id='subtotal' name='subtotal' readonly/></td>
</div>
</div>
<div class="col-md-3 pull-right">
<div class="form-group">
<label>Subtotal</label>
</div>
</div>
</div>
</div>
</body>
</html>
Thank you so much in advance!
The problem is that parseFloat fails to correctly parse the value from the total cost textbox because it contains one or more ,. You need to remove the , from the string before parsing to float. You can remove any ,'s by calling .replace(/,/g,'') on the textbox value in the calculateSubTotal function.
It seems that for some values the function commaSeparateNumber doesn't work as expected. I removed it from the snippet below and replaced it with toLocaleString() which takes parameters for locale and minimum/maximum fraction digits .toLocalString("en-US", { maximumFractionDigits: 2}). Set the locale to one you know uses , to separate thousands. If you know that won't be an issue you can pass undefined for the locale.
Your snippet has been updated below:
var rowCount = 1;
$('#add').click(function() {
rowCount++;
$('#orders').append('<tr id="row'+rowCount+'"><td><input class="form-control product_price" type="number" data-type="product_price" id="product_price_'+rowCount+'" name="product_price[]" for="'+rowCount+'"/></td><input class="form-control" type="hidden" data-type="product_id" id="product_id_'+rowCount+'" name="product_id[]" for="'+rowCount+'"/><td><input class="form-control quantity" type="number" class="quantity" id="quantity_'+rowCount+'" name="quantity[]" for="'+rowCount+'"/> </td><td><input class="form-control total_cost" type="text" id="total_cost_'+rowCount+'" name="total_cost[]" for="'+rowCount+'" readonly/> </td><td><button type="button" name="remove" id="'+rowCount+'" class="btn btn-danger btn_remove cicle">-</button></td></tr>');
});
// Add a generic event listener for any change on quantity or price classed inputs
$("#orders").on('input', 'input.quantity,input.product_price', function() {
getTotalCost($(this).attr("for"));
});
$(document).on('click', '.btn_remove', function() {
var button_id = $(this).attr('id');
$('#row'+button_id+'').remove();
});
// Using a new index rather than your global variable i
function getTotalCost(ind) {
var qty = $('#quantity_'+ind).val();
var price = $('#product_price_'+ind).val();
var totNumber = (qty * price);
// .toLocaleString
var tot = totNumber.toLocaleString("en-US", { maximumFractionDigits: 2});
$('#total_cost_'+ind).val(tot);
calculateSubTotal();
}
function calculateSubTotal() {
var subtotal = 0;
$('.total_cost').each(function() {
// replace ',' here
subtotal += parseFloat($(this).val().replace(/,/g,''));
});
// toLocaleString
$('#subtotal').val(subtotal.toLocaleString("en-US", { maximumFractionDigits: 2}));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<div class="col-md-12">
<div class="line line-dashed line-lg pull-in"></div>
<div class="row">
<table class="table table-bordered" id="orders">
<tr>
<th>Price</th>
<th>Quantity</th>
<th>Total Cost</th>
<th>
</th>
</tr>
<tr>
<td><input class="form-control product_price" type='number' data-type="product_price" id='product_price_1' name='product_price[]' for="1"/></td> <!-- purchase_cost -->
<td><input class="form-control quantity" type='number' id='quantity_1' name='quantity[]' for="1"/></td>
<td><input class="form-control total_cost" type='text' id='total_cost_1' name='total_cost[]' for='1' readonly/></td>
<td><button type="button" name="add" id="add" class="btn btn-success circle">+</button></td>
</tr>
</table>
<input class="form-control" type='hidden' data-type="product_id_1" id='product_id_1' name='product_id[]'/>
</div>
</div>
<div class="line line-dashed line-lg pull-in" style="clear: both;"></div>
<div class="col-md-12 nopadding">
<div class="col-md-4 col-md-offset-4 pull-right nopadding">
<div class="col-md-8 pull-right nopadding">
<div class="form-group">
<td><input class="form-control subtotal" type='text' id='subtotal' name='subtotal' readonly/></td>
</div>
</div>
<div class="col-md-3 pull-right">
<div class="form-group">
<label>Subtotal</label>
</div>
</div>
</div>
</div>
</body>
</html>
When pressing the button, i get this error message in the console:
Uncaught TypeError: Cannot read property 'reset' of undefined
I thought, that the form ID is missing, but it is there, and its correct.
The javascript files, and all the javascipt is called at the page end, before the body closing tag, not in the head section.
My source code:
<form id="AllapotForm" class="form-horizontal" method="post">
<table id="products" class="table table-hover">
<thead>
<tr class="tr_bold">
<!--width="33.3%"-->
<td class="left" >Létrehozva</td>
<td class="left" >Állapot</td>
<td class="left" >A megrendelő értesítve email-ben</td>
<td class="left" >Megjegyzés</td>
</tr>
</thead>
<tbody id="allapotok">
<tr>
<td class="left">2018-03-18 20:16</td>
<td class="left">Feldolgozás alatt</td>
<td class="left">Nem</td>
<td class="left">Teszt állapot.</td>
</tr> </tbody>
</table>
<img src="https://domain.hu/images/assets/preloader.gif" id="preloaderImage2" class="img-responsive" style="margin:10px auto;">
<div class="form-group row">
<label class="control-label col-md-2">Állapot:</label>
<div class="col-md-2">
<select name="allapot" id="allapot" class="input input-select form-control">
<option value="3">Feldolgozva</option><option value="2">Feldolgozás alatt</option><option value="1">Függőben lévő</option><option value="4">Kiküldve</option><option value="5">Postázva</option><option value="7">Sikertelen</option><option selected="selected" value="9">Stornó</option><option value="6">Teljesítve</option><option value="10">Törölt</option><option value="8">Visszafizetve</option><option value="0">Új megrendelés</option> </select>
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-2">Megrendelő értesítése email-ben:</label>
<div class="col-md-2">
<input type="checkbox" name="notify" id="notify" class="form-control" />
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-2">Megjegyzés hozzáadása az email-hez:<span class="help">Amennyiben ezt bepipálja, a megjegyzés az ügyfélnek kiküldött üzenetbe is bele fog kerülni.</span></label>
<div class="col-md-2">
<input type="checkbox" name="add_text" id="add_text" class="form-control" />
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-2">Megjegyzés:</label>
<div class="col-md-4">
<textarea name="comment" id="comment" rows="8" class="form-control" style="width: 99%"></textarea>
<div style="margin-top: 10px; text-align: center;">
<a class="saveButton btn btn-primary" style="color:#fff" onclick="allapot_modosit();" id="history_button">Állapot módosítása</a>
</div>
</div>
</div>
</form>
function allapot_modosit()
{
var html;
var RendelesID = 8;
var RendelesUserEmail = "email#test.hu";
var RendelesUserName = "name";
var webshopEmail = "teszt#teszt.hu";
var webshopName = "Teszt Webáruház";
var Allapot = $( "#allapot option:selected" ).val();
var Comment = $('#comment').val();
if($("#notify").is(':checked')){var Notify = 1;}else{var Notify = 0;}
if($("#add_text").is(':checked')){var AddToEmail = 1;}else{var AddToEmail = 0;}
$.ajax({
type: 'POST',
cache: false,
url: 'files/update_rendeles_allapot.php',
dataType: 'json',
data: { RendelesID:RendelesID, Allapot:Allapot, Notify:Notify, AddToEmail:AddToEmail, Comment:Comment, RendelesUserEmail:RendelesUserEmail, RendelesUserName:RendelesUserName, webshopEmail:webshopEmail, webshopName:webshopName },
beforeSend: function(){
$('#preloaderImage2').show();
},
success: function(data)
{
html += ' <tr>';
html += ' <td class="left">' + data.allapot_datetime + '</td>';
html += ' <td class="left">' + data.allapot_name + '</td>';
html += ' <td class="left">' + data.ertesites + '</td>';
html += ' <td class="left">' + data.comment + '</td>';
html += ' </tr>';
$('#allapotok').append(html);
},
complete: function(){
$('#preloaderImage2').hide();
$('#AllapotForm')[0].reset();
}
});
}
On this line:
$('#AllapotForm')[0].reset();
Try removing the [0]. If you're querying an id, I don't think it returns a collection.
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);
}
/*creates phoens dynamically*/
var phoneList = [];
function add_phone() {
var index = phoneList.length+1;
phoneList.push('phone: '+index);
var divtest = '<div class="form-group removeclass'+index+'">'+
'<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone ( '+index+' )</span>'+
'<div class="col-sm-3 nopadding">'+
'<div class="form-group">'+
' <input type="text" class="form-control" name="a[]" value="" placeholder="Type"></div></div>'+
'<div class="col-sm-3 nopadding"><div class="form-group">'+
'<input type="text" class="form-control" name="b[]" value="" placeholder="Model"></div>'+
'</div><div class="col-sm-3 nopadding">'+
'<div class="form-group"> <input type="text" class="form-control" name="c[]" value="" placeholder="Color">'+
'</div></div><div class="col-sm-3 nopadding"><div class="form-group"><div class="input-group"> '+
'<select class="form-control" name="d[]">'+
'<option value="">Year</option><option value="2015">2015</option><option value="2016">2016</option>'+
'<option value="2017">2017</option><option value="2018">2018</option> </select><div class="input-group-btn"> '+
'<button class="btn btn-danger" type="button" onclick="remove_phone('+ index +');"> <span '+
'class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button></div></div></div></div><div '+
'class="clear"></div>';
$('#education_fields').append(divtest);
updatePhonePicker();
}
function remove_phone(rid) {
$("#phone_picker option[value='"+rid+"']").remove();
$('.removeclass'+rid).remove();
phoneList.splice(phoneList.indexOf(rid),1);
updatePhonePicker();
}
function updatePhonePicker(){
var options = '<option selected disabled>---</option>';
phoneList.forEach(function(element, index){
options+='<option value="'+element+'">'+element+'</option>'
})
$('#tab_logic').find('tr').each(function(ind,ele){
var r = $(ele).find("#phone_picker").empty().append(options);
});
}
/*Add details about phone added here*/
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><select class='form-control' title='Phone' id='phone_picker'><option selected disabled>---</option></select> </td><td><input name='mail"+i+"' type='text' placeholder='field 1' class='form-control input-md'></td><td><input name='mobile"+i+"' type='text' placeholder='field 2' class='form-control input-md'></td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"></tr>');
i++;
updatePhonePicker();
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Add Phone-->
<div class="panel panel-default">
<div class="panel-heading">Phone Information</div>
<div class="panel-body">
<div id="education_fields">
</div>
<div class="input-group">
<div class="input-group-btn">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Add Phone.</span>
<button class="btn btn-success" type="button" onclick="add_phone();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
<!--Individual phone information-->
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone selected additional details.</span>
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
#
</th>
<th class="text-center">
Phone
</th>
<th class="text-center">
Type
</th>
<th class="text-center">
Carrier
</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
1
</td>
<td>
<select class="form-control" title="Phone" id="phone_picker">
<option selected disabled>---</option>
</select>
</td>
<td>
<input type="text" placeholder='field 1' class="form-control"/>
</td>
<td>
<input type="text" placeholder='field 2' class="form-control"/>
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<a id="add_row" class="btn btn-default pull-left">Add Phone</a><a id='delete_row' class="pull-right btn btn-default">Delete Phone</a>
</div>
When clicking on 'Add Phone', I get the option to add as many phones as needed. Phone count (How many phones created) get added on the 'Phone selected additional details' select option when adding or removing a new phone.
My issue is that when I create 3 phone sections then remove phone #1 and add another phone again it give me the same phone counter (example added 1,2,3 removed 1 added another one get 1 and 1 again and it should be like that, it should be a unit counter(phone) everytime).
To be more specific steps go as follow:
click on 'add phone' one time and a 2nd time and a 3rd time.
click on the red button where it's title 'Phone(1)'.
check if the number of phone present match what is on the 'Phone' select/dropdown.
You will see that the number of phone display doesn't match what on select.
Your issue is in this line:
var index = phoneList.length+1;
Because you create new div with a class like removeclass1, removeclass2..... you can consider to get directly the last div and so extract the number instead to increment by one:
var index = 1;
if ($('#education_fields > div').length > 0) {
index = 1 + +$('#education_fields > div:last').attr('class').match(/.*removeclass(\d+).*/)[1];
}
From your comment:
Ok this is good but if you look down the table column 'Phone' and the select/dropdown, it seems not be getting updated when deleting 'phone'/section
You can change updatePhonePicker in order to build dynamically the options getting the data directly from the divs:
From:
phoneList.forEach(function(element, index){
options+='<option value="'+element+'">'+element+'</option>'
})
to:
$('#education_fields > div > span').each(function(idx, ele) {
var txt = ele.textContent.replace(/[()]/g, '').trim();
options+='<option value="'+txt+'">'+txt+'</option>'
})
var phoneList = [];
function add_phone() {
var index = 1;
if ($('#education_fields > div').length > 0) {
index = 1 + +$('#education_fields > div:last').attr('class').match(/.*removeclass(\d+).*/)[1];
}
phoneList.push('phone: '+index);
var divtest = '<div class="form-group removeclass'+index+'">'+
'<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone ( '+index+' )</span>'+
'<div class="col-sm-3 nopadding">'+
'<div class="form-group">'+
' <input type="text" class="form-control" name="a[]" value="" placeholder="Type"></div></div>'+
'<div class="col-sm-3 nopadding"><div class="form-group">'+
'<input type="text" class="form-control" name="b[]" value="" placeholder="Model"></div>'+
'</div><div class="col-sm-3 nopadding">'+
'<div class="form-group"> <input type="text" class="form-control" name="c[]" value="" placeholder="Color">'+
'</div></div><div class="col-sm-3 nopadding"><div class="form-group"><div class="input-group"> '+
'<select class="form-control" name="d[]">'+
'<option value="">Year</option><option value="2015">2015</option><option value="2016">2016</option>'+
'<option value="2017">2017</option><option value="2018">2018</option> </select><div class="input-group-btn"> '+
'<button class="btn btn-danger" type="button" onclick="remove_phone('+ index +');"> <span '+
'class="glyphicon glyphicon-minus" aria-hidden="true"></span> </button></div></div></div></div><div '+
'class="clear"></div>';
$('#education_fields').append(divtest);
updatePhonePicker();
}
function remove_phone(rid) {
$("#phone_picker option[value='"+rid+"']").remove();
$('.removeclass'+rid).remove();
phoneList.splice(phoneList.indexOf(rid),1);
updatePhonePicker();
}
function updatePhonePicker(){
var options = '<option selected disabled>---</option>';
$('#education_fields > div > span').each(function(idx, ele) {
var txt = ele.textContent.replace(/[()]/g, '').trim();
options+='<option value="'+txt+'">'+txt+'</option>'
})
$('#tab_logic').find('tr').each(function(ind,ele){
var r = $(ele).find("#phone_picker").empty().append(options);
});
}
/*Add details about phone added here*/
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"</td><td><select class='form-control' title='Phone' id='phone_picker'><option selected disabled>---</option></select> </td><td><input name='mail"+i+"' type='text' placeholder='field 1' class='form-control input-md'></td><td><input name='mobile"+i+"' type='text' placeholder='field 2' class='form-control input-md'></td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"></tr>');
i++;
updatePhonePicker();
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!--Add Phone-->
<div class="panel panel-default">
<div class="panel-heading">Phone Information</div>
<div class="panel-body">
<div id="education_fields">
</div>
<div class="input-group">
<div class="input-group-btn">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Add Phone.</span>
<button class="btn btn-success" type="button" onclick="add_phone();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
<!--Individual phone information-->
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<span class="help-block" style="font-weight: 400; font-size: 14px;">Phone selected additional details.</span>
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
#
</th>
<th class="text-center">
Phone
</th>
<th class="text-center">
Type
</th>
<th class="text-center">
Carrier
</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>
1
</td>
<td>
<select class="form-control" title="Phone" id="phone_picker">
<option selected disabled>---</option>
</select>
</td>
<td>
<input type="text" placeholder='field 1' class="form-control"/>
</td>
<td>
<input type="text" placeholder='field 2' class="form-control"/>
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
<a id="add_row" class="btn btn-default pull-left">Add Phone</a><a id='delete_row' class="pull-right btn btn-default">Delete Phone</a>
</div>
I think your problem is in the first line of add_phone
var index = phoneList.length+1;
I would remove the "+1", because if you add your first item it get's the html class removeclass1, but has the index 0 in the phoneList array. To remove this phone you call removePhone(1), but actually its index is 0, so you remove no phone or rather a wrong phone.
You simply have to write another function like the updatePhonePicker() where you gonna update the numbers displayed inside the <span>
Here is the function:
1-First surround the counter display in a span and give it a class (counterClass): ....Phone <span class="counterClass">( '+index+' )</span>
2- Each row give it a class (.someClass)
function updatePhoneNumbers(){
var counter = i;
$('someClass').forEach(function(element, index){
var number = i-counter+1;
$(element).find('.counterClass').html(counter);
counter--;
})
}