I have HTML table. I get data from Firebase and append that data to my HTML table, with classes.
I'm trying to figure out how to select that appended data on my HTML and update values, because my values changes by time (I do some math with time).
I know the way to select using on.('click'), but I would like to select it and update it without any click events.
var frequency = snapshot.val().frequency;
var recordKey = snapshot.key;
var minsAway = frequency - (firstCurrentDiff % frequency);
var nextArrival = moment().add(minsAway, "minutes").format("HH:mm")
var row = $("<tr>").attr("class", recordKey);
row.appendTo("#tableBody");
$("<td>" + frequency + "</td>").appendTo(row);
$("<td>" + nextArrival + "</td>").appendTo(row);
$('<td class="mins-away">' + minsAway + "</td>").appendTo(row);
If i get what you need, after append, you can get it with :last
row.appendTo("#tableBody");
$myrow = $("#tableBody tr:last");
And then, for ex, refer to each td or find specific one:
$td_mins_away = $myrow.find('td.mins-away');
Related
I'm working on a small project where I am wanting to randomly pull one row of a google sheet, and then use that data in an HTML table.
For now, my solution has been first to use javascript to make a random number, then generate an HTML table from google sheets for just that row using this method. So, I end up with a URL for an HTML table with just header row, and a random row of data, similar to this. Then I just embed that table as an object in my HTML page. This is the gist of it:
< script >
window.onload = function() {
var albumno = Math.random() * 408;
var albumno = Math.round(albumno);
var albumurl = "https://docs.google.com/spreadsheets/d/UNIQUE-DOCUMENT-ID/gviz/tq?tqx=out:html&tq=SELECT%20B%2C%20D%2C%20E%2C%20F%2C%20G%20WHERE%20A%20MATCHES%20%27" + albumno + "%27&gid=1739065700";
document.getElementById("output").innerHTML = "ALBUM NUMBER: " + albumno + ".";
document.getElementById("albumpath").innerHTML = '<object align="middle" data="' + albumurl + '">';
};
</script>
There are two major drawbacks. First, the table cannot be (easily) formatted when embedded as an object. Second, my google sheet is a list that is added to weekly, and therefore I have to manually adjust the limits of the random value generated in my javascript.
Is there a way to do this more effectively in Javascript? Perhaps by scraping the full table, and then randomly selecting a row of data, which can be used in an proper HTML table (i.e. not embedded as an object)? Or maybe there exists a google sheets API that would help me?
UPDATE:
I have managed to write a quick function in Google Apps Script that picks the random row of data. I have figured two ways to output the data, option 1 as an array, or option 2 as HTML code for a table. Now how do I call this function in my HTML page, and make use of these data?
}
function randomalbum() {
//get spreadsheet
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/[DOCID]/edit#gid=1');
var sh = ss.getSheetByName("Pick List");
//find last album
var Fvals = sh.getRange("F:F").getValues();
var Flast = Fvals.filter(String).length;
var colnum = sh.getRange(2, 1, Flast).getValues();
var albumlast = Math.max.apply(null, colnum)-1;
//pick random row (note the row an album is in is 1 more than the album no.)
var rowrand = Math.round(Math.random()*(albumlast+1));
//extract data of interest
var albumrand = rowrand -1;
var pick = sh.getRange(rowrand, 5).getValues();
var artist = sh.getRange(rowrand, 6).getValues();
var title = sh.getRange(rowrand, 7).getValues();
//make array (option 1)
var array = [albumrand, pick, artist, title];
return array;
//make HTML string (option 2)
var HTMLString = " <table style='width:100%'>"
+ "<tr>"
+ "<th>Album No.</th>"
+ "<th>Picked By</th>"
+ "<th>Artist</th>"
+ "<th>Artist</th>"
+ "</tr>"
+ "<tr>"
+ "<td>" + albumrand + "</td>"
+ "<td>" + pick + "</td>"
+ "<td>" + artist + "</td>"
+ "<td>" + title + "</td>"
+ "</tr>"
+"</table>"
HTMLOutput = HtmlService.createHtmlOutput(HTMLString);
return HTMLOutput
}
Using a Google Sheets API without needing to run your own server: I remember following the suggestions in the following article to solve this a while ago.
https://coderwall.com/p/duapqq/use-a-google-spreadsheet-as-your-json-backend
You'll probably need another service to add CORS headers to the Google response because cors.io apparently no longer exists.
If you want to publish a web app out of the HTMLOutput returned by your function, you can do the following:
Rename your function to doGet: if you do this, Apps Script will run this function whenever a user visits the URL of the web app you are about to publish, as you can see here.
Remove the return array; in your code: the keyword return finishes current function, so the code will never return an HTMLOutput, and an array of values is not a valid object to return in this situation.
Publish the script as a web app: in your script editor, select Publish > Deploy as web app. Then select a Project version, choose under whose authorization the app should run and who should have access to it, and click Deploy. A URL will show app as Current web app URL. If you access that URL, you will see the HTML you created.
I hope this is of any help.
I have module appending the result of response to the other table. looking forward I found a solution in my module. however I found problem on that i will give to you guys the scenario what the problem it does.
First Scenario:
User will choose what condiment he wanted to click, Looking forward Ex. User 1 choose the Second table row, the Condiments *LG FRIES.
Second Scenario:
In the first scenario user choose the *LG FRIES, as you can see here modal will open and the result of response will append to the table B.
Third Scenario: Well First and Second scenario look works and good, but here I will show you, how does appending will multiply in the table once i force double click the table row of *LG FRIES.
So now i will let you show my codes.
This is my function for getting the result of clicking the of table row then the result will append to the table B.
$('table#noun_chaining_order').on('click','tr.editCondiments',function(e){
var allow_to_open_condiments_conditional = $(this).closest("tr").find(".allow_to_open_condiments_conditional").text();
if(allow_to_open_condiments_conditional == 'Yes') {
$('.conditional_table_hidden_noun').hide();
$('.conditional_table_hidden_condiments').show();
$('table#noun_chaining_order tr').removeClass('selected');
$(this).addClass('selected');
var find_each_id_condiments = $(this).find('td.condi_section_id').text();
$("table#customer_table_update_chain_order tbody").html('');
$('#customer_modal_update_chain_order').modal('show');
$.ajax({
url:'/get_each_id_section_condiments',
type:'get',
data:{find_each_id_condiments:find_each_id_condiments},
success:function(response){
var get_each_section = response[0].condiments_table;
$.each(get_each_section, function (index, el) {
var stringify = jQuery.parseJSON(JSON.stringify(el));
var cat_condi_screen_name = stringify['cat_condi_screen_name'];
var cat_condi_price = stringify['cat_condi_price'];
var cat_condi_image = stringify['cat_condi_image'];
var image = '<img src=/storage/' + cat_condi_image + ' class="responsive-img" style="width:100px;">';
// $('#edit_chainingBuild').append("<tr class='clickable-row'><td>" + Qty + "</td><td class='clickable-row-condiments'>" + Condiments + "</td><td>" + Price + "</td><td style='display:none;' data-attribute-chain-id="+menu_builder_details_id +" class='data-attribute-chain-id'>"+menu_builder_details_id+"</td></tr>");
$('table#customer_table_update_chain_order tbody').append("<tr class='edit_condimentsClicked' style='font-size:14px; border:none;'><td class='edit_condimentsScreenNameClicked'>" + cat_condi_screen_name + "</td><td class='edit_condimentsScreenPriced'>" + cat_condi_price + "</td><td>"+image+"</td></tr>");
});
},
error:function(response){
console.log(response);
}
});
}
else
{
}
});
So the question will be, How to stop appending multiple times once I force double click the table row?
I see simple solutions here.
When you appending cart item, you can add that item ID from database
to the element. And before appending check if an item from response
doesn't exist in BODY.
Another solution will be just after you click append - hide that CTA
(button)to prevent it from another click.
Check your database for multiple records.
Anyways, please check when you do ajax request? after click?
Have you tried to debug your code with breakpoints? or console?
I created a note-taking front end page which saves the data from text field into the localStorage. The problem occurs when the user deletes one field using the Delete button, which corresopndents to DeleteT function.
For example if we have three textareas with id txt1, txt2, txt3 they apper with the sames names in the localStorage. After the user deletes for example txt2 using the Delete button, in the local Storage the left ones are txt1 and txt3 but on the next reload there are two textareas with id txt1 and txt2 because in the localStorage the number of textareas is saved by key AllNum. The data from txt3 in the localStorage should go to txt2 in the DOM on the page.
The problematic functions:
// Deletes textelemnt
function DeleteT(num) {
localStorage.removeItem("txt" + num);
localStorage.removeItem("h" + num);
console.log('del');
i=i-1;
var now = localStorage.getItem("AllNum");
if((now-1)<0){
now=0;
localStorage.setItem("AllNum", (0));
}else{
localStorage.setItem("AllNum", (now-1));
}
$("div.textarea" + num).remove();
}
//Loads all the text elemnts with a for loop until the number of areas is reached
function load() {
if (document.getElementById("alltxt").childElementCount < localStorage.getItem('AllNum')) {
for (var i = 1; i <= localStorage.getItem('AllNum'); i++) {
$('#alltxt').append('<div class="textarea' + i + '"><input onkeyup="save()" id="h' + i + '"></input><textarea onkeyup="save()" id="txt' + i + '"></textarea></br><button onClick="cut(txt' + i + ')" class="f b">Cut</button> <button onClick="copy(txt' + i + ')" class="f b">Copy</button> <button onClick="speak(txt' + i + ')" class="f b">Speak</button> <button onClick="download(' + i + ')" class="f a">Save</button><button onClick="textFull(' + i + ')" class="f">Fullscreen</button> <button onClick="DeleteT(' + i + ')" class="f">Delete</button> </div>');
document.getElementById('txt' + i).innerHTML = localStorage.getItem("txt" + i);
document.getElementById("h" + i).setAttribute('value', localStorage.getItem("h" + i));
}
}
}
https://codepen.io/abooo/pen/NoqOXX?editors=1010
To experience the problem create three textareas using the + button. Then Enter data in the them. After this delete the latter. Finally reload the page and make sure the two textreas appeared. You can see the data from the second one is missing replaced with null value. How to fix this issue?
The result
LocalStorage values
The value "AllNum" only stores total number of items; it does not contain any information about which items were there before reloading. So in first load, if you add 3 items and remove the 2nd, your local storage will have "AllNum" equal 2, and the next time it loads, your load() function will iterate from 1 to 2, looking for data of text1 and text2. That's why only 1st item displays correctly.
Another problem that you might notice after fixing the above issue is that the iteration is not good for unique id; a simple test can prove it: you add 3 items, remove the 2nd - now you have text1 and text3 in localStorage, and AllNum is 2. If you add one more, the newest item will have id as 3 and all its data will be written on top of the existing text3 and h3.
2 suggestion for your code:
Use something else as unique id instead of iteration number. Use Math.random(), for example.
Store all your unique ids in localStorage, not AllNum. Rewrite your code to add and delete unique ids from localStorage.
A small example of how to modify the 2 function add() and save():
function add() {
var newId = Math.random();
// your render logic here. Replace i with newId
save(newId);
}
function save(newId) {
localStorage.setItem("txt" + newId, document.getElementById('txt' + a).value);
localStorage.setItem("h" + newId, document.getElementById('h' + a).value);
var allIds = JSON.parse(localStorage.getItem('AllIds'));
allIds.push(newId);
localStorage.setItem("AllIds", JSON.stringify(allIds));
}
I have html table on my parent page that has some data:
Begin Date End Date City
03/28/2017 Toronto
03/25/2017 03/26/2017 Miami
03/22/2017 03/24/2017 Chicago
03/16/2017 03/21/2017 Dallas
03/10/2017 03/15/2017 Austin
After use update the element from specific row I would like to replace entier content of that row. Each row had unique id. I have to do this with plain JavaScript Vanilla. Here is my example what I have so far:
fnObj.DATA is numeric and I get that after my ajax call is successfully completed. I use the id from that callback function to detect the row that I want to update. I'm not sure what is the best technique to replace all the td tags. This technique works with one exception. There is no id on the row that I have replaced the data. If anyone knows better way to do this please let me know. Thank you.
window.parent.document.getElementById("New_"+fnObj.DATA).outerHTML = "<td>"+document.getElementById("newBegDt").value+"</td><td>"+document.getElementById("newEndDt").value+"</td><td>document.getElementById("newCity").value</td>";
window.parent.document.getElementById(dType+"_"+fnObj.DATA).id = 'New_'+fnObj.DATA;
Try this:
var newtr = "<tr id='" + "New_"+fnObj.DATA + "'><td>"+document.getElementById("newBegDt").value+"</td><td>"+document.getElementById("newEndDt").value+"</td><td>" + document.getElementById("newCity").value + "</td></tr>";
$("#New_"+fnObj.DATA ).replaceWith(newtr);
If you don't want to use jquery you can use something like:
var currentTr = document.getElementById("New_"+fnObj.DATA), parent = currentTr.parentNode,
tempDiv = document.createElement('div');
tempDiv.innerHTML = "<tr id='" + "New_"+fnObj.DATA + "'><td>"+document.getElementById("newBegDt").value+"</td><td>"+document.getElementById("newEndDt").value+"</td><td>" + document.getElementById("newCity").value + "</td></tr>";
var input = tempDiv.childNodes[0];
parent.replaceChild(input, currentTr);
function grid(rows, cols) {
var table = "<table id = \"myTable\">";
var size = (1 / rows * 525) + "px";
for (i=0; i<rows; i++) {
table += "<tr>";
for (j=0; j<cols; j++) {
var ID = i+','+j;
table += "<td id = \"ID\" >"+"</td>";
}
table += "</tr>";
}
table += "</table>";
var ID2 = randomFunction(rows, cols);
alert(ID2);
document.ID2.style.color = "red";
//document.getElementById(ID2).style.color = "#ff0000";
//table1.rows[1].cells[0].style.backgroundColor = "#003F87";
//id.style.backgroundColor='#003F87';
$("#container").empty().append(table);
}
I have generated table dynamically in javaScript specifying number of rows and columns. I have given id to each cell. I need to change the color of particular cell whose id is generated by random function. I tried in different ways but no solution.
One by one:
document.getElementById(ID2).style.color = "#ff0000";
won't work, because at this moment, the table is not in the dom, so document.getElementById(ID2) will return nothing.
table1.rows[1].cells[0].style.backgroundColor = "#003F87";
won't work, because table is a regular string, and strings don't have a rows property.
id.style.backgroundColor='#003F87';
won't work because id is again, a simple string. What would work is, to add the table to the dom first, using $("#container").empty().append(table);, and then do the setting of the color, using straightforward
document.getElementById(ID2).style.backgroundColor = "#ff0000";
or with jquery:
$("#"+ID2).css({backgroundColor: "#ff0000"}).
I would also recommend inserting a space ( ) in the table cells (note that your current code is incorrect, it sets the id for all the cells to the string "ID"), using
table += '<td id = "'+ID+'"> </td>';
otherwise the table could be rendered a little odd. Also id in the format 1,2 might cause problems, how about
var ID = 'td_'+i+'_'+j;
which gives you an ID like td_1_2, which won't mess up any browser.