I have an HTML table with the id "roster1" that allows users to add table rows with a button click, and I am attempting to save the table state via a "Save" button that runs the following piece of code:
function saveRoster () {
localStorage.setItem('rosterPd1','');
var roster = document.getElementById ('roster1');
localStorage.setItem('rosterPd1', roster);
}
If I input some static value into 'rosterPd1', then I can use the information written to localStorage with no problem. However, when I attempt to save the table by using the above code, I get [object HTMLTableElement] returned... which is CORRECT, but not particularly useful!
Can someone point me in the right direction on what I would have to do to get localStorage to save the contents of the table itself?
You can only save Strings to Storage, but it seems for what you're trying to do, innerHTML will suffice;
function saveRoster() {
var roster = document.getElementById('roster1');
if (!roster) return; // not found
localStorage.setItem('rosterPd1', roster.innerHTML); // store innerHTML
}
function loadRoster() {
var roster = document.getElementById('roster1');
if (!roster) return; // not found
roster.innerHTML = localStorage.getItem('rosterPd1'); // get+apply innerHTML
}
As for why you're getting [object HTMLTableElement], this is what happens when you call toString on a JavaScript reference to a <table>.
document.createElement('table').toString() // "[object HTMLTableElement]"
Related
For this project, I want to change the logic written in jquery with that in js vanilla.
My code looks like this
Based on the information from the input using the event keydown,
I call a function through which I do a search in api.
var selectedUsers = [] //empty array
$('#userSearchTextbox').keydown((event)=>{
var textBox = $(event.target);
var value = textBox.val();
//Function which search in api
searchUsers(value);
});
//Search in array function
function searchUsers(searchTerm){
$.get("/api/users",{search:searchTerm},results =>{
outputSelectableUsers(results,$('.resultsContainer'));
});
}
After I call another function outputSelectableUsers
which will call 2 functions one that displays the data in HTML and one that creates an array of values.
function outputSelectableUsers(results,container){
results.forEach(results => {
//Call function which will render the html
var html =createUserHtml(results,false);
/*
Here is the problem, as seen using jquery element variable selects html variable which render function
*/
var element = $(html);
/*
with jquery, I managed to select the variable and assign it a click event that when I click it calls the function that adapts the array with data
from each API call
*/
element.click(()=>userSelected(results))
//append content to the html selector
container.append(element);
});
}
//Function which will update the array
function userSelected(user){
selectedUsers.push(user);
}
This is what the visible result looks like
And when I click on one of the cards, the area adapts to the user's values.
values that I take from the array and enter them in the database.
I managed to convert everything to js using fetch instead of ajax jquery and changed the selectors and events with vanilla js code.
But the problem is I couldn't find a way to change this piece of code.
var html =createUserHtml(results,false);
var element = $(html);
console.log(element)
element.click(()=>userSelected(results))
container.append(element);
at consol.log (element) I observed asata in the console.
The question is could I choose the element with js vanilla and get the same result as in the jquery version. To use Js Vanilla code instead of
var element = $(html);
element.click(()=>userSelected(results))
let users_id = results._id;
let html = createUserHtml(results,users_id ,false);
container.insertAdjacentHTML('beforeend',html);
//Identify each element by a unique selector
document.querySelector(`[data-selectorTab ="${results._id}"]`).addEventListener('click',()=>{
userSelected(res)
})
I solve this by adding a data attribute to dinamically generated elements,using this data atribute I can make a individual selector for each user.
My firebase db structure is given below,
users
fb-user-key1
user1-details1
Tags
Tag-key1
"name":"value"
Tag-key2
"name":"value"
fb-user-key2
user1-details2
Tags
Tag-key1
"name":"value"
Tag-Key1 & user-key's are generated by firebase with push(). firebase code to access the content is,
var fbref = firebase.database().ref("users");
fbref.child("Tags").on("child_added", function(e){
var Tagobj = e.val().name;
console.log(Tagobj);
});
This one is not returning anything. I am not able to access name:value pair in the above data structure.
`
adding modified code,
firebase.database().ref("users").on("child_added",function(e) { var Tagobj = e.val().Tags; });
Output of the above code is output data structure
How to access that name value pairs?? firebase keys are issue?
Not getting, where I am wrong. Appreciate your inputs.
Since Tags is a child property of each user, then you have to read it off of each user object.
If you want all Tags for all users, assuming Tags for each user is not updated after a user is created, you can do this:
tagsPerUserId = {};
firebase.datatabs().ref('users').on('child_added', function(snap) {
tagsPerUserId[snap.key] = snap.value().Tags;
// TODO: Notify view that tagerPerUserId is updated and needs to be re-rendered
console.log(`Tags for userId ${snap.key}: ${snap.value().Tags}`);
});
This way you will also get Tags of new users when they are created, but you will not get updates to Tags of existing users.
I have a php page which calls a javascript function to populate it.
The page is a list of users each with their own form, the form id has the id appended to its name to allow edit, delete etc on each user.
The form is is the shape of an html page that is in theory sucked in for each record.
I am using jquery each() to iterate over the records, then in theory the html page should be sucked in and populated for each record. I have tried for loop also.
The code below produces the correct number of forms but empty.
Other efforts have left me with only the last record populating the fist box and the others empty.
Any help greatly appreciated.
$(Udata).each(function(uId, value){
uid = value.uid;
var uname = value.uname;
function setValues() {
window.document.getElementById("username").value=uname;
window.document.getElementById("frmDelUsr").setAttribute("name","frmDelUsr"+uid);
}
$.get("users.html",{}, function (data) {
$("#divfrmDelUser").append(data), function(){setValues();}
});
$(Udata).each(function(uId, value){
uid = value.uid;
var uname = value.uname;
function setValues() {
window.document.getElementById("username").value=uname;
window.document.getElementById("frmDelUsr").setAttribute("name","frmDelUsr"+uid);
}
$.get("users.html",{}, function (data) {
$(this).children('.divfrmDelUser').append(data), function(){setValues();} //<--- CHANGED
});
First you'd have to change the element with the ID "divfrmDelUser" by making that ID into a class(just erase "id" and type "class" obviously), then what this ought to do is select the current Udata being used, and then look for the elements within it containing the class "divfrmDelUser" and do what you set it to do past that.
I create a table dynamically and add rows, labels etc to it.
I want to be able to access those rows to make either visible or hidden AND access labels to change content on the fly. So far the table and all info is created with no problem. I spent days trying to access the data from JS, but I keep getting NULL etc on objects using ALERT to test it. Here's a snippet example of my code...
ASP.NET (C#) code
mTable = new HtmlTable();
mTable.ID = "mTable";
aCell = new HtmlTableCell();
aLabel = new Label();
aLabel.ID = "aLabel";
aLabel.Text = "TEST";
aCell.Controls.Add(aLabel);
aRow = new HtmlTableRow();
aRow.ID = "r" + x;
aRow.Cells.Add(aCell);
mTable.Controls.Add(aRow);
Ive put the following code in a SCRIPT FILE etc and ive tried many styles.
alert(document.getElementById('<%=aLabel.ClientID%>'));
If you are using plain vanilla javascript, please look at the code sample here: How do I iterate through table rows and cells in javascript?
The code sample in the above link gets the table by id, which in your case is 'mTable' (from your c# code)
var table = document.getElementById('mTable');
// will return you a reference to the table object on the page
You also have to place the code to call your javascript function that accesses data on the 'mTable' on the document load event
I am using the CreateEventLink method of the ComponentResources class to create a link to a delete event on my page called UserList using the following:
resources.createEventLink("delete", user.getUserId()).toURI();
The UserList page uses datatables to create a list of user's data and a delete link. When the delete link is clicked, the delete event is called on the same page and everyone is happy.
The problem is the datatable goes back to the first page of records after a user is deleted. For example, if I am on page 5 of my datatable, on the UserList page, and I click delete it will stay on the Userlist page, but my datatable will reset itself to the first page.
After some research I haved discovered that the fnStandingRedraw plugin from datatables will fix this issue: http://datatables.net/plug-ins/api
Going through the documentation I have learned that I should use:
javaScriptSupport.addInitializerCall("fnStandingRedraw", "");
to call the following in js file via an Import notation:
Tapestry.Initializer.fnStandingRedraw = function(oSettings) {
//redraw to account for filtering and sorting
// concept here is that (for client side) there is a row got inserted at the end (for an add)
// or when a record was modified it could be in the middle of the table
// that is probably not supposed to be there - due to filtering / sorting
// so we need to re process filtering and sorting
// BUT - if it is server side - then this should be handled by the server - so skip this step
if(oSettings.oFeatures.bServerSide === false){
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
//iDisplayStart has been reset to zero - so lets change it back
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
//draw the 'current' page
oSettings.oApi._fnDraw(oSettings);
};
However I get the error:
Uncaught TypeError: Cannot read property 'bServerSide' of undefined
Tapestry.Initializer.fnStandingRedrawhelpdesk.js:16
$.extend.inittapestry-jquery.js:32
jQuery.extend.eachjquery-1.6.2.js:655
$.extend.inittapestry-jquery.js:26
jQuery.extend.eachjquery-1.6.2.js:649
$.extend.inittapestry-jquery.js:18
(anonymous function)list:70
jQuery.extend._Deferred.deferred.resolveWithjquery-1.6.2.js:1008
jQuery.extend.readyjquery-1.6.2.js:436
DOMContentLoadedjquery-1.6.2.js:915
Any guidance would be most appreciated...Thanks in advance!!
The best practice is to save DataTables plugin to separate js file, so you can use it not only through tapestry initializer but also from other js.:
(function($) {
$.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
if(oSettings.oFeatures.bServerSide === false){
var before = oSettings._iDisplayStart;
oSettings.oApi._fnReDraw(oSettings);
// iDisplayStart has been reset to zero - so lets change it back
oSettings._iDisplayStart = before;
oSettings.oApi._fnCalculateEnd(oSettings);
}
// draw the 'current' page
oSettings.oApi._fnDraw(oSettings);
};
})(window.jQuery);
So you can use it from other places as:
var oTable = $('.dataTable').dataTable();
oTable.fnStandingRedraw();
To call fnStandingRedraw() from tapestry:
jsSupport.addScript("$(%s).dataTable().fnStandingRedraw()", "#myTable");
or you can add tapestry initializer and call it:
Tapestry.Initializer.standingRedraw = function(spec) {
$(spec.tableId).dataTable().fnStandingRedraw();
};
in java:
jsSupport.addInitializerCall("standingRedraw",
new JSONObject("tableId", "#myTable"));
But this will work for you only if your DataTable is client-side(pagination, sorting, filtering) and you do ajax request to delete row and delete this row from DataTable manually from js.
You have no oSettings object.
You can call it from the dataTable object (which has oSettings):
var dt = $("#table").dataTable();
dt.fnStandingRedraw();