I am using a html table that contains available times for scheduling. I want the user to be able to click on a time and from that be able to get the column header, which is the staff persons name, and the value of the cell - the time. I than want to change the contents of the cell to 'NA' and set the cell background to some color. I have been playing with this for awhile with no luck. I am new to javascripts and jquery. Any help would be greatly appreciated.
This should be a doable jquery task as long as you have the appropriate selectors. So you need a way to associate each time cell with a header cell. To do this i would add a user id to the cells in the header and the body:
<th class="header" id="1">Bob</th>
<td class="selectable" id="10" name="1">10:00 AM</td>
Then for the jquery:
$("table#timetable tbody tr td").click(function(){
var user_id = $(this).attr('name');
var user_name = $("table#timetable thead tr th#" + user_id).html();
var time = $(this).attr('id');
$(this).html('N/A');
$(this).css('background':'#990000');
alert(user_id + ' ' + user_name + ' ' + time);
});
Related
What I'm trying to do:
Get every value from a spreadsheet (6 columns, ~10+ rows)
I can get the values. I will probably get each column individually with .getRange(row, column, sheet.getLastRow() - 1, 1).getValues();. Or I could get every single value with .getDataRange().getValues() and then put them in the table that way?
Or would it be better to just use a for loop? -- example at very bottom
Return those values [as Templated HTML?] surrounded by <table>, <tr>, <th>, <td> code -- example below
Display the table with the values on a web app when a name gets
clicked
Can the inserted <table> code start as style="display: none;", and then when the name gets clicked, have the table show? Or have it in a div that is invisible then visible once clicked?
Example of table:
<table>
<tr>
<th>header1</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
<th>header6</th>
</tr>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
<td>value4</td>
<td>value5</td>
<td>value6</td>
</tr>
//etc
</table>
I dont know if what I'm trying to do counts as Templated HTML or not, or if it would be better to do this using Templated Html...
The big thing I need help with is returning every value in a table and displaying it on the web app.
Example of for loop
If I do a for loop and return every value in a column or a row
column1[i]
column2[i]
etc
or
row1[i]
row2[i]
etc
How would I return those values as a table?
Would it be something like:
var x = "<tr>";
var y = row1[i];
var z = "</tr>";
return x + y + z
If so, how would I make a whole table out of all the row/column values?
Also, how would I style the table with css once it's fully built? I'm assuming I can still add an id to the table and style it from there.
I don't know the exact number of rows there will be in the spreadsheet, so making this dynamic would be best -- probably getting all the rows instead of columns and using a for loop for each row?
Any help would be appreciated. Thanks.
If I wanted to add another column to the table (not in the spreadsheet), how would I go about doing that? I'm trying to add an add row button to the header row, and a delete row button on the end of every row of table data.
Also, I know that you can set the <td> to <td contenteditable='true'>... but, how would I have it where the data is only editable on a newly added row AND the table cell cant be edited once a value is submitted? -- Would I need an event listener or some trigger that sees when a value is inputted and triggers that cell to contenteditable='false'?
Thanks again.
You can use a nested for loop.
var range = SpreadsheetApp.getActiveSpreadsheet().getDataRange().getValues();
var isHeader = true;
var html = "<table>\n";
for (var i = 0; i < range.length; i++) {
html += "<tr>\n";
for (var j = 0; j < range[i].length; j++) {
if (isHeader) {
html += "<th>" + range[i][j] + "</th>\n";
}
else {
html += "<td>" + range[i][j] + "</td>\n";
}
}
isHeader = false;
html += "</tr>\n";
}
html += "</table>";
I've a PHP file which is a view (so mainly HTML) composed of several tables.
When the user click on one of the button, I want that the variables that are into my cells (and into the correct table) are sent to a Table in my Database.
To do this i'll use AJAX later, but at the moment i've a problem using JS/Jquery.
So I did something like this :
$('.boutton').click(function(){
$(?).find('td input').each(function(){
console.log($(this));
console.log($(this).val());
var iValue = $(this).val();
var sAllId = $(this).attr('id');
var sName = $(this).attr('name')
});
});
My table and buttons are into a div which has as id "table" + the number of the table.
I don't know what to do since I want this to work on every table, and on every button. It has to select only the td input that is into the table where the button was clicked.
My HTML is into a variable $sHtml since everything in this table are made of datas (in my DB) but it should be something like this :
<table id = "domaine-1-south">
<tr>
<th>BlaBla</th> // Several times
</tr>
<tr>
<td>Blabla</td>
<td><input id = "1#1#1#" name="high"></td>
<td><input id = "1#1#1#" name="mid"></td>
<td><input id = "1#1#1#" name="low"></td>
</tr>
<tr>
<td>Blabla</td>
<td><input id = "1#1#2#" name="high"></td>
<td><input id = "1#1#2#" name="mid"></td>
<td><input id = "1#1#2#" name="low"></td>
</tr>
For the id 1#1#1# the last 1 is for the number of the line and the second one is for in which table I'm.
You could use "start with" selector ^= to select all tables that have an id start with table :
$('[id^="table"]').find('td input').each(function(){
But in your OP you want to select the specific table related with the clicked button .boutton, so i guess that you have this button inside the table so you could select the current table using :
$(this).closest('table[id^="table"]').find('td input').each(function(){
Hope this helps.
If I append rows to my table like this:
$('#tbody_upload').append('<tr id="' + data.originalFiles[counter].name + '"><td>' + 'Uploading...' + '</td><td></td><td></td><td></td></tr>');
how can I remove it from another event?
$('#' + this.name).remove();
that function doesn't work, also appended items don't appear in source of the page.
If you want remove the element that triggers the event to be removed (as appears from this.name) you can simply do
$(this).remove();
Maybe you should name your table and then with a selector select the body and first errase it and then append data so every time you get new data, the table deletes the old data and puts the new one.
<table id="yourtableName" border="1" class="hoverTable">
<thead>
</thead>
<tbody>
</tbody>
</table>
var gridBody = your tr code;
$('#yourtableName tbody').empty().append(gridBody);
Using jQuery, I append rows to a table and each row contains an anchor tag. The jQuery is then supposed to add in a link to the anchor tag but the links do not show up. The other data (e.g., date, location) fills in fine so I'm not sure what the issue is.
jQuery:
for (var i = 1; i <= 20; i++) {
...
$('.recent-reports tbody').append('<tr><td></td><td></td><td><a class="js-pdf-download" href="">Download</a></td></tr>');
$('.recent-reports tbody tr:last').find('td').eq(0).text(date)
.find('td').eq(1).text(location)
.find('.js-pdf-download').attr("href", link)
...
}
HTML:
<table class="recent-reports">
<thead>
</thead>
<tbody>
</tbody>
</table>
Thanks to Johann found a fix while simplifying my code at the same time. Rather than appending a row to the table and then adding in the data, I now append the row with the data in one fell swoop.
$('.recent-reports tbody').append('<tr><td>' + date + '</td><td>' + location + '</td><td><a class="js-pdf-download" href="' + link + '" target="_blank">Download</a></td></tr>')
Also, a clumsier solution, but one that would have been in line with my original approach:
...
$('.recent-reports tbody tr:last').find('td').eq(0).text(date)
$('.recent-reports tbody tr:last').find('td').eq(1).text(location)
$('.recent-reports tbody tr:last').find('.js-pdf-download').attr("href", link)
...
I have a html table that I reorder based on a CSV list of custom attribute values that I have for each table row. I am using the following function to do it:
for (var i = 0; i < arrCSV.length; i++)
{
$('#' + tableId)
.find('[fname = ' + arrCSV[i] + ']')
.eq(0)
.parents('tr')
.eq(0)
.appendTo('#' + tableId);
}
The table structure is:
<table>
<tr>
<td fname='f1'>something here</td>
</tr>
<tr>
<td fname='f2'>something here</td>
</tr>
</table>
The CSV could be something like this "f2, f1"
I find this is very very slow performing function. Any help in optimizing it is really appreciated.
EDIT:
Based on the article at http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly, one can achieve the greatest boost in performance by calling append only once with the html concatenated string. Can someone help in using this technique to my problem? I am not sure how to go about getting the s HTML in the for loop and appending it once.
I would suggest finding the elements as few times as possible. Store all the matching rows into a "hash" using the attribute value of interest as the key. Go through your CSV, pick the corresponding row out of the hash, push it into an array, then finally append the elements of the array to the table using the jQuery object previously found.
var table = $('#' + tableId);
var rowHash = {};
table.find('[fname]').each( function() {
rowHash[$(this).attr('fname')] = $(this).closest('tr');
});
var rows = [];
for (var i = 0; i < arrCSV.length; ++i)
{
var row = rowHash[arrCSV[i]];
if (row) {
rows.push(row);
}
}
$(rows).appendTo(table);
EDIT: This seems like a slight improvement to my previous code where I was appending each row to the table as it was found. I tested on a table with 1000 rows and it seems to take about 1sec to sort a table that needs to be completely inverted.
If you want to append html only once (like that learningjquery.com article), try following:
$(document).ready(
function()
{
var arrCSV = ['f2', 'f1'];
var tableId = 'mainTable';
var newTable = [];
for (var i = 0; i < arrCSV.length; i++)
{
var row = $('#' + tableId)
.find('[fname = ' + arrCSV[i] + ']')
.eq(0)
.parents('tr')
.eq(0);
newTable.push(row.html());
}
$('#' + tableId).html(newTable.join(''));
};
});
Live version: http://jsbin.com/uwipo
Code: http://jsbin.com/uwipo/edit
Though I personally feel that you should profile your code first and see if it's append which is slow OR that 'find' method call. I am thinking that for a huge table, using 'find method' to find a custom attribute could be slow. But again, there is no point in any guesswork, profile the code and find it out.
If the 'find' method is slow, will it be possible to use id attribute on td instead of giving custom attribute.
e.g.
<table>
<tr>
<td id='f1'>something here</td>
</tr>
<tr>
<td id='f2'>something here</td>
</tr>
</table>
Then your code to find the parent row could be as simple as:
('#' + arrCsv[i]).parent('tr')
EDIT: As pointed out by tvanfosson, this code assumes that arrCSV contains attribute for all the rows. The final table will only contain those rows which are present in arrCSV. Also, this code does not copy 'thead', 'tfoot' section from the original table, though it should be easy to write code which does.
You may have to rethink your algorithm.
Without changing the algorithm, a slight optimization would be:
var $table = $("#" + tableId);
for (var i = 0; i < arrCSV.length; i++)
{
$('[fname = ' + arrCSV[i] + ']:first',$table).closest('tr').appendTo($table);
}
Wait a second...
$('#' + tableId)
Get #myTable
.find('[fname = ' + arrCSV[i] + ']')
Find anything with an attribute of fname equal to i
.eq(0)
Give me the first item of the previous expression
.parents('tr')
Find the parents of type TR
.eq(0)
Give me the first in the previous expression
.appendTo('#' + tableId);
Add that TR to #myTable
Okay. Now that I've broken it down - are you duplicating a Table Row only? If so, the .append() isn't your problem, your choices of selectors is. To further compound my confusion here, the only tags with an attribute of fname are your TR's, so why are you going to their parents() and seeking out the first TR? You're basically asking for TR tags to be placed within TR tags - but that isn't what your Markup example shows.