i have been watching some questions here about the same topic but i cant make my code works with the solutions,
I have a dynamic tr table, what i want to do is when i write on the last input of each row a div "result" overwrite like the values, that because i want to make later a connection that shows me users name on my db, like a data live search
JS
function createTable() {
var a;
var r;
a = document.getElementById('tb1').value;
var length = document.getElementById('table').rows.length;
if (a == "") {
alert("Please enter some numeric value");
} else {
var change = document.getElementById("trow1").style.visibility = 'visible';
//var change = document.getElementById("trow2").style.visibility = 'visible';
var changet = document.getElementById("table").style.visibility = 'visible';
var rows = "";
for (var i = 0; i < a; i++) {
r=i+length;
let tr = document.createElement("tr");
tr.innerHTML = "<td>"+r+"</td><td><input type='text' id='" + "parameter".concat(r) + "'></td><td id='tdlmin'><input type='text' id='" + "lmin".concat(r) + "'></td><td id='tdlmax'><input type='text' id='" + "lmax".concat(r) + "'></td><td><input type='text' id='" + "level".concat(r) + "'></td><td><select id='" + "relcal".concat(r) + "' style='width:100%;'><option value='NA'>NA</option><option value='SI'>SI</option></select></td><td><input type='text' id='" + "comment".concat(r) + "' cols=100></td><td><input type='text' id='" + "procown".concat(r) + "' onkeyUp='document.getElementById('result').innerHTML = this.value;'></div></td>";
document.getElementById("table").appendChild(tr);
}
}
}
HTML
<div class="container-fluid">
<div class="row align-items-start">
<div class="col-9">
Numero de Parametros: <input type="text" id="tb1"/>
<button type="button" onclick='createTable()'>Crear</button>
<table id="table" class="order-table table" name="table1" required style="visibility:hidden;">
<tr id="trow1" style="visibility:hidden; text-align: center;"><td>#</td><td>Parametro</td><td colspan="2"><table><tr><td colspan="2">Limite</td></tr><tr><td>Min.</td><td>Max.</td></tr></table></td><td><table style="width: 100%;"><tr><td>Nivel</td></tr><tr><td>1 - 4</td></tr></table></td><td>Relevante Calidad</td><td>Comentario</td><td>Dueño del Proceso</td></tr>
</table>
<button type="button" onclick='subir()'>Subir Parametros</button>
</div>
<div class="col-3">
<div id="result" name="result"></div>
</div>
</div>
</div>
Edit:
This is what i have tried yet:
$('"'+procownid+'"').on("keyup",function(){
var userlike = document.getElementById(procownid).value;
alert(userlike);
});
$("#table tr").on('keyup', procownid, function({
var userlike = document.getElementById(procownid).value;
alert(userlike);
result.innerHTML="<p>"+userlike+"</p>"
});
alert(userlike);
document.getElementById('result').innerHTML="<p>userlike:"+uselike+"</p>";
$.post('getUser',{accion:"ListarUserTPMD",userlike:userlike}, function(data){
result.innerHTML=data;
});
my question is, i can get that when i write on the input it trigger the onkeyup and show me for example the input.value, why i cant make it write on the div?
Related
As part of a web app I'm building in Google Apps Script, I'm trying to create a checkbox field that shows one checkbox for each learner/student, arranged in rows of 3. The learner data is being taken from a spreadsheet (this bit is working fine).
I want the checkboxes to look like this:
image of 6 checkboxes, in 2 rows of 3
The problem I am having is that my code is inserting the closing fieldset tag in the wrong place (too early) and so the checkboxes don't look right (I'm using the jquery mobile 1.4.5 framework).
I've been staring at the code and tinkering with it for hours, I'm hoping it's something simple I just can't see and hoping someone can help me fix it.
The code I am using is basically a nested loop - the outer loop should create the fieldset tags for each row, and the inner loop should create each checkbox. My code is as follows:
First the container div
<div id="learners">Loading...</div>
The javascript to grab the data and replace the container div above with it...
// The code in this function runs when the page is loaded.
$(function() {
google.script.run.withSuccessHandler(showLearners)
.getLearnerData();
});
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
for (var i = 0; i < learners.length; i++) {
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\">");
for (var j = 0; j < 3; j++) {
learnerCheckboxes.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"<label for=\"learner" + i + "\">" + learners[i][0] + "</label>" +
"</div>"
);
i++
}
learnerCheckboxes.append("</fieldset>");
}
}
The problem is, when the code runs, the closing </fieldset> is inserted too early... here's the output from this code:
<div id="learners">
<fieldset class="ui-grid-b">
</fieldset><!-- THIS IS THE PROBLEM - IT SHOULD BE AT THE BOTTOM OF THIS GROUP?-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner0" data-mini="true">
<label for="learner0">David</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner1" data-mini="true">
<label for="learner1">Dominic</label>
</div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner2" data-mini="true">
<label for="learner2">Eliza</label>
</div>
<fieldset class="ui-grid-b">
</fieldset><!-- THIS SHOULD BE AT THE BOTTOM OF THIS GROUP-->
<div class="ui-block-a">
<input type="checkbox" name="learner" id="learner4" data-mini="true">
<label for="learner4">Francois</label>
</div>
<div class="ui-block-b">
<input type="checkbox" name="learner" id="learner5" data-mini="true">
<label for="learner5">James</label></div>
<div class="ui-block-c">
<input type="checkbox" name="learner" id="learner6" data-mini="true">
<label for="learner6">Louise</label>
</div>
</div>
It took a lot of trial and error because I don't use jquery. I do it the old fashion way. But I finally got it to work. You can play with the CSS to get it to look like you want.
HTML_Test.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div id="learners">Loading...</div>
<script>
(function() {
google.script.run.withSuccessHandler(showLearners).getLearnerData();
})();
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
let i = 0;
while( i < learners.length ) {
let id = "fieldset"+i;
let fieldset = $('<fieldset class="ui-grid-b" id="'+id+'"></fieldset>')
learnerCheckboxes.append(fieldset);
for (var j = 0; j < 3; j++) {
let div = $('<div class="ui-block-' + cols[j] + '"></div>')
fieldset.append(div);
id = "learner"+i;
let input = $('<input type="checkbox" name="learner" id="' + id + '" data-mini="true">');
let label = $('<label for="' + id + '">' + learners[i][0] + '</label>' );
div.append(input);
div.append(label);
i++;
if( i === learners.length ) break;
}
}
}
</script>
</body>
</html>
Code.gs
function getLearnerData() {
try {
Logger.log("In getLearnerData");
return [["Dave"],["Tom"],["Larry"],["Mary"],["Joe"],["Sam"],["John"]];
}
catch(err) {
Logger.log("Error in getLearnerData: "+err);
}
}
Results
Thanks TheWizEd for the idea to dynamically name the fieldset tags - this is what lead to the solution. By dynamically creating the fieldset ID, I can use the inner loop to append the checkboxes BETWEEN the fieldset tags. Here's the code:
function showLearners(learners) {
var learnerCheckboxes = $('#learners');
learnerCheckboxes.empty();
var cols=['a','b','c'];
var rowCount = 1;
for (var i = 0; i < learners.length; i++) {
//in this next line, use rowCount to create a unique fieldset id
learnerCheckboxes.append("<fieldset class=\"ui-grid-b\" id=\"checkRow" + rowCount + "\"></fieldset>");
//then grab it
var checkRow = $("#checkRow" + rowCount)
for (var j = 0; j < cols.length; j++) {
//and append the checkboxes to the newly created fieldset
checkRow.append(
"<div class=\"ui-block-" + cols[j] + "\">" +
"<div class=\"ui-checkbox ui-mini\">" +
"<label for=\"learner" + i + "\" class=\"ui-btn ui-corner-all ui-btn-inherit ui-btn-icon-left ui-checkbox-off\">" +
learners[i][0] + "</label>" +
"<input type=\"checkbox\" name=\"learner\" id=\"learner" + i + "\" data-mini=\"true\">" +
"</div>" +
"</div>"
);
i++;//we're in the inner loop, so have to manually increment i
}
rowCount++;
}
}
I am struggling to get this working and would like to know if i'm headed in the right direction with what i have.
Whats supposed to be happening is two input fields that get added to a on a click event. This part is done and its working fine.
Whats supposed to happen after the input fields get added to the table is you can then delete a tr with a button that gets added when the tr is created. Which is not working. I also cant figure out why the page refreshes when you click the delete button to delete a tr, preventDefault() is being used.
let data = [];
let speciesInput = document.querySelector('#speciesInput')
let breedInput = document.querySelector('#breedInput')
let messageBox = document.getElementById("display");
const addProductBtn = document.querySelector('#addValue')
let deleteProductBtn = document.getElementsByClassName('deleteProduct')
const deleteBtnArray = Array.from(deleteProductBtn)
addProductBtn.addEventListener('click', function (e) {
e.preventDefault();
let species, breed;
species = speciesInput.value;
breed = breedInput.value;
data.push({
species: species,
breed: breed,
});
clearAndShow();
})
function clearAndShow() {
// Clear our fields
speciesInput.value = "";
breedInput.value = "";
messageBox.innerHTML = computeHTML();
}
function computeHTML() {
let html = "<table>";
data.forEach(function (item) {
html += "<tr>";
html += "<td>" + item.species + ' ' + "</td>"
html += "<td>" + item.breed + "</td>"
html += "<td>" + "<button class='deleteProduct' onclick='deleteProduct()'> − </button>" + "</td>"
html += "</tr>"
console.log(deleteBtnArray)
});
html += "</table>"
return html;
}
function deleteProduct() {
console.log(deleteBtnArray)
deleteBtnArray.forEach((btn) => {
btn.addEventListener('click', function (e) {
e.preventDefault();
console.log('Delete item')
deleteItem() // Not made yet
})
})
}
deleteProduct()
document.querySelector('#productForm').addEventListener('submit', function (e) {
e.preventDefault();
})
<!-- Add Product -->
<div class="">
<div class="d-flex flex-column justify-content-center align-content-center">
<div class="intro-wrapper">
<h1 class="welcome-heading">Welcome <span class="brand-heading"></span><span class="brand-heading brand-heading-grey"></span></h1>
<span class="intro-description">Set up your profile to begin interacting with the community.</span>
</div>
<span class="secondary-txt mt-5 mb-2">Add Your Product For Display</span>
<form id="productForm" class="form d-flex flex-column align-items-center mt-2" action="">
<div class="product-field-outter">
<div class="form-field product-field-inner d-flex flex-column align-items-center">
<div style="width: 100%!important;" class="form-field my-auto">
<label for="species"></label>
<input id="speciesInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Species">
</div>
<div style="width: 100%!important;" class="form-field my-auto">
<label for="breed"></label>
<input id="breedInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Breed">
</div>
<small></small>
<button id="addValue" class="add-product-btn btn-active mt-4 ms-2">+</button>
</div>
</div>
<div id="display" class="output d-flex flex-column justify-content-center mt-5"></div>
<!-- <ul id="list" class="productList justify-content-between"></ul> -->
<button class="primary-btn continue-btn btn-active mt-4">Continue</button>
</form>
<button class="back-btn btn-active me-auto mt-4">Back</button>
</div>
</div>
</div>
<!-- Add Product -->
<div class="">
<div class="d-flex flex-column justify-content-center align-content-center">
<div class="intro-wrapper">
<h1 class="welcome-heading">Welcome<span class="brand-heading"></span><span class="brand-heading brand-heading-grey"></span></h1>
<span class="intro-description">Set up your profile to begin interacting with the community.</span>
</div>
<span class="secondary-txt mt-5 mb-2">Add Your Product For Display</span>
<form class="form d-flex flex-column align-items-center mt-2" action="">
<div class="product-field-outter">
<div class="form-field product-field-inner d-flex flex-column align-items-center">
<div style="width: 100%!important;" class="form-field my-auto">
<label for="species"></label>
<input id="speciesInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Species">
</div>
<div style="width: 100%!important;" class="form-field my-auto">
<label for="breed"></label>
<input id="breedInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Breed">
</div>
<small></small>
<button id="addValue" class="add-product-btn btn-active mt-4 ms-2">+</button>
</div>
</div>
<div id="display" class="output d-flex flex-column justify-content-center mt-5"></div>
<!-- <ul id="list" class="productList justify-content-between"></ul> -->
<button class="primary-btn continue-btn btn-active mt-4">Continue</button>
</form>
<button class="back-btn btn-active me-auto mt-4">Back</button>
</div>
</div>
</div>
Javascript
let data = [];
let speciesInput = document.querySelector('#speciesInput')
let breedInput = document.querySelector('#breedInput')
let messageBox = document.getElementById("display");
const addProductBtn = document.querySelector('#addValue')
let deleteProductBtn = document.getElementsByClassName('deleteProduct')
const deleteBtnArray = Array.from(deleteProductBtn)
addProductBtn.addEventListener('click', function (e) {
e.preventDefault();
let species, breed;
species = speciesInput.value;
breed = breedInput.value;
data.push({
species: species,
breed: breed,
});
clearAndShow();
})
function clearAndShow() {
// Clear our fields
speciesInput.value = "";
breedInput.value = "";
messageBox.innerHTML = computeHTML();
}
function computeHTML() {
let html = "<table>";
data.forEach(function (item) {
html += "<tr>";
html += "<td>" + item.species + ' ' + "</td>"
html += "<td>" + item.breed + "</td>"
html += "<td>" + "<button class='deleteProduct' onclick='deleteProduct()'> − </button>" + "</td>"
html += "</tr>"
console.log(deleteBtnArray)
});
html += "</table>"
return html;
}
function deleteProduct() {
console.log(deleteBtnArray)
deleteBtnArray.forEach((btn) => {
btn.addEventListener('click', function (e) {
e.preventDefault();
console.log('Delete item')
deleteItem() // Not made yet
})
})
}
deleteProduct()
There is more than one thing happening
The variables on top of your JS code are recovering elements from the document object only when the page loads. You are not updating them (I.E. the deleteBtnArray) after appending the html on clearAndShow() function. That's why the deleteBtnArray is always empty when you click the - buttons.
One way to avoid this is collectiong the elements inside the deleteProduct function. Also, you don't need to convert into array using Array.from because document.getElementsByClassName(...) already returns an iterable collection. Also, using "for of" is a little better readable than forEach with callbacks.
You are adding the deleteProduct(...) function more than once using this method, because you are calling using the onclick='deleteProduct()' and also btn.addEventListener('click'...). And after that you also call the deleteProduct function right after its declaration. No need for that.
If you want to remove the whole <tr>, there is a easy way of doing that referencing each <tr> with an id and using it as argument for the deleteProduct function, just like in the example below
Replace your whole javascript by this, and use the same HTML
let data = [];
var speciesInput = document.querySelector('#speciesInput')
var breedInput = document.querySelector('#breedInput')
var messageBox = document.getElementById("display");
var addProductBtn = document.querySelector('#addValue')
addProductBtn.addEventListener('click', function (e) {
e.preventDefault();
let species, breed;
species = speciesInput.value;
breed = breedInput.value;
data.push({
species: species,
breed: breed,
});
clearAndShow();
})
function clearAndShow() {
// Clear our fields
speciesInput.value = "";
breedInput.value = "";
messageBox.innerHTML = computeHTML();
}
function computeHTML() {
let html = "<table>";
data.forEach(function (item, index) {
html += "<tr id='line-" + index + "'>";
html += "<td>" + item.species + ' ' + "</td>"
html += "<td>" + item.breed + "</td>"
html += "<td>" + "<button onclick='deleteProduct(" + index + ")'> − </button>" + "</td>"
html += "</tr>"
});
html += "</table>"
return html;
}
function deleteProduct(removedIndex) {
document.getElementById("line-" + removedIndex).remove()
data = data.filter(function (item, index) { return index != removedIndex })
}
document.querySelector('#productForm').addEventListener('submit', function (e) {
e.preventDefault();
})
Bonus:
I recommend you to use ` instead of " or ' when writing html inside strings, because
You can insert variables using ${variableName}
You can break lines
You can use ' and " freely inside strings delimited by `
You don't need to use a lot of +=
I also recommend you to use .map( instead of .forEach(. Things get cleaner this way.
Replace the computeHTML() I've shown before with this piece of code:
function itemHtml(item, index) {
return `<tr id="line-${index}">
<td>${item.species}</td>
<td>${item.breed}</td>
<td><button onclick="deleteProduct(${index})"> − </button></td>
</tr>`
}
function computeHTML() {
return `<table>${data.map(itemHtml)}</table>`
}
I'm trying to create a list of products added from a select in a form using jQuery.
After the addition of those products, I would like to send them with the rest of the form.
The question is when I delete a product, I would also like to remove the hidden input created before.
Could you someone please give me a hand.
Thanks!!
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="form-receta" id="form-receta">
<label for="nombre_receta">Nombre :</label><input id="nombre_receta" name="name_receta" type="text">
<label for="nombre_ingr">Ingredientes:</label><br />
<select style="width:7.7em;display: inline-block;" id="nombre_ingr" name="nombre_ingr">
<option></option>
<option value="1*Prueba">Prueba</option>
<option value="2*Test">Test</option>
</select>
<input id="cantidad_ingr" name="cantidad_ingr" placeholder="cantidad" type="text">
<input id="um_ingr" name="um_ingr" placeholder="U.M" type="text">
<button type="button" class="add-row">ADD</button>
<h3>Ingredientes</h3>
<table>
<tr >
<th>#</th>
<th></th>
<th>Cantidad</th>
<th>U.M</th>
<th>Eliminar</th>
</tr>
<tbody id="tabla-ingr"></tbody>
</table>
<script>
$(document).ready(function(){
var x = 0;
$(".add-row").click(function(){
var id_nombre = $("#nombre_ingr").val();
var res = id_nombre.split("*");
var nombre = res[1];
var id = res[0];
var cantidad = $("#cantidad_ingr").val();
var um = $("#um_ingr").val();
x = x + 1;
var markup = "<tr><td>" + x + "</td><td>" + nombre + "</td><td class=\"text-center\">" + cantidad +
"</td><td class=\"text-center\">" + um + "</td><td class=\"text-center\"><button type=\"button\" class=\"btn btn-xs btn-danger removebutton\"><span class=\"glyphicon glyphicon-remove\"></span>DEL</button></tr>";
$("tbody#tabla-ingr").append(markup);
$('#form-receta').prepend('<input type="hidden" name="_id_ingr[]" value="'+ id +'" />');
$('#form-receta').prepend('<input type="hidden" name="_cantidad_ingr[]" value="'+ cantidad +'" />');
$('#form-receta').prepend('<input type="hidden" name="_um_ingr[]" value="'+ um +'" />');
});
$(document).on('click', 'button.removebutton', function () {
$(this).closest('tr').remove();
return false;
});
});
</script>
Thanks!
You can set an id to those input hidden elements. Then, when you delete the row, you can look for the id of that specific row and delete only the input hidden related to that row.
I hope it makes sense!
$(document).ready(function(){
var x = 0;
$(".add-row").click(function(){
var id_nombre = $("#nombre_ingr").val();
var res = id_nombre.split("*");
var nombre = res[1];
var id = res[0];
var cantidad = $("#cantidad_ingr").val();
var um = $("#um_ingr").val();
x = x + 1;
var markup = "<tr><td>" + x + "</td><td>" + nombre + "</td><td class=\"text-center\">" + cantidad +
"</td><td class=\"text-center\">" + um + "</td><td class=\"text-center\"><button type=\"button\" class=\"btn btn-xs btn-danger removebutton\"><span class=\"glyphicon glyphicon-remove\"></span>DEL</button></tr>";
$("tbody#tabla-ingr").append(markup);
$('#form-receta').prepend('<input type="hidden" name="_id_ingr[]" id="_id_ingr_'+x+'" value="'+ id +'" />');
$('#form-receta').prepend('<input type="hidden" name="_cantidad_ingr[]" id="_cantidad_ingr_'+x+'" value="'+ cantidad +'" />');
$('#form-receta').prepend('<input type="hidden" name="_um_ingr[]" id="_um_ingr_'+x+'" value="'+ um +'" />');
});
$(document).on('click', 'button.removebutton', function () {
var ingrediente_row = $(this).closest('tr');
var ingrediente_id = $(ingrediente_row).children('td')[0].innerHTML;
$('#_id_ingr_' + ingrediente_id).remove();
$('#_cantidad_ingr_' + ingrediente_id).remove();
$('#_um_ingr_' + ingrediente_id).remove();
$(ingrediente_row).remove();
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="form-receta" id="form-receta">
<label for="nombre_receta">Nombre :</label><input id="nombre_receta" name="name_receta" type="text">
<label for="nombre_ingr">Ingredientes:</label><br />
<select style="width:7.7em;display: inline-block;" id="nombre_ingr" name="nombre_ingr">
<option></option>
<option value="1*Prueba">Prueba</option>
<option value="2*Test">Test</option>
</select>
<input id="cantidad_ingr" name="cantidad_ingr" placeholder="cantidad" type="text">
<input id="um_ingr" name="um_ingr" placeholder="U.M" type="text">
<button type="button" class="add-row">ADD</button>
</form>
<h3>Ingredientes</h3>
<table>
<tr >
<th>#</th>
<th></th>
<th>Cantidad</th>
<th>U.M</th>
<th>Eliminar</th>
</tr>
<tbody id="tabla-ingr"></tbody>
</table>
Simply add a specific class for each hidden field and and pass this no to delete button :
$(document).ready(function(){
var x=0;
$(".add-row").click(function(){
var id_nombre = $("#nombre_ingr").val();
var res = id_nombre.split("*");
var nombre = res[1];
var id = res[0];
var cantidad = $("#cantidad_ingr").val();
var um = $("#um_ingr").val();
x = x + 1;
var markup = "<tr><td>" + x + "</td><td>" + nombre + "</td><td class=\"text-center\">" + cantidad +
"</td><td class=\"text-center\">" + um + "</td><td class=\"text-center\"><button type=\"button\" class=\"btn btn-xs btn-danger removebutton\" data-id='"+x+"'><span class=\"glyphicon glyphicon-remove\"></span>DEL</button></tr>";
$("tbody#tabla-ingr").append(markup);
$('#form-receta').prepend('<input type="hidden" name="_id_ingr[]" class="_hidden_'+x+'" value="'+ id +'" />');
$('#form-receta').prepend('<input type="hidden" name="_cantidad_ingr[]" class="_hidden_'+x+'" value="'+ cantidad +'" />');
$('#form-receta').prepend('<input type="hidden" name="_um_ingr[]" class="_hidden_'+x+'" value="'+ um +'" />');
});
$(document).on('click', 'button.removebutton', function () {
$('._hidden_'+$(this).data('id')).remove();
$(this).closest('tr').remove();
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="form-receta" id="form-receta">
<label for="nombre_receta">Nombre :</label><input id="nombre_receta" name="name_receta" type="text">
<label for="nombre_ingr">Ingredientes:</label><br />
<select style="width:7.7em;display: inline-block;" id="nombre_ingr" name="nombre_ingr">
<option></option>
<option value="1*Prueba">Prueba</option>
<option value="2*Test">Test</option>
</select>
<input id="cantidad_ingr" name="cantidad_ingr" placeholder="cantidad" type="text">
<input id="um_ingr" name="um_ingr" placeholder="U.M" type="text">
<button type="button" class="add-row">ADD</button>
</form>
<h3>Ingredientes</h3>
<table>
<tr>
<th>#</th>
<th></th>
<th>Cantidad</th>
<th>U.M</th>
<th>Eliminar</th>
</tr>
<tbody id="tabla-ingr"></tbody>
</table>
you can just use Jquery selected type=hidden to remove too, while you click remove botton.
$(document).on('click', 'button.removebutton', function () {
$(this).closest('tr').remove();
$('[type=hidden]').remove();
return false;
});
You can use input[type="hidden"] to remove input elements alone.
Code snippets:
$(document).on('click', 'button.removebutton', function () {
$(this).closest('tr').remove();
$('#form-receta input[type="hidden"]').remove();
return false;
});
Fiddle Demo
If the hidden inputs were added using append(), the order of these inputs woud be the same as shown in the table.
So there is 3 hidden fields created on each ADD click.
On DEL click, we know on wich row the click occured.
So we can deduct the index of the 3 hidden fields to remove.
In your HTML, I added <div id="hiddenInputList"></div> in the form.
Then in the code, to append the hidden fields:
// Append the hidden fields to a div, in the same order as the table.
$('#hiddenInputList').append('<input type="hidden" name="_id_ingr[]" value="'+ id +'" />');
$('#hiddenInputList').append('<input type="hidden" name="_cantidad_ingr[]" value="'+ cantidad +'" />');
$('#hiddenInputList').append('<input type="hidden" name="_um_ingr[]" value="'+ um +'" />');
And then, to remove them:
$(document).on('click', 'button.removebutton', function () {
var thisTR = $(this).closest("tr");
var thisTR_Index = thisTR.index();
console.log("thisTR_Index: "+thisTR_Index);
// Delete the 3 hidden fields (Must do it in the revers order)
$('#hiddenInputList').find("[type='hidden']").eq((thisTR_Index*3)+2).remove();
$('#hiddenInputList').find("[type='hidden']").eq((thisTR_Index*3)+1).remove();
$('#hiddenInputList').find("[type='hidden']").eq(thisTR_Index*3).remove();
// Remove the table row.
thisTR.remove();
return false;
});
In this CodePen, to be make it a visual example... Instead of hidden fields, I used classes.
Added fields are green. And on DEL click, we can see that re right ones are targeted because they turn red.
I made a table that you can add text to and edit it inside it.
However if you add more than three rows, It is stuck and not working anymore.
The errors comes from here:
document.getElementById('vda' + z).addEventListener('click', doSomething);
document.getElementById('cvda' + z).addEventListener('click', doSomething2);
It is only adding event listener to the last row added, so if you add more than one row. The not last row won't have a working edit button.
I checked the IDs by inspecting the edit and update buttons elements.
Try adding 3 rows then click on the edit button for one of the row.
you can look at the code here and also https://jsfiddle.net/3e6d4qsv/
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
</style>
</head>
<body>
<div style="display:inline-flex;">
<form id="myForm">
<input id="inptext" type="text" placeholder="Your name..."></input>
<input id="inpadress" style="margin-left: 10px;" type="text" placeholder="Your email..."></input>
</form>
<button onclick="myFunction()"style="margin-left: 10px;" id="box">Add</button>
</div>
<br>
<div style="display: inline-flex">
<table id="tablename" style="width:80%; margin-top:15px;">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</table>
<div id="buttons" style="float:right;width: 300px; margin-top:50px;">
</div>
</div>
<script>
var z = 1;
function myFunction() {
var x = document.getElementById("inptext").value;
var y = document.getElementById("inpadress").value;
var form = document.getElementById("myForm");
form.reset();
document.getElementById("tablename").innerHTML = document.getElementById("tablename").innerHTML + '<tr><td id=acvda'+ z + '>' + x + '</td><td id=zcvda' + z + '>' + y + '</td></tr>';
var h = '<button style="margin-left:8px" class="edit" id=vda' + z + '>Edit</button>';
var f = '<div id=zzza'+z+' style=height:10px></div>';
var abc = '<button style="margin-left:-36px" class="update" id="cvda'+z+'">Update</button>';
var total = h + abc + f;
document.getElementById("buttons").innerHTML = document.getElementById("buttons").innerHTML + total;
document.getElementById('vda' + z).addEventListener('click', doSomething);
document.getElementById('cvda' + z).addEventListener('click', doSomething2);
document.getElementById('cvda' + z).style.visibility='hidden';
z = z + 1;
}
function doSomething() {
document.getElementById("inptext").value = document.getElementById("ac"+this.id).innerHTML;
document.getElementById("inpadress").value = document.getElementById("zc"+this.id).innerHTML;
document.getElementById(this.id).style.visibility='hidden';
document.getElementById('c'+this.id).style.visibility='visible';
}
function doSomething2() {
document.getElementById("a"+this.id).innerHTML = document.getElementById("inptext").value;
document.getElementById("z"+this.id).innerHTML = document.getElementById("inpadress").value;
document.getElementById(this.id).style.visibility='hidden';
form.reset();
var edit = this.id;
var edit2 = edit.replace("c", "");
document.getElementById(edit2).style.visibility='visible';
}
</script>
</body>
</html>
The following line remove all your listeners:
document.getElementById("buttons").innerHTML =
document.getElementById("buttons").innerHTML + total;
document.getElementById('vda' + z).addEventListener('click',
doSomething);
use this instead:
var div = document.createElement('div');
div.innerHTML = total;
document.getElementById("buttons").appendChild(div);
I have a form where users have 10 text fields. But initially only 1 text field is shown. If the user needs to enter more data they can click on the add one button and then displays the next text field from the maximum of 10.
like so:
Im working with angular.js so I thought about using ng-show to hide & show fields.
<div class="form-group">
<input type="text" class="form-control" name="pointOne" ng-show="pointOne">
<input type="text" class="form-control" name="pointTwo" ng-show="pointTwo">
<input type="text" class="form-control" name="pointThree" ng-show="pointThree">
<span><button ng-click="addOne()">Add One</button></span>
</div>
I am unable to figure out the most effective way to doing this. Any hints, help or suggestions would be great.
Haven't tested it but this is how I would do it:
<div class="form-group" >
<input ng-repeat="i in getNumber(number)" type="text" class="form-control" name="point{{i}}" ng-show="$index<=counter">
<span><button ng-click="addOne()">Add One</button></span>
</div>
And in your controller just add something like this:
$scope.number = 10;
$scope.getNumber = function(num) {
return new Array(num);
}
$scope.counter=0;
$scope.addOne= function() {
$scope.counter++;
}
You could easily add elements to the DOM:
function createPetField() {
var input = document.createElement('input');
input.type = 'text';
input.name = 'pet[]';
return input;
}
var form = document.getElementById('myForm');
document.getElementById('addPet').addEventListener('click', function(e) {
form.appendChild(createPetField());
});
To go the Angular route, I'd suggest using ng-repeat. Here's a fiddle that might not be exactly what you're looking for, but it shows how to use ng-repeat and you can modify as needed:
Fiddle: https://jsfiddle.net/jvsnao97/5/
<body ng-app="myApp" ng-controller="myController">
<button ng-click="add_input()">Add Input</button>
<br/><br/>
<input type="text" class="form-control" ng-repeat="x in random_array" name="point{{$index}}">
</body>
var app = angular.module("myApp", []);
app.controller("myController", ["$scope", function($scope) {
$scope.random_array = [0]
$scope.add_input = function() {
var i = $scope.random_array.length
$scope.random_array.push(i)
}
}]);
When you want a new <input>, you simply push a new element to $scope.random_array.
Probably good way is to make array of input fields and then ng-repeat them. When user clicks on AddOne, then just push input field in array, and it will be there.
<html>
<head>
<title>jQuery add / remove textbox</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<style type="text/css">
div{
padding:8px;
}
</style>
</head>
<body>
<h1>jQuery add / remove textbox example</h1>
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("#addButton").click(function () {
if(counter>10){
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.after().html('<label>Textbox #'+ counter + ' : </label>' +
'<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
});
$("#removeButton").click(function () {
if(counter==1){
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
$("#getButtonValue").click(function () {
var msg = '';
for(i=1; i<counter; i++){
msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
}
alert(msg);
});
});
</script>
</head><body>
<div id='TextBoxesGroup'>
<div id="TextBoxDiv1">
<label>Textbox #1 : </label><input type='textbox' id='textbox1' >
</div>
</div>
<input type='button' value='Add Button' id='addButton'>
<input type='button' value='Remove Button' id='removeButton'>
<input type='button' value='Get TextBox Value' id='getButtonValue'>
</body>
</html>
JQuery can be used to add inputs in your addOne() method.
Like so:
var maxInputs = 10;
var currentInput = 0;
function addOne() {
currentInput++;
if (currentInput > maxInputs) {
currentInput = maxInputs;
return;
}
var name = "point" + currentInput;
var $input = $("<input type='text' class='form-control' name='" + name + "' ng-show='" + name + "'>");
$(".form-group").append($input);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group">
<span><button onclick="addOne()">Add One</button></span>
</div>