I am creating a form where the user can add fields one after the other. For each field I am setting a "remove" button. Each field is in a table, so I give a random id to the table, and pass this id to a removing function doing: $(random-id).remove().
The strange thing is that jQuery is removing all of the tables created by the user, as if the id is not taken into account
Why that can be?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script>
function delete_field(id)
{
$("#"+id+"").remove();
}
function add_form_field()
{
id = Math.random();
html = '<table id='+id+'>\
<tr><td>Label </td></tr>\
</table>\
\
<button onclick=delete_field('+id+')>remove</button>';
$("form").append(html);
}
</script>
</head>
<body>
<form>
</form>
<button onclick=add_form_field()> Add a field </button>
</body>
</html>
Don't use Math.random, rather increment a number and create ID like: #tab_NN.
Add an ID to your Form Element id=myForm
Delegate click events to dynamically generated delete buttons using .on()
While removing the table that matched the button data-* attribute, delete the button too using .add( this ) (where this stays for the clicked button)
var id = 0;
function delete_field(event){
event.preventDefault();
$("#tab_"+ $(this).data("remove")).add(this).remove();
}
function add_form_field(){
id += 1;
var html = '<table id="tab_'+ id +'">'+
'<tr><td>Label</td></tr>'+
'</table>'+
'<button data-remove="'+id+'" class="remove">remove</button>';
$("#myForm").append(html);
}
$('#addField').on('click', add_form_field);
$('#myForm').on('click', '.remove', delete_field);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="myForm"></form>
<button id="addField"> Add a field </button>
The code above allows you to have changes in the future markup cause it targets a specific ID, but in case your DELETE buttons will always be exactly after table than you can do it without assigning ID's, by simply using .prev("table"):
http://jsbin.com/wuqati/1/edit
function delete_field(event){
event.preventDefault();
$(this).prev("table").add(this).remove();
}
function add_form_field(){
var html = '<table>'+
'<tr><td>Label</td></tr>'+
'</table>'+
'<button class="remove">remove</button>';
$("#myForm").append(html);
}
$('#addField').on('click', add_form_field);
$('#myForm').on('click', '.remove', delete_field);
Math.random() produces a floating point number less than 1 which is invalid for an id. You can use a global variable to keep count of the rows created. Keep in mind that a CSS ID can not start with a digit. So append the number to a string before using it as an ID.
<script>
function delete_field(id)
{
$("#"+id+"").remove();
}
tableID = 1;
function add_form_field()
{
id = 'table-'+tableID;
html = '<table id='+id+'>\
<tr><td>Label </td></tr>\
</table>\
\
<button onclick=delete_field('+id+')>remove</button>';
$("form").append(html);
tableID++;
}
</script>
Why not simplify this by doing something like below.
$(".remover").click(function() {
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<input type="text" placeholder="input One"/> <input type="button" class="remover" value="remove" />
</td> </tr>
<tr>
<td>
<input type="text" placeholder="input Two"/> <input type="button" class="remover" value="remove" />
</td> </tr>
<tr>
<td>
<input type="text" placeholder="input Three"/> <input type="button" class="remover" value="remove" />
</td> </tr>
</table>
Related
Let's say I have an Admin page with a list of items, and I have various capabilities to modify those records -- Change its name, Delete it, Clear its contents, etc. For example a row would be rendered similar to the following:
const row =`<tr id="id${this.id}">
<td name="name">
<input type="text" placeholder="Set name" value=${this.name} />
<input type="submit" name="setName" value="Save" />
</td>
<td name="size">${this.set.size}<td/>
<td name="elements"><b>{ ${this.renderSetElements()} }</td>
<td name="actions">
<input type="text" placeholder="Add element" />
<input type="submit" name="addElement" value="Add" />
<input type="submit" name="clearElements" value="Clear" />
<input type="submit" name="deleteSet" value="Delete" />
</td>
</tr>`
What would the proper way to add forms here? Should there be one form around the row? Should there be four forms per row -- one for each action? (setName, addElement, clearElements, deleteSet)? Or what is the suggested way to accomplish the above? Additionally, is identifying the row as id${this.id} appropriate, or what's usually the contention for something like that?
The short answer is that you can have a
The form inside a cell td.
<table>
<tr><td><form>...</form></td></tr>
<tr><td><form>...</form></td></tr>
</table>
You can have a table inside a form
<form>
<table>
<tr><td>...</td></tr>
<tr><td>...</td></tr>
</table>
</form>
Or you can ditch the form element and use JavaScript to do Ajax:
In this case, I will be using the Javascript library jQuery since it simplifies a lot of stuff; however, you can implement this with pure Javascript if you want to.
// Wait for the document to be fully loaded
$(document).ready(function(){
$(".submit").on("click", function(event){
event.preventDefault();
console.log("submit...");
var url = "https://httpbin.org/get";
var data = {
id: $('#id').val()
};
$.get(url, data, function(result){
console.log("Server received the id number: ", result.args.id);
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td><input class="inputs" id="id" value="0"/></td>
</tr>
<tr>
<td><button class="submit" id="add">Add</button></td>
</tr>
</table>
In your particular case, you might try generate these rows dynamically and using Ajax to send the information to the server, without having to refresh the whole page. Here is an example:
(function(){
let count = 0;
function createColumn(){
let column = $('<td>');
let text = $(`<input type="text" placeholder="Set name" value="${count}">`);
let submit = $('<button class="save" type="submit" name="setName">Save</button>');
column.append(text);
column.append(submit);
return column;
}
function createRow(){
let row = $('<tr>');
row.attr("id", count++);
row.append(createColumn());
return row;
}
let table = $('#table');
$('#btnAdd').on('click', () => {
table.append(createRow());
});
table.on('click', '.save', function() {
let text = $(this).prev().val();
console.log("INPUT TEXT:", text);
});
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btnAdd">Add Row</button>
<table id="table">
</table>
I hope you found this informative, useful, and that you can apply it to your particular issue.
My requirement is I have a table having 4 columns
in first cloumn can select item name, second is item rate, third is item qty last one is the total amount
I want to get the item rate automaticaly in second column while changing item in first, and want tom get the total after focus out from qty field as the multiple opf qty and rate,
i want a row adding buton to add rows and the onchange and onblur event should working on all rows,
how can i do this ?
my coode is
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/dataTables.bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.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.7/js/bootstrap.min.js"></script>
<table id="item_table">
<tr><th>SL No</th><th>Item Name</th><th>Rate</th><th>Qty</th><th>Total</th><th><button type="button" name="add" class="btn btn-success btn-sm add" >add</button></tr>
</table>
<script>
$(document).ready(function(){
$(document).on('click', '.add', function(){
var html = '';
html += '<tr>';
html += '<td><input type="text" name="slno[]" /></td>';
html += '<td><select name="item[]" id=item[] onchange="show_rate()"><option value="10">Item 1</option><option value="20">Item 2</option><option value="30">Item 3</option><option value="35">Item 4</option></td>';
html += '<td><input type="text" name="rate[]" id="rate[]" /></td>';
html += '<td><input type="text" name="qty[]" id="qty[]" onblur="sum_total()"/></td>';
html += '<td><input type="text" name="total[]" id="total[]" /></td>';
html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove" >Remove</button></td></tr>';
$('#item_table').append(html);
});
$(document).on('click', '.remove', function(){
$(this).closest('tr').remove();
});
});
function show_rate(){
var a=document.getElementsByName("item[]")[0].value;
var b=document.getElementById("rate[]");
b.value=a;
}
function capitalise(){
var c=document.getElementsByName("rate[]")[0].value;
var d=document.getElementsByName("qty[]")[0].value;
var e=document.getElementById("total[]");
e.value=+c * +d;
}
</script>
You must make your select with values in the option tags. Each option must have a unique ID or name. You can then call upon the value attribute of the option and display it in column 2. Then use simple math operators to take the value and multiply it by a set variable, which you can also get from a select by using the mentioned above method. Example 12
Look at other posts for questions about adding rows, there are tons of posts out there on that topic with exactly the code you need.
I'm working on a request form. It needs to list the study team members on a research study besides the PI and submitter of the form. However, some studies will have no additional team members so I would like the row to remain hidden until someone clicks the Add Team Member button.
What's working:
1. I've got the element hidden on initially loading the page.
2. Clicking add rows adds the correct rows.
3. Clicking remove will remove a row.
Current problems:
1. If someone adds a team member then removes all the team members, clicking add team member will not add a row.
2. When the element is hidden on initial page load, the first time the Add Team Member button is clicked it adds two rows.
Here's my current code with only the relevant section of the form.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="assets/css/test.css" />
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function addTableRow(jQtable){
jQtable.each(function(){
var tds = '<tr>';
jQuery.each($('tr:last td', this), function() {tds += '<td>'+$(this).html()+'</td>';});
tds += '</tr>';
if($('tbody', this).length > 0){$('tbody', this).append(tds);
}else {$(this).append(tds);}
});
}
</script>
<script>
function myDeleteFunction() {
document.getElementById("stmember").deleteRow(0);
}
</script>
<script type="text/javascript">
$(function() {
$('#add').click(function() {
$('#stmember').show();
});
});
</script>
<style>
#stmember {
display: none
}
</style>
</head>
<body>
<h3><strong>Other Study Team Members:</strong></h3>
<FORM>
<table id="stmember">
<tr>
<td>Name:
<label for="namest1"></label>
<input type="text" name="namest1" id="namest1" placeholder="First Name, Last Name" />
</td>
<td>JHED ID:
<label for="jhedst1"></label>
<input type="text" name="jhedst1" id="jhedst1" />
</td>
<td>Email:
<label for="emailst1"></label>
<input type="email" name="emailst1" id="emailst1" placeholder="you#example.com" />
</td>
</tr>
</table>
<CENTER>
<button type="button" id="add" onclick="addTableRow($('#stmember'));">Add Study Team Member</button>
<button type="button" onclick="myDeleteFunction()">Remove Study Team Member</button>
</CENTER>
</FORM>
</body>
</HTML>
Here are a couple solutions for you:
Solution 1
Store the HTML of the row in your addTableRow function within a variable. That way you can use tokens for the input IDs to ensure they are unique. Also, you won't have to provide the first row in your HTML, as it will be created through your JS function. Something like:
var template = "<tr><td>Name:<label for="namest1"></label><input type="text" name="namest!!TOKEN!!" id="namest!!TOKEN!!" placeholder="First Name, Last Name" /></td><td>JHED ID:<label for="jhedst1"></label><input type="text" name="jhedst!!TOKEN!!" id="jhedst!!TOKEN!!" /></td><td>Email:<label for="emailst1"></label><input type="email" name="emailst!!TOKEN!!" id="emailst!!TOKEN!!" placeholder="you#example.com" /></td></tr>";
Solution 2
Use a templating engine like jsRender or Mustache.
Conclusion
The cleanest method would be to use a templating engine, if you're game for that. But using a string to store the template within your function will work.
If you're using jQuery, I'd fully commit to using that instead of mixing vanilla JS, as with jQuery you can use clone and remove effectively for what you're trying to achieve. Also, if you plan on submitting this as a form, please be sure to add [] to your input names so you can parse each row properly as the names are the same on the input fields. Please see the below snippet:
function addTableRow() {
var $tableRow = $('tr.model-row:first-child');
var $clonedRow = $tableRow.clone().show();
$('#stmember').append($clonedRow);
}
function myDeleteFunction() {
var $memberTRs = $('tr', '#stmember');
// If rowcount === 1, hide first row, don't remove it!!
var rowCount = $memberTRs.length;
if (rowCount === 1) {
$('tr.model-row:first-child').hide();
return;
}
$memberTRs.last().remove();
}
jQuery(function() {
$('#delete').click(function() {
myDeleteFunction();
});
$('#add').click(function() {
addTableRow();
});
});
.model-row {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h3><strong>Other Study Team Members:</strong></h3>
<FORM>
<table id="stmember">
<tbody>
<tr class="model-row">
<td>Name:
<label for="namest1"></label>
<input type="text" name="namest1[]" id="namest1" placeholder="First Name, Last Name" />
</td>
<td>JHED ID:
<label for="jhedst1"></label>
<input type="text" name="jhedst1[]" id="jhedst1" />
</td>
<td>Email:
<label for="emailst1"></label>
<input type="email" name="emailst1[]" id="emailst1" placeholder="you#example.com" />
</td>
</tr>
</tbody>
</table>
<CENTER>
<button type="button" id="add">Add Study Team Member</button>
<button type="button" id="delete">Remove Study Team Member</button>
</CENTER>
</FORM>
</body>
When you create a row, you use the last existing row to create it. But if you remove all the row you lose your example of row.
You can easily fix your problem by checking when you remove a Row, if it's the last one, add a new row before remove the last one.
For convenience I'm giving the script and the html in one place (instead of separate .js file). After selecting any check checkboxes if I click the "edit" link then the alert keeps repeating in a loop and the no of selected checkboxes are reported as 0 1 2 3 4 5 .... in successive occurences. Anybody's help in this matter will be appreciated.
<!doctype html>
<html>
html>
<head>
<title>Cities</title>
<script type="text/javascript" src="jquery-3.2.1/jquery-3.2.1.min.js"></script>
<script type = "text/javascript">
var jq = jQuery.noConflict();
var ids = new Array();
jq(document).ready(function () {
jq("#edit").click(function(){
jq('input[name="cid"]:checked').each(function() {
ids.push(parseInt(jq(this).val()));
}); // end checked each
if(ids.length > 0)
alert(ids.length + " cities selected \n"+"their names: "+ids);
else
alert("Please select one or more rows to edit.");
}); // end #edit click
}); // end document ready
function setCityUpdateAction(){
jq("#edit").click();
}
</script>
</head>
<body>
<form name="myform">
<table border=1px>
<tr><th></th>select<th>CityID</th><th>City</th></tr>
<tr><td><input type="checkbox" name="cid" value=1></td>
<td>1</td><td>London</td></tr>
<tr><td><input type="checkbox" name="cid" value=2></td>
<td>1</td><td>New York</td></tr>
<tr><td><input type="checkbox" name="cid" value=3></td>
<td>1</td><td>Paris</td></tr>
<tr><td></td><td></td><td><a id="edit" href="#" onclick="setCityUpdateAction();">edit</a></tr>
</table>
</form>
</body>
</html>
You already have click event handler when you write jq("#edit").click. So you need to get rid of onclick event handler in the <a> tag.
So, it should look like this:
<a id="edit" href="#" >edit</a>
Additionally, you can get rid of function as well due to click event handler already set. So remove below function.
setCityUpdateAction() {
jq("#edit").click();
}
try this:
<!doctype html>
<html>
<head>
<title>Cities</title>
<script type="text/javascript" src="jquery-3.2.1.min.js"></script>
<script type = "text/javascript">
var jq = jQuery.noConflict();
jq(document).ready(function () {
jq("#edit").click(function(){
var ids = new Array();
jq('input[name="cid"]:checked').each(function() {
ids.push(parseInt(jq(this).val()));
}); // end checked each
if(ids.length > 0)
alert(ids.length + " cities selected \n"+"their names: "+ids);
else
alert("Please select one or more rows to edit.");
setCityUpdateAction()
}); // end #edit click
}); // end document ready
function setCityUpdateAction(){
jq("#edit").click();
}
</script>
</head>
<body>
<form name="myform">
<table border=1px>
<tr><th></th>select<th>CityID</th><th>City</th></tr>
<tr><td><input type="checkbox" name="cid" value=1></td>
<td>1</td><td>London</td></tr>
<tr><td><input type="checkbox" name="cid" value=2></td>
<td>1</td><td>New York</td></tr>
<tr><td><input type="checkbox" name="cid" value=3></td>
<td>1</td><td>Paris</td></tr>
<tr><td></td><td></td><td><a id="edit" href="#">edit</a></tr>
</table>
</form>
</body>
</html>
First declare the ids array inside the jq("#edit").click event, second remove the onclick from a tag and call the setCityUpdateAction function inside your jq("#edit").click event.
I hope this will help you.
Make sure you reset the ids array, Also serialize the form values,
Make sure you name every inputfield! It can be achieved with serializeArray() like this:
var $form = $(form).serializeArray();
$.each($form, function(i, field) {
...
});
Javascript
var jq = jQuery.noConflict();
jq(document).ready(function () {
jq("#edit").click(function(){
var $form = jq(myform).serializeArray();
var ids = new Array();
jq.each($form, function(i, field) {
ids.push(parseInt(field.value)+"-"+field.name);
});
if($form.length > 0)
alert($form.length + " cities selected \n"+"their names: "+ids);
else
alert("Please select one or more rows to edit.");
}); // end #edit click
}); // end document ready
HTML
<form name="myform">
<table border=1px>
<tr><th></th>select<th>CityID</th><th>City</th></tr>
<tr><td><input type="checkbox" name="london" value=1></td>
<td>1</td><td>London</td></tr>
<tr><td><input type="checkbox" name="newyork" value=2></td>
<td>2</td><td>New York</td></tr>
<tr><td><input type="checkbox" name="paris" value=3></td>
<td>3</td><td>Paris</td></tr>
<tr><td></td><td></td><td><a id="edit" href="javascript:;">edit</a></tr>
</table>
</form>
See here how it is done: jsFiddle
I want to create a table that can auto calculate some values for each fields for each rows. I found these jquery calculator, I would like to ask how am I going to use it incase I'll be using jstl forEach, how can I use this so I would it can auto calculate what ever user entered on a field for each rows.. Thanks..
<html>
<head>
<script type="text/javascript" src="js/jquery-latest.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
$(document).ready(function()
{
$('input').change(function()
{
var ProductUnitVal = parseInt($('#product-unit-val').val());
var TotalUnitSales = parseInt($('#total-unit-sales').val());
var answer = ProductUnitVal * TotalUnitSales;
$('#sales-val').html('$' + answer);
});
});
</script>
</head>
<body>
Unit Value <input type="text" id="product-unit-val" /><br />
Unit Sales <input type="text" id="total-unit-sales" /><br />
<span id="sales-val"></span>
</body>
</html>
Make it row based. When an input changes, look for the closest row (tr) which finds the scope of the elements. Then search just that scope (i.e. the row) for the various elements. Note, I changed from id to class for the 3 items.
<table id="thetable">
<tr>
<td>
Unit Value <input type="text" class="product-unit-val" />
</td>
<td>
Unit Sales <input type="text" class="total-unit-sales" />
</td>
<td><span class="sales-val"></span></td>
</tr>
</table>
And then your script:
$(document).ready(function()
{
$('#thetable input').change(function()
{
var $row = $(this).closest('tr');
var ProductUnitVal = parseInt($row.find('.product-unit-val').val());
var TotalUnitSales = parseInt($row.find('.total-unit-sales').val());
var answer = ProductUnitVal * TotalUnitSales;
$row.find('.sales-val').html('$' + answer);
});
});