Jquery not adding index to last row when creating a new row - javascript

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);
};

Related

Javascript filter on html table does not work if it is injected to div. if table is loaded with page it works

I want to filter out table before loading it to reduce it's size that it would load faster, when its loaded i would like to let user to filter it. I am using public CDN script for filter part, but it does not work on content which is injected to . It only works if whole table is loaded together with page.. what i'am doing wrong?
Jsfilter: <script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tablefilter/2.5.0/tablefilter.js"></script>
DetailedRport.html
//this function called on button click it gets user and date to resize data set
<script type="text/javascript">
function myFunction() {
var y = document.getElementById("month-input").value;
var z = document.getElementById("email2").value;
//here is called server side script
google.script.run.withSuccessHandler(onSuccess).functionToRunOnFormSubmit(y, z);
}
//Resized data set gets injected to tbody
function onSuccess(c){
var table=toHTMLTable(c);
document.getElementById('myOutput1').innerHTML = table;
}
//Array to HTML table
function toHTMLTable(a) {
var content = a.map(function(row, i) {
var rowHTML = row.map(function (col) {
return "<td>" + col + "</td>";
}).join("");
return "<tr>" + rowHTML + "</tr>";
}).join("");
return content;
}
</script>
//user selects criteria for data table
<b> Report for:</b>
<select value="" name="email2" id="email2" width="300" autofocus="autofocus" autocorrect="off" autocomplete="off">
<?!= myEmails(); ?>
</select>
<b>Pick Period :</b>
<select name="Student" id="month-input" autofocus="autofocus" autocorrect="off" autocomplete="off">
<?!= myDates(); ?>
</select>
//On click table is loaded based on selection
<input type="button" value="Load Data" class="loadbutton" onclick="myFunction();" >
<br><br>
//Js tablefilter which should work but does not if table is injected
<table id="table1"class="mytable TF" cellspacing="0" cellpadding="0">
<thead>
<tr class="header">
<th style="width:5%;">TASK</th>
<th style="width:20%;">PROJECT</th>
<th style="width:30%;">DATE</th>
<th style="width:10%;">TIME SPENT</th>
<th style="width:10%;">WORDCOUNT</th>
<th style="width:10%;">SPEED</th>
</tr>
</thead>
//Where data table is injected
<tbody id="myOutput1">
</tbody>
</table>
//Setting Js tablefilter source http://tablefilter.free.fr/
<script language="javascript" type="text/javascript">
var tf = setFilterGrid("table1");
</script>
server.gs
// here data set gets filtered based on users selection and is sent back
// Using ArrayLib library
function functionToRunOnFormSubmit(y,z) {
var ss = SpreadsheetApp.openById(id);
var ActiveSheet = ss.getSheetByName("TogglMap");
var StartRow = 2;
var RowRange = ActiveSheet.getLastRow() - StartRow + 1;
var EMWholeRange = ActiveSheet.getRange(StartRow,2,RowRange,13);
var AllValues = EMWholeRange.getDisplayValues();
var dat = y +'-01'
var removeCol = function(arr, colIndex, colIndex2) {
for (var i = 0; i < arr.length; i++) {
var row = arr[i];
row.splice(colIndex, colIndex2);
}
}
removeCol(AllValues, 5 , 6);
var filteredArr1 = ArrayLib.filterByText(AllValues, 1, z)
var filteredArr2 = ArrayLib.filterByText(filteredArr1, 3, dat)
removeCol(filteredArr2, 1 ,1);
Logger.log(AllValues)
return filteredArr2
};
My goal is working JS filter

How do you clear a specific JSON object in a JSON array within localStorage by a delete button?

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));

How do I sort table from dropdown list

How do I create a simple sorting function for this. I know there is plugin like tablesorter. But it doesn't sort it from a dropdown list. Or is the plugin can be modified so that it can sort from a dropdown list. Thank you in advance.
HTML:
<form action="#" method="post">
<input type="text" id="UserID" name="UserID" readonly="readonly">
<input type="text" id="UserName" name="UserName" placeholder="Name">
<input type="text" id="UserOccupation" name="UserOccupation" placeholder="Occupation">
<button type="button" name="button">Add</button><br>
</form>
Sort By:
<select>
<option>ID</option>
<option>Name</option>
<option>Occupation</option>
</select>
<table id="table" class="tablesorter">
<thead>
<tr >
<th>ID</th>
<th>Name</th>
<th>Occupation</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Javascript:
$(document).ready(function() {
//Set id field to 1
var id = $('#UserID');
id.val("1");
//Add 1 to the id in textbox
function incID(){
var str = id.val();
var int = parseInt(str);
var idVal = int + 1;
id.val(idVal.toString());
}
//When button clicked
$('button').on('click', function(){
//create a new object
var obj = new Object();
//pass value dynamically from input box
obj.id = $('#UserID').val();
obj.name = $('#UserName').val();
obj.occupation = $("#UserOccupation").val();
//display data to the table
var addrow = "<tr><td>" + obj.id + "</td><td>" + obj.name + "</td><td>"+ obj.occupation +"</td></tr>";
$("table tbody").append(addrow);
//Add 1 to id field
incID();
});
});
Sorting the table is fairly easy to do yourself, all you'd have to do is sort the rows using javascript's sort method (http://www.w3schools.com/jsref/jsref_sort.asp) and re-adding the rows to the table.
You could create sorting methods for different data-types like:
function sortByNumber(rows, selector, ascending) {
rows.sort(function(a, b) {
var numberA = parseInt($(selector, a).text(), 10);
var numberB = parseInt($(selector, b).text(), 10);
if (ascending)
return numberA - numberB;
else
return numberB - numberA;
});
return rows;
}
function sortByText(rows, selector, ascending) {
rows.sort(function(a, b) {
var textA = $(selector, a).text();
var textB = $(selector, b).text();
if (ascending)
return textA.localeCompare(textB);
else
return textB.localeCompare(textA);
});
return rows;
}
(working example at https://jsfiddle.net/kg000ta7/)
However, if you plan to have a lot of rows or columns in your table, a plugin like tablesorter will probably perform better.
According to the documentation you are able to manually sort tablesorter by triggering the 'sorton' event: http://tablesorter.com/docs/example-trigger-sort.html
$('select').on('change', function() {
var sorting;
switch (field) {
case 'ID':
sorting = [[0,0]];
break;
case 'Name':
sorting = [[1,0]];
break;
case 'Occupation':
sorting = [[2,0]];
break;
default:
console.error('Undefined sort field ' + field);
break;
}
$("table").trigger("sorton",[sorting]);
return false;
});

jquery clone select element within a <tr><td>

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>

I need the id and name of inner element when cloning a row of a table with javascript

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)

Categories

Resources