I would like to clone a select and update the name and id values. The select is within a <tr><td>
<table>
<tr id="tr_1">
<td id="td_1">
<select name="tech_1" id="tech_1">
<option value="0">Please Select</option>
<option value="1">Mango</option>
<option value="2">Apple</option>
<option value="3">Banana</option>
<option value="4">Orange</option>
</select>
</td>
</tr>
</table>
<input type="button" id="btnClone" value="Clone" />
I can do it without the table, but my challenge is putting the clone within a new <tr><td> ... </td></tr>
Here is my jquery:
$("#btnClone").bind("click", function () {
// get the last SELECT which ID starts with ^= "tech_"
var $tr = $('tr[id^="tr_"]:last');
// get the last SELECT which ID starts with ^= "tech_"
var $select = $('select[id^="tech_"]:last');
// Read the Number from that SELECT's ID (i.e: 3 from "tech_3")
// And increment that number by 1
var num = parseInt( $select.prop("id").match(/\d+/g), 10 ) +1;
// Clone it and assign the new ID (i.e: from num 4 to ID "tech_4")
var $klon = $select.clone().prop('id', 'tech_'+num ).prop('name', 'tech_'+num );
// Finally insert $klon wherever you want
$tr.after("<tr><td>").after($klon).after("</td></tr>");
});
This code results in the cloned <select> below the original and nothing between the new <tr><td> and </td></tr>
Add tr and td first with the id of tr and then add select to the td under new tr like following.
$("#btnClone").bind("click", function () {
var $tr = $('tr[id^="tr_"]:last');
var $select = $('select[id^="tech_"]:last');
var num = parseInt($select.prop("id").match(/\d+/g), 10) + 1;
var $klon = $select.clone().prop('id', 'tech_' + num).prop('name', 'tech_' + num);
$tr.after($("<tr id=tr_" + num + "><td></td></tr>")); // change here
$('#tr_' + num + ' td').append($klon); // change here
});
Try to append the select element after creating the tr and td,
$tr.after($("<tr><td></td></tr>").find("td").append($klon).end());
You should create the elements rather than appending html.
var $klon = $select.clone().prop('id', 'tech_'+num ).prop('name', 'tech_'+num );
var newTr = $('<tr/>');
var newTd = $('<td/>');
newTr.insertAfter($tr);
newTr.append(newTd);
newTd.append($klon);
Working example : https://jsfiddle.net/DinoMyte/raz34m93/
Try using jQuery(html, attributes) ; also, to include childNodes of cloned element, add true to .clone(true) , see .clone()
$tr.after($("<tr>", {append:$("<td>", {append:$klon})}))
$("#btnClone").on("click", function() {
// get the last SELECT which ID starts with ^= "tech_"
var $tr = $('tr[id^="tr_"]:last');
// get the last SELECT which ID starts with ^= "tech_"
var $select = $('select[id^="tech_"]:last');
// Read the Number from that SELECT's ID (i.e: 3 from "tech_3")
// And increment that number by 1
var num = parseInt($select.prop("id").match(/\d+/g), 10) + 1;
// Clone it and assign the new ID (i.e: from num 4 to ID "tech_4")
var $klon = $select.clone(true).prop('id', 'tech_' + num).prop('name', 'tech_' + num);
// Finally insert $klon wherever you want
$tr.after(
$("<tr>", {
append: $("<td>", {
append: $klon
})
})
)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr id="tr_1">
<td id="td_1">
<select name="tech_1" id="tech_1">
<option value="0">Please Select</option>
<option value="1">Mango</option>
<option value="2">Apple</option>
<option value="3">Banana</option>
<option value="4">Orange</option>
</select>
</td>
</tr>
</table>
<button id="btnClone">click</button>
Related
I have a program that simply add's students to a table and stores that information into local-storage. I can add students and see the data stored into local-storage, but my big problem is figuring out how to remove a specific object within local storage upon button click after adding it (without clearing all of local storage).
Link for test: https://www.chriscaldwelldev.com/studentIA/student.html
Here is the table and inputs (HTML):
<body>
<div class="container">
<h1 class="title">Student Manager</h1>
<div class="controlCenter">
<table id="studentTable" class="table">
<thead>
<tr>
<th>Student Number:</th>
<th>Name:</th>
<th>Address:</th>
<th>Phone Number:</th>
<th>GPA:</th>
<th>Academic Plan:</th>
<th>Level:</th>
<th>Status:</th>
</tr>
</thead>
<tbody id="students"></tbody>
<tbody>
<tr>
<td><input type="text" id="studentN"></td>
<td><input type="text" id="name"></td>
<td><input type="text" id="address"></td>
<td><input type="text" id="phoneN"></td>
<td><input type="text" id="gpa"></td>
<td><input type="text" id="ap"></td>
<td><select id="selectL" name="SelectL">
<option value="" disabled selected>Select...</option>
<option value="freshman">Freshman</option>
<option value="sophomore">Sophomore</option>
<option value="junior">Junior</option>
<option value="senior">Senior</option>
<option value="graduate">Graduate</option>
</select></td>
<td><select id="selectS" name="SelectS">
<option value="" disabled selected>Select...</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select></td>
</tr>
</tbody>
</table>
<input id="add" class="addButton" value="ADD">
</div>
</div>
</body>
Here is the JS:
// when the document loads
$(function(){
// add an onclick function to the id=add button
$("#add").click(function(){
var studentN = $("#studentN").val();
var name = $("#name").val();
var address = $("#address").val();
var phoneN = $("#phoneN").val();
var gpa = $("#gpa").val();
var ap = $("#ap").val();
var selectL = $("#selectL").val();
var selectS = $("#selectS").val();
if(studentN==null || name==null || address==null || phoneN==null ||
gpa==null || ap==null || selectL==null || selectS==null){
alert("All Fields Are Required to Add a Student");
return;
}
//create JSON object with text inputs with key:value pairs
var student = {
studentN: studentN,
name: name,
address: address,
phoneN: phoneN,
gpa: gpa,
ap: ap,
selectL: selectL,
selectS: selectS
}
//load local storage
var students = JSON.parse(localStorage.getItem("students"));
//if empty
if(!students){
students = [];
}
students.push(student);
localStorage.setItem("students", JSON.stringify(students));
// store a copy of the row in the body
var row = $("<tr>");
// store a copy of the current state in the <td> tag
var studentNData = $("<td>");
// now change the innerHTML for that <td>
studentNData.html(studentN);
// append the new value to our row
row.append(studentNData);
(...)
// store a copy of the current state for the next <td> tag
var selectSData = $("<td>");
// change the inner html of the <td>
selectSData.html(selectS);
// append the new value to our row
row.append(selectSData);
var deleteButton = $("<td>" + "<input type=\"button\" class=\"deleteButton\" value=\"X\">");
row.append(deleteButton);
// on the DOM, put the new row on the top of the list
$("#students").prepend(row);
// reset the values of the text inputs to empty strings
$("#studentN").val("");
$("#name").val("");
$("#address").val("");
$("#phoneN").val("");
$("#gpa").val("");
$("#ap").val("");
$("#selectL").val("");
$("#selectS").val("");
});
var students = JSON.parse(localStorage.getItem("students"));
$("#studentTable").on('click', '.deleteButton', function () {
$(this).closest('tr').remove();
//I can't think of what to do here...
});
if (students) {
// loop through the entire JSON array stored in local storage
for (i in students) {
// get a current copy of the content in the row
var row = $("<tr>");
// store a copy of the current state in the <td> tag, update the innerHTML, then append it to the DOM at the end of the row
var studentNData = $("<td>");
studentNData.html(students[i].studentN);
row.append(studentNData);
(...)
var selectSData = $("<td>");
selectSData.html(students[i].selectS);
row.append(selectSData);
var deleteButton = $("<td>" + "<input type=\"button\" class=\"deleteButton\" value=\"X\">");
row.append(deleteButton);
// now add the row to the DOM at the beginning of the list
$("#students").prepend(row);
}
}
});
I assume that whatever I need to do primarily needs to be done in the deleteButton onclick. I've thought some ideas through but they seem super wrong. I appreciate any help if you can.
One solution you could use is adding a data-studentn attribute to your delete buttons. Then, when the delete button is clicked, you can load the students array from localStorage, remove the student with that studentn, and save the new students array.
Change
"<input type=\"button\" class=\"deleteButton\" value=\"X\">"
to
"<input type=\"button\" class=\"deleteButton\" value=\"X\" data-studentn=\"" + students[i].studentN + "\" >"
Note: Remember to do something similar in the other place where you create a delete button.
Under //I can't think of what to do here... you can do the following:
var deletedStudentN = $(this).attr('data-studentn');
var students = JSON.parse(localStorage.getItem("students"));
students = students.filter(function(student) {
return student.studentN != deletedStudentN;
});
localStorage.setItem("students", JSON.stringify(students));
I would like to change the selected value of a dropdown onclick of a button. There are a few dropdowns in a div with class = '.WHERE', I want to append a parenthesis to the first dropdown and to the second to last dropdown
The button calls this function:
//add parenthesis to the first child, and to the second to last child
function addParens(){
var len = $(".WHERE").children('div > select').length;
len -= 1;
var firstDropdown = $('.WHERE').children().first(); //the first child
var lastDropdown = $('.WHERE').children().eq(len); //the second to last child
//attempting here to append left parenthesis to the first dropdown
var text = firstDropdown.val(); //the old selected option
text = '(' + text; //new text with left parenthesis
console.log(text); //prints out correctly
firstDropdown.text(text); //tried ,doesn't work
var firstId = firstDropdown.attr('id'); //grab id firstDropdown
$('#'+firstId).val(text); //doesn't work by grabbing id first
firstDropdown.val(text); //also tried this, doesn't work
}
Afterwards if I print firstDropwdown.val() it prints null, and the dropdown has nothing selected.
here is a sample of what one of the dropdown looks like, it is created dynamically
function addParens() {
var len = $(".WHERE").children('div > select').length;
len -= 1;
var children = $('.WHERE').children();
var firstDropdown = children.first().find("option:selected"); //the first child
var lastDropdown = children.eq(len).find("option:selected"); //the second to last child
firstDropdown.text('(' + firstDropdown.text() + ')');
lastDropdown.text('(' + lastDropdown.text() + ')');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="WHERE">
<select>
<option></option>
<option>Article.Author</option>
<option>Article.Editor</option>
<option>Article.Publisher</option>
<option>Article.Title</option>
<option>Article.BookTitle</option>
<option>Article.Year</option>
</select>
<select>
<option></option>
<option>Article.Author</option>
<option>Article.Editor</option>
<option>Article.Publisher</option>
<option>Article.Title</option>
<option>Article.BookTitle</option>
<option>Article.Year</option>
</select>
<select>
<option></option>
<option>Article.Author</option>
<option>Article.Editor</option>
<option>Article.Publisher</option>
<option>Article.Title</option>
<option>Article.BookTitle</option>
<option>Article.Year</option>
</select>
<select>
<option></option>
<option>Article.Author</option>
<option>Article.Editor</option>
<option>Article.Publisher</option>
<option>Article.Title</option>
<option>Article.BookTitle</option>
<option>Article.Year</option>
</select>
</div>
<button onClick="addParens();">
DO IT
</button>
When hitting areasensornewline_button, a new row gets created and appended to the table. I can change the row ID, but all new dropdownboxes within this row now have id="selectedArea0", id="selectedSensor0" and name="AreaBinding0", name="sensorBinding0". These have to be 1, 2 and so fort. Any help would much be appreciated!!!!
<table border="0" id="areasensor_table">
<tr id="areasensor_row0">
<td id="area_column0">
<select name="areaBinding0" id="selectedArea0"> #for(area <- areas) {
<option value="#area.uniqueid">#area.name</option>}
</select>
</td>
<td id="sensor_column0">
<select name="sensorBinding0" id="selectedSensor0"> #for(sensor <- sensors) {
<option value="#sensor.id">#sensor.name</option> }
</select>
</td>
<td>
<a class="glyphicon glyphicon-plus" id="areasensornewline_button"></a>
</td>
</tr>
</table>
<p>
<p>
<script>
var q = 1;
document.getElementById('areasensornewline_button').onclick = cloneRowAreaSensor;
function cloneRowAreaSensor() {
var row = document.getElementById('areasensor_row0'); // find row to copy
var table = document.getElementById('areasensor_table'); // find table to append to
var clone = row.cloneNode(true); // copy children too
var innerClone = row.innerHTML;
clone.id = 'areasensor_row' + q; // change id or other attributes/contents
q++;
table.appendChild(clone); // add new row to end of table
}
</script>
A trick is to use Regular expression but is far to be perfect ...
function cloneRowAreaSensor() {
var row = document.getElementById('areasensor_row0'); // find row to copy
var table = document.getElementById('areasensor_table'); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.innerHTML = clone.innerHTML.replace(/0"/g, q + '"');
clone.id = 'areasensor_row' + q; // change id or other attributes/contents
q++;
table.appendChild(clone); // add new row to end of table
}
The added row is placed outside the tbody html tag. You really should use jQuery, il will help you a lot.
Your code only works first time. Create a counter use it to name element.
Example:
var count = 1;
for(i = 0; i<= 10; i++){
var row = document.getElementById('areasensor_row'+ count +'');
}
It is a simple example. You need to restructure your code like this example. (This cicle for isnt better example, but it works at 10 elements)
Please can someone tell me why the first row gets and index value of 1 but every other new row also get 1 instead of 2,3,4 and so on.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<form>
<table>
<thead>
<tr>
<th scope="col">Track</th>
<th scope="col">Album</th>
<th scope="col">Artist</th>
</tr>
</thead>
<tbody>
<tr>
<td><input name="track[0]" id="track"></td>
<td><input name="album[0]" id="album"></td>
<td>
<select name="artist[0]" id="artist">
<option value="">Please select</option>
<option value="1">Joe Bloggs</option>
<option value="2">Jack Bloggs</option>
<option value="3">Tina Bloggs</option>
</select>
</td>
</tr>
</tbody>
</table>
</form>
<button>Add Row</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
$(document).ready(function($)
{
// trigger event when button is clicked
$("button").click(function()
{
// add new row to table using addTableRow function
addTableRow($("table"));
// prevent button redirecting to new page
return false;
});
function addTableRow(table)
{
var $tr = $(table).find("tr:last").clone();
alert($tr);
var fname = $("#track").attr("name");
var nid = fname.match(/\[(.*?)\]/g);
var idx = nid[0];
idx = idx.replace(/[[\]]/g,'')
var n = fname.split("[");
idx = parseInt(idx) + 1;
$tr.find("input,select").attr("name", n[0] + "[" + idx + "]");
$(table).find("tbody tr:last").after($tr);
};
});
</script>
</body>
I cant seem to work out how to add a new row every time increasing the "name" of each table element by 1 every time ready to use an AJAX post.
The new rows are being created wrong. Artist and Album elements name are always track[0]
Wouldn't be easier to do something like this?
function addTableRow(table) {
var index = $(table).find("tbody tr").length;
var $tr = $(table).find("tr:last").clone();
$tr.find("input,select").each(function (i, k) {
var old_name = $(k).attr("name");
var new_name = old_name.replace(index-1, index);
$(k).attr("name", new_name);
});
$(table).find("tbody tr:last").after($tr);
};
DEMO
Also, consider to give a class instead of a id in every input/select and give a id to the row. It would be easier to work with. as #HMR said when cloning the tr the inputs and select id's are cloned as well, adding the row then causes multiple elements with the same id's. This is not good, make sure each element as a unique ID
How about just counting tr in the tbody instead:
function addTableRow(table)
{
var $tr = table.find("tbody").find("tr").last().clone();
var fname = $("#track").attr("name");
var nid = fname.match(/\[(.*?)\]/g);
var new_idx = table.find('tbody').find('tr').length;
var n = fname.split("[");
idx = parseInt(idx) + 1;
$tr.find("input,select").attr("name", n[0] + "[" + new_idx + "]");
$(table).find("tbody tr:last").after($tr);
};
Using a select form field with values of "10", "20", "30", how could you reveal / hide that number of tr rows in a table onchange of the dropdown?
Something like:
$("#rows").change(function(){
var num_rows = $(this).val();
$("#data tr").reveal(num_rows) (???)
});
EDIT: rows should be added / removed starting from the bottom of the table.
A sliding show / hide effect would be great.
as kennis answered, use jQuery's slice() method.
I've put together a working example that you can try here: http://jsfiddle.net/a9TQ5/
HTML Markup:
<table id="mytable">
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
...
</tbody>
</table>
Javascript Code:
function show (min, max) {
var $table = $('#mytable'), // the table we are using
$rows = $table.find('tbody tr'); // the rows we want to select
min = min ? min - 1 : 0;
max = max ? max : $rows.length;
$rows.hide().slice(min, max).show(); // hide all rows, then show only the range we want
return false;
}
Using this function you are able to control the number of rows in #mytable by using these examples:
show(); // show all rows
show(1, 10); // show rows 1 - 10
show(1, 20); // show rows 1 - 20
show(3, 7); // show rows 3 - 7
show(20); // show rows 20 and up
You can bind this function to the change on a <select> like so:
HTML:
<select id="limit">
<option value="0">None</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="" selected>All</option>
</select>
Javascript:
$('#limit').bind('change', function () {
show(0, this.value);
});
Let me know if this is what you had in mind...
I think this should work.
$("#rows").change(function(){
var num_rows = $(this).val();
$("#data tr").slice(num_rows).hide();
});
So, I needed a break from work so I decided to throw this together (hopefully I read your question correctly ;)):
$(document).ready(function(){
$('#rows').change(function(){
if($('#tbl tr').length !== parseInt($(this).val()))
{
(u = function(){
if($('#tbl tr').length < parseInt($('#rows').val()))
{
var id = $('#tbl tr').length;
var e = $('#tbl').append('<tr style="display: none;" id="'+id+'"><td>foo</td></tr>');
$('#'+id).fadeIn('fast', function(){
if($('#tbl tr').length < parseInt($('#rows').val())) u();
});
}
else if($('#tbl tr').length > parseInt($('#rows').val()))
{
var id = $('#tbl tr').length-1;
$('#tbl #'+id).fadeOut('fast', function(){
$(this).remove();
if($('#tbl tr').length >= parseInt($('#rows').val())) u();
});
}
})();
}
});
});
Using this, you can reveal/hide any number of rows in a table with nifty little tail calling fade in and outs.
Of course, this was quickly hacked together and there's all kinds of optimizations that could be done.
Fiddle sample here