This is almost working but I am missing something. I am building an html table and I have JQuery. The idea is fairly simple. I have a list of names which will populate the first column of the table body. Next come two blank columns for some book keeping then a number of columns based on the number of days in the month of the date value passed into the function then a final bookkeeping column.
The general table structure is fine, the header and colgroups are fine. The thing that is biting me is the section of <td></td>'s in each body row that correspond the the days of the month. They are not showing up in the resulting table.
There are two loops. The first one builds the elements necessary to display the month day columns for the colgroup, header and body rows. Again, the colgroup and header bits are working. The $trb portion builds a single "row" of blank td elements that I hope to insert into each body row. The problem is $trb is not being appended/inserted to the body rows.
I'm not seeing this, ideas?
$(function() {
var list = ['11111 111', '2222 22222222', '3333333, 3333 3333333'];
buildMonthTable(new Date(), list);
function buildMonthTable(targetDate, list) {
var myDate = new Date(targetDate.getTime());
myDate.setDate(1);
myDate.setHours(0);
myDate.setMinutes(0);
myDate.setSeconds(0);
var lastDay = new Date(myDate.getTime());
var dayNames = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
var $table = $('<table>');
var $colGroup = $('<colgroup>');
var $thead = $('<thead>');
var $tbody = $('<tbody>');
var $trh = $('<tr>');
var $trb = $('<tr>');
$trh.append('<th>Name</th>');
$colGroup.append('<col class="colPlain colName"/>');
$trh.append('<th>Last Date</th>');
$colGroup.append('<col class="colPlain colRank"/>');
$trh.append('<th>Month Total</th>');
$colGroup.append('<col class="colPlain colTestDays"/>');
for (lastDay = new Date(myDate.getTime());
lastDay.getMonth() == myDate.getMonth();
lastDay.setTime(lastDay.getTime() + 86400000)) {
$trh.append('<th>' + lastDay.getDate() + '<br/>'
+ dayNames[lastDay.getDay()] + '</th>');
if (lastDay.getDay() % 2 == 0) {
$colGroup.append('<col class="colPlain colDay"/>');
} else {
$colGroup.append('<col class="colShade colDay"/>');
}
$trb.append('<td> </td>');
}
$trh.append('<th>Practice Days This Month</th>');
$colGroup.append('<col class="colPlain colTestDays"/>');
$table.append($colGroup);
$thead.append($trh);
$table.append($thead);
for (var i = 0; i <list.length; i++) {
var $bodyRow = $('<tr></tr>');
$bodyRow.append('<td>' + list[i]
+ '</td><td> </td><td> </td>');
console.log($trb);
$bodyRow.append($trb); // <===== this is not appending
$bodyRow.append('<td> </td>');
$tbody.append($bodyRow);
}
$table.append($tbody);
$("#content").append($table);
}
});
rafaelcastrocouto is correct, it is outputting... so I think you're problem is here:
var $bodyRow = $('<tr></tr>');
You want to have the tr tag at the top and close the tr at the bottom instead.
Also, I don't see your closing table tag either.
The trb is appending as you can see here
$trb.append($('<p>x</p>')); // this will make you see lots of "x" in your table
$bodyRow.append($trb); // <===== so this is appending
You should not append a tr(trb) inside another tr(bodyRow) the way you are doing and I guess you do not really want to do that rigth?!
Related
I have a table which looks essentially like this
<!DOCTYPE html>
<html lang="en">
<body>
<table class="ui table" id="items">
<tbody>
<tr data-toggle="fieldset-entry">
<td><input id="items-0-quantity" name="items-0-quantity" type="text" value=""></td>
<td><input id="items-0-description" name="items-0-description" type="text" value=""></td>
</tr>
</body>
</html>
Using javascript, I'd like to have a button which adds a new row to the table, and I'd like the inputs in that new row to have id="items-1-xxx", and name="items-1-xxx, i.e. where there's a 0 in the original row I'd like a 1 in the new row.
I can make a new table row by cloning the old one, but I have not figured out how to modify the name and id attributes of the input.
Here's a sketch of what I've tried:
function cloneRow() {
var table = document.getElementById("items");
var original_row = table.rows[table.rows.length - 1];
var new_row = original_row.cloneNode(true);
// We have a new row and now we need to modify it as
// described in the question. The only way I've found
// is to grab the inner HTML:
var cell_contents = original_row.cells[0].innerHTML;
// Now we could do a bunch of string parsing and manipulations
// to increment the 0 to a 1 and stuff the modified HTML into
// new_row, but it seems there must be a better way.
// Finally insert the new row into the table.
original_row.parentNode.insertBefore(new_row, original_row.nextSibling);
}
What is the right way to update the input elements' id and name?
You could just build a new <td> and assign document.querySelectorAll('#items tr').length as the x in items-x-...:
function addItem() {
var items = document.querySelector('#items')
, itemcount = items.querySelectorAll('tr').length
, newitemQuantityText = 'items-' + itemcount + '-quantity'
, newitemDescriptionText = 'items-' + itemcount + '-description'
, newitem = document.createElement('tr')
, newitemQuantity = document.createElement('td')
, newitemDescription = document.createElement('td')
, newitemQuantityInput = document.createElement('input')
, newitemDescriptionInput = document.createElement('input');
newitemQuantityInput.id = newitemQuantityText;
newitemQuantityInput.name = newitemQuantityText;
newitemQuantity.appendChild(newitemQuantityInput);
newitemDescriptionInput.id = newitemDescriptionText;
newitemDescriptionInput.name = newitemDescriptionText;
newitemDescription.appendChild(newitemDescriptionInput);
newitem.appendChild(newitemQuantity);
newitem.appendChild(newitemDescription);
document.querySelector('#items').appendChild(newitem);
}
document.querySelector('#add').addEventListener('click', addItem);
<button id="add">add item</button>
<table id="items"></table>
However using good old innerHTML reads way better:
function addItem() {
var items = document.querySelector('#items')
, itemcount = items.querySelectorAll('tr').length;
items.innerHTML += '<tr><td>' +
'<input id="item-' + itemcount + '-quantity" name="item-' + itemcount + '-quantity">' +
'</td><td>' +
'<input id="item-' + itemcount + '-description" name="item-' + itemcount + '-description">' +
'</td></tr>';
}
document.querySelector('#add').addEventListener('click', addItem);
<button id="add">add item</button>
<table id="items">
</table>
You can separately reconstruct the node itself by using
createAttribute()
createElement()
Fiddle: http://jsfiddle.net/ztb9gq3d/1/
This is not the data oriented approach the question asks for, but a reasonably simple solution is
numRows = table.rows.length;
// Use a regexp so we can replace all instances of the number
// corresponding to what is currently the last table row.
var re = new RegExp((numRows - 1).toString(), "g")
for (var i = 0; i <= originalRow.cells.length - 1; i++) {
var originalHTML = originalRow.cells[i].innerHTML;
var newHTML = originalHTML.replace(re, numRows.toString());
newRow.cells[i].innerHTML = newHTML;
}
Obviously this only works if the number we replace doesn't exist elsewhere in the HTML string, so this is not a particularly good solution.
However, we could use a more complex regexp.
This solution does have the advantage that we don't need to hard-code anything except the parts we want to replace into the regexp.
Therefore, if the HTML in the table were to acquire additional parts in future development this solution will still work, up to the quality of the regexp as already mentioned.
I've a form in which containing one <div> tag and the HTML within it. This is what I've when page loads. Then through AJAX I'm appending the same block(i.e. ) to the existing one. In every <div> tag there is one <table> and in that <table> I've a button with class products. After clicking on it I'm calculating the no. of rows present in that table only and assigning the id to the newly added row. But the issue I'm facing is when I add multiple such tables using AJAX and click on add button of any table it's calculating the total no. of rows present in all tables and adding that much no. of rows to the table in which I clicked add button. This shouldn't have to happen. It has to add only one row. I've created a jsfiddle for your reference. In fiddle I've put in static HTMl so it's working fine over there but on my local machine when I add multiple tables using AJAX I'm getting wrong no. of rows added.For example if I added three tables and click on add button of first table then it's adding four rows to that table. Why it's counting the total no. of rows present in all the tables present on a page?Is there any need to improve my script? My script is as follows:
$(document).ready(function() {
$('.products').click(function () {
var table_id = $(this).closest('table').attr('id');
var no = table_id.match(/\d+/)[0];
//var first_row = $(this).closest('table').find('tbody tr:first').attr('id');
var first_row = $('#'+table_id).find('tbody tr:first').attr('id');
var new_row = $('#'+first_row).clone();
var tbody = $('tbody', '#'+table_id);
var n = $('tr', tbody).length + 1;
new_row.attr('id', 'reb' + no +'_'+ n);
$(':input', new_row).not('.prod_list').remove();
$('select', new_row).attr('name','product_id_'+no+'['+n+']');
$('select', new_row).attr('id','product_id_'+no+'_'+n);
$('<button style="color:#C00; opacity: 2;" type="button" class="close delete" data-dismiss="alert" aria-hidden="true">×</button>').appendTo( $(new_row.find('td:first')) );
tbody.append(new_row);
$('.delete').on('click', deleteRow);
});
});
Following is jsFiddle link: http://jsfiddle.net/vrNAL/2/
I think what you mean to query is this:
var tbody = $('#' + table_id + ' tbody');
Instead of:
var tbody = $('tbody', '#' + table_id);
From the jQuery documentation, I don't think selectors work this way.
You are doing some strange things with the IDs here. why are you getting the IDs and selecting the sleemts with that, instead of using the selected elements directly?
Example:
var table_id = $(this).closest('table').attr('id');
var table = $("#" + table_id);
Is the same as just
var table = $(this).closest('table');
and
var first_row = $('#'+table_id).find('tbody tr:first').attr('id');
var new_row = $('#'+first_row).clone();
is the same as:
var new_row = table.find('tbody tr:first').clone();
What I'm trying to do is pretty simple: Add a 1x20 table of input cells inside a div.
I created a JavaScript function
var tableHTML = function(attributes, rows, columns)
{
var retHTML = "<table " + attributes + ">";
for (var i = 0; i < rows; ++i)
{
retHTML += "<tr>";
for (var j = 0; j < columns; ++j)
retHTML += "<td> </td>";
retHTML += "</tr>";
}
return (retHTML + "</table>retHTML");
}
to give me the HTML for a table with a specified dimensions and attributes. Then, in the body of my HTML, I put
<div class="inner_div" id="input_table">
<!-- div to house the table -->
</div>
<script type="text/javascript">
document.getElementById("input_table").innerHTML += tableHTML("id=\"input_table\" type=\"input\"", 1, 20);
</script>
which I thought would accomplish the task, but hasn't. I think this is because I'm trying to assign a string object to an HTML object. I kinda assumed that an implicit cast would be made. Anyways, I'm wondering if anyone has a "quick fix" to my problem. I would prefer not to redo my entire approach to the problem, but I also wouldn't mind someone informing me of the proper way to do the type of thing I'm trying to do -- using JavaScript to fill in page HTML on load.
Here's my take on this. I'm learning functional programming, so I do a bunch things here that might seem like their a waste of coding, but here's the concept:
Get the dimensions
Create a single row
Copy that row to make the table
After that return the table.
If you want to add id's, class's, etc... work with the DOM element returned by makeTable.
// Makes a single row
var makeRow = function(_columns) {
var row = document.createElement('tr');
var cell = document.createElement('td');
var cols = _columns;
while (cols) {
row.appendChild(cell.cloneNode(true));
cols--;
}
return row;
}
// Makes a table
var makeTable = function(_rows, _columns) {
var table = document.createElement('table');
var row = makeRow(_columns);
var rows = _rows;
while (rows) {
table.appendChild(row.cloneNode(true));
rows--;
}
return table;
}
I tried your code and it works: the table is generated and obviously empty
But be carrefull: if you do this, you will have two elements with the same ID (input_table)
I'm using jquery, as well as the CSVtoTable (plugin here: https://code.google.com/p/jquerycsvtotable/ ) plugin to convert large CSV files into tables that I can manipulate. I need to attach links relevant to each row.
I need to convert the text in one of these rows to add a link to a pdf. The problem is I can't seem to modify the strings. I'm using data like that found here: http://jsfiddle.net/bstrunk/vaCuY/297/
The file names generated by my system can't be easily edited, so I'm stuck using these formats:
423-1.pdf
So I need to convert two strings from tables formatted like so:
4/23/2013
1
to drop the year, as well as the slashes, and add a '-' and then the extra digit.
I'm able to grab the table data, I just can't seem to manipulate the variables with either the .replace or .substr
$(document).ready(function () {
$("tr td:nth-child(5)").each(function () {
var $docket = $('td=eq(5)');
var $td = $(this);
var $dataDate = $td.substr(0, $td.lastIndexOf("/"));
var $newDataDate = $dataDate.replace("/", "");
$td.html('<a html="./docs/' + $newDataDate.text() + '-' + $docket.text() + '.pdf">' + $td.text() + '</a>');
});
});
(edit): Sample table data:
<tr><td>13CI401111</td><td>22</td><td>Name1</td><td>Name2</td><td>4/23/2013</td><td>1</td></tr>
<tr><td>13CI401112</td><td>22</td><td>Name1</td><td>Name2</td><td>4/24/2013</td><td>2</td></tr>
First set the table id properly:
<table id="CSVTable">
Then use the right selector to select the 5th cell in each row:
$("#CSVTable tr td:nth-child(5)") //note that we need to tell Jquery to look for the cells inside `CSVTable` otherwise it will search the whole document
dollar sign is not required at the beginning of each variable and doesn't have any significance, you can remove it.
This wont work:
var $docket = $('td=eq(5)');
it's telling jquery to look for 6th cell but where? you should specify the parent like:
$("#CSVTable tr td:nth-child(6)");
but we only need the next cell to the one already selected in each function, so a better approach would be to use next() method which will select the next td directly:
$(this).next('td');
complete code:
$(document).ready(function () {
$("#CSVTable tr td:nth-child(5)").each(function () {
var td = $(this),
docket = td.next('td').text(),
dataDate = td.text(),
newDate = dataDate.substr(0, dataDate.lastIndexOf('/')).replace("/", '');
td.html('' + dataDate + '');
});
});
Demo
Bstrunk, try this :
$(function() {
$("tr").each(function () {
var $tr = $(this);
var $td_date = $tr.find('td').eq(4);
var $td_docket = $tr.find('td').eq(5);
var dateArr = $td_date.text().split("/");
$td_date.html('<a html="./docs/' + dateArr[0] + dateArr[1] + '-' + $td_docket.text() + '.pdf">' + $td_date.text() + '</a>');
});
});
I am wanting to have a series of dates (mainly Month, Day, Year) displayed within a vertical arrangement of table cells on a web page. The first date needs to be the current date minus one day, with the next date in the sequence be the current date, The remaining dates need to incrementally be one day in future out to 16 days.
Can someone provide help me figure out how to do this? I have looked at and understand a Javascript to manipulate and display a single date (add or subtract) but am unable to get that date in a cell as well as figure out how to display the other multiple dates mentioned above in a HTML table.
Try this:
HTML
<table id="myTable"></table>
JavaScript
var table = document.getElementById('myTable')
var myDate = new Date();
myDate.setDate(myDate.getDate() - 1)
for(var i = 0; i < 16; i++)
{
var row = document.createElement('TR');
var cell = document.createElement('TD');
cell.innerText = myDate.getDate() + "/" + (myDate.getMonth() + 1) + "/" + myDate.getYear();
myDate.setDate(myDate.getDate() + 1)
row.appendChild(cell);
table.tBodies[0].appendChild(row);
}
Did you try myDate.toString() or myDate.toDateString()?
What you need to do is have some variables holding a date... Like this
var myDate = new Date();
Put whatever date in it that you fancy, then do this.
myDate.toDateString()
You can create your table in a loop in javascript and fill it with dates.
Did this help?
Option 1:
You can use write the output into the document like:
<table>
<tr>
<td><script type="text/javascript">document.write(mydate);</script></td>
...
</tr>
Option 2: generate the markup in javascript and then inject it into the DOM:
var markup = '<table>\
<tr>\
<td>' + mydate + '</td>\
</tr>\
...
</table>';
document.getElementById('contentDiv').innerHTML = markup;
Where you have a div element in your page:
<div id="contentDiv"></div>