How to Access an array of objects properties? - javascript

i'm working in a simple program that uses an HTML Form to fill an Array with some information, so far, i can get the input data, store it into my list, and visualize it like this :
It basically, converts the Name to a Link, when you click it, it will create a <div> in which i show all the information of the contact.
And i've done this like this :
The error i'm getting is in the last 6 lines of Code.
(I'm trying to avoid all non-troubling code)
var list = [];
var ulList = document.createElement("UL");
function AddToList(){
//Just pushes the info into the list.
}
function Visualize(){
ClearScreen();
for(var i = 0 ; i < list.length ; i++){
//Tried to keep it clean, this just works with each item in the list.
AddToList(i);
}
}
//This Works correctly, it shows every Name i've previously pushed into the list like a Link.
function AddToList(index){
var element = document.createElement("LI");
var name = document.createTextNode(list[index].name);
element.appendChild(name);
var link = document.createElement("A");
link.setAttribute("HREF", "#");
link.appendChild(element);
lik.setAttribute("ID", index);
link.addEventListener("click", ShowInfo(this.id)); //Index would do the same
ulList.appendChild(link);
document.getElementsByTagName("body")[0].appendChild(ulList);
}
//Trouble comes here
function ShowInfo(index){
CleanDIV();
//Previously created <div> with box as id
var box = document.getElementById("box");
var details = document.createElement("UL");
var lName = document.createElement("LI");
var lNumber = document.createElement("LI");
var lMail = document.createElement("LI");
//
//The error is here : Cannot Read Property 'name' of undefined
//And i dont know why, since i've done something similar in a previous line...
//
lName.appendChild(document.createTextNode("Name :" + list[index].name));
lNumber.appendChild(document.createTextNode("Number : " + list[index].number));
lMail.appendChild(document.createTextNode("Mail : " + list[index].mail));
details.appendChild(lName);
details.appendChild(lNumber);
detaisl.appendChild(lMail);
}
I dont even know what kind of mistake i'm making, and was not sure of how to ask this question.
I apologyze for any grammar mistake, my bad variable naming abilities and any lack of quality in my question.
Thank you kindly.

In your AddToList function, indice is 'undefined'

You get the error because you have not added anything to your list array. Add the person details to the list array when the Add to List button is clicked. And retrieve this when the link is clicked.
var name = document.getElementById("txtName").value;
var number = document.getElementById("txtNnumber").value;
...
var person = {'name': name, 'number': number};
list.push(person);

Looks like you have a couple of typos in your code.
lik.setAttribute("ID", indice);
link.addEventListener("click", ShowInfo(this.id)); //Index would do the same
should be
link.setAttribute("ID", index);
link.addEventListener("click", ShowInfo(index)); //Index would do the same

Related

MDN JavaScript exercise using additional variable

just trying to learn some JS via the MDN website and a bit confused to why they are using one variable to store the result of the loop and then again another variable to store 2nd variable, see example
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods
Scroll down to the exercise "Filtering greeting messages"
You will see the code below on the MDN page:
var list = document.querySelector('.output ul');
list.innerHTML = '';
var greetings = ['Happy Birthday!',
'Merry Christmas my love',
'A happy Christmas to all the family',
'You\'re all I want for Christmas',
'Get well soon'];
for(var i = 0; i < greetings.length; i++) {
var input = greetings[i]; // They assign it here first
if(greetings[i].indexOf('Christmas') !== -1) {
var result = input; // Then they assign input to result here
var listItem = document.createElement('li');
listItem.textContent = result; // Then they use result, WHY?
list.appendChild(listItem);
}
}
Now, why can't listItem.textContent = result be listItem.textContent = input
I've tested this and it works assigning input but just would like to know what the reason behind this method of assigning the result of the loop into two different variables.
Thanks

Google Script: Format URL in Array.Push

I have a working script that upon form submit, specific rows move from one sheet to another. One of the fields I'm pushing is a url.
On the second sheet, the link is listed and it is hyperlinked, but it's really ugly and I really want to format it so that it shows "Edit" with a hyperlink. I've tried a number of ways, but my knowledge is limited so all I get are errors. I'm hoping someone can point me in the right direction.
Here is my code. I'm very new at this so the script is not at all sophisticated. Any help/suggestions would be appreciated!
function copyAdHoc(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Form Responses 1"));
var data = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
// Grab the Headers from master sheet
var headers = sh.getRange(1,1,1,sh.getLastColumn()).getValues();
var date = headers[0].indexOf('Effective Date');
var name = headers[0].indexOf('Employee Name');
var loc = headers[0].indexOf('Location');
var issue = headers[0].indexOf('Description/Question/Issue');
var add = headers[0].indexOf('Additional Information');
var change = headers[0].indexOf('Is this a Qualifying Life Event?');
var url = headers[0].indexOf('Form URL');
var category = headers[0].indexOf('Primary Category');
var status = headers[0].indexOf('Current Status');
var users = headers[0].indexOf('Users');
// Grab only the relevant columns
for(n = 0; n < data.length; ++n ) { // iterate in the array, row by row
if (data[n][change] !== "Yes" & data[n][category] !== "Employee Relations" & data[n][date] !== "") { // if condition is true copy the whole row to target
var arr = [];
arr.push(data[n][url]);
arr.push(data[n][users]);
arr.push(data[n][date]);
arr.push(data[n][loc]);
arr.push(data[n][name]);
arr.push(data[n][category]);
arr.push(data[n][issue] + ". " + data[n][add]);
arr.push(data[n][status]);
var sh2 = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Ad Hoc")); //second sheet of your spreadsheet
sh2.getRange(sh2.getLastRow()+1,2,1,arr.length).setValues([arr]); // paste the selected values in the 2cond sheet in one batch write
}
}
}
It's a bit messy but the only way I know to achieve what you're trying to do would be to insert a column to the left of the hyperlink with the word Edit right justified and then remove the borders between the two.
From your description I am assuming you want the word "Edit" to be Hyperlinked. To do so, try this:
function getHyperlink(url)
{
return "=HYPERLINK(\""+url+"\","+"\"Edit\""+")";
}
function mainFunct()
{
//Do necessary steps
var tarLink = "https://www.google.com";
var tarRng = tarSheet.getRange(rowNum, colNum).setValue(getHyperlink(tarLink));
//perform other steps
}
EDIT:
Forgot to mention, since you're pushing your values to the array... you can do it in a similar way by either just storing the hyperlink in a variable or directly pushing it to the array like all the other values. Or if you're dealing with a hyperlink that has a static and dynamic part, For example: https://stackoverflow.com/questions/post_id, where post_id keeps changing but most of the URL is static, you can easily handle it by just passing the post_id to the getHyperlink function and getting the required Hyperlink in return. Hope this helps.

HTML-modifying JavaScript Code says that my HTML Element is undefined

I'm currently trying to get a simple Category System to work.
To do so, I've created a tiny Category "class" which fits my needs:
var categories = [];
function Category (id, name, ownedBy){
this.id = id;
this.name = name;
this.ownedBy = ownedBy;
categories[id] = this;
}
id is, well, the ID of the Category. It's name is only used for display purposed. And "ownedBy" is the ID of the super-category, or "none" if it hasn't one.
After filling my categories-array, I iterate over it and call a function of mine to add the categories to my HTML-Code:
function addHTMLCategory(catID){
var cat = categories[catID]; //Get the Category-"Object"
if(!cat) return; //If it doesn't exist, do nothing.
if(cat.ownedBy != "none"){ //If the category has a supercategory,
addHTMLCategory(cat.ownedBy); //Add it to the HTML first.
}
if(document.getElementById("cat"+catID)) return; //And if it already exists, dont add it again.
//ERROR-PART: If a category has a superclass, get the superclass element.
var contentElement = document.getElementById(cat.ownedBy=="none"?"categories":"cat"+cat.ownedBy);
var li = document.createElement("div");
li.id = "cat"+catID;
li.className = "category";
li.innerText = cat.name;
contentElement.appendChild(li);
}
Initial HTML:
<div id="categories"></div>
This function checks if the Category has a Super-Category, and if yes, it adds this one first: I did this to avoid that the element where the category should be added to doesn't exist.
Unfortunately, exactly this happens: When a Category has a super-category, the "contentElement" variable is null. Could anyone tell me why?
The problem was that the ownedBy variable of Category was set to the name of the super-category, instead of its ID (In another part of the code which I thought was irrelevant)

localStorage loop missing records after deleting 2 records ( on a different page )

Everything seems to work fine when I add records using my form. They all show up nicely on the page.
When I press on the delete button that is generated with each record, it removes the record and reloads the page. This also works. The second time I do this though, my records seem to vanish.
For example, I add 5 records titled : a,b,c,d,e. They show up, I delete record b, the list reloads with a,c,d,e without a problem. The moment I delete c from the newly generated list my e record vanishes, so it shows only a and d.
Clearly I am doing something horribly wrong, I am hoping someone can show me what that is. If it's bad programming practice this way, please let me know in what direction to search for the right way.
I have 3 seperate pages:
Storing records:
function storeEntry(){
var myId = localStorage.length;
addBtn.addEventListener("touchstart", submitEntry, false);
addBtn.addEventListener("mousedown", submitEntry, false);
function submitEntry(event) {
//Get the form data to store in the Array
var myTitle = document.getElementById("myTitle").value;
var myDate = document.getElementById("myDate").value;
var myContent = document.getElementById("myContent").value;
//Fill array that will be placed in localstorage
var myArray = [myId,myTitle,myDate,myContent];
//Store it as a json string
localStorage.setItem(myId, JSON.stringify(myArray));
//Provide feedback
alert("Item: " + myTitle + " has been added with id: "+myId);
//Id +1 zodat het volgende item een uniek id krijgt.
myId=myId+1;
//Clear the form
setFields();
}
}
For deleting records:
function deleteEntry(){
var key=localStorage.key(this.i);
this.removeEventListener("click",deleteEntry);
localStorage.removeItem(key);
alert("Item : "+key+" is verwijderd!");
window.location.href = "showEntry.html";
}
And finally for showing records:
function loadEntries(){
var myEntryBox = document.getElementById("entryBox");
var myvar="";
for(var i=0;i<=localStorage.length;i++){
if(localStorage.getItem(i)!==null) {
var myData = JSON.parse(localStorage[i]);
myvar = myvar +"-------------------"+ myData;
var newNode = document.createElement('div');
newNode.innerHTML = myData;
myEntryBox.appendChild( newNode );
var delButton = document.createElement('button');
delButton.innerHTML = "Del";
delButton.i=myData[0];
newNode.appendChild(delButton);
alert("This node id is: "+myData[0]);
delButton.addEventListener("click",deleteEntry);
}
else{
alert("Geen data");
}
document.getElementById("log").innerHTML = myvar;
}
}
I think the problem lies with your key id... You are setting it to the localstorage length, but when you remove an item the length is changed... Try using a counter instead and increment by ++.
I think your looking at it like an array, but its really an object ( like a dictionary) with a length property... you're removing the keys so the length is "wrong"..
var counter = 0;
function storeEntry(){
counter++;
var myId = counter;
addBtn.addEventListener("touchstart", submitEntry, false);
addBtn.addEventListener("mousedown", submitEntry, false);
function submitEntry(event) {
...
//Id +1 zodat het volgende item een uniek id krijgt.
//myId=myId+1; <-- no need anymore
}
}
You will need to fix your delete ....
I have figured out my problem,
On the showEntry page I was looping with:
for(var i=0;i<=localStorage.length;i++){
if(localStorage.getItem(i)!==null) {
var myData = JSON.parse(localStorage[i]);
I have changed this to :
for(var i=0;i<=localStorage.length;i++){
var myKey=localStorage.key(i);
if(localStorage.getItem(myKey)!==null) {
localStorage.getItem was trying to find items matching some key from the i variable, but that would result in errors since the key names stored can be way higher than the length of localstorage after deleting items.

How to save a HTMLElement (Table) in localStorage?

I've been trying this for a while now and could not find anything online...
I have a project, where tablerows get added to a table. Works fine.
Now I want to save the Table in the localStorage, so I can load it again. (overwrite the existing table).
function saveProject(){
//TODO: Implement Save functionality
var projects = [];
projects.push($('#tubes table')[0].innerHTML);
localStorage.setItem('projects', projects);
//console.log(localStorage.getItem('projects'));
The problem is the Array "projects" has (after one save) 2000+ elements. But all I want is the whole table to be saved to the first (or appending later) index.
In the end I want the different Saves to be listed on a Option element:
function loadSaveStates(){
alert('loading saved states...');
var projects = localStorage.getItem('projects');
select = document.getElementById('selectSave'); //my Dropdown
var length = projects.length,
element = null;
console.log(length);
for (var i = 0; i < length; i++) {
element = projects[i];
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = 'project ' + i;
select.appendChild(opt);
}
}
Can anyone tell me what I am doing wrong?
You can easily do this by jquery, are you interested in this, if yes.. then try following code
For setting the value
$.jStorage.set("projects", $.trim(projects));
For Getting the data
$.jStorage.get("projects");
For deleting the data with key
$.jStorage.deleteKey("projects");
I coose to stay with localStorage, but insted of using an Array I just let the user give every project a name and create a new Item for every Save:
function saveProject(){
//TODO: Implement Save functionality
var pname=prompt("Please enter your project name:","projectname")
var text = $('#mainTable')[0].innerHTML;
//console.log(text);
localStorage.setItem(pname, text);
//console.log(localStorage.key(2));
loadSaveStates();
}
function loadProject(){
var selected = $('#selectSave')[0].selectedIndex
//console.log(selected);
if (localStorage.key(selected) == 'jStorage'){
selected++;
}
var innerHTMLTable = localStorage[localStorage.key(selected)];
//console.log(innerHTMLTable);
$('#mainTable')[0].innerHTML = innerHTMLTable;
updateHandlers();
}
function deleteProject(){
var selected = $('#selectSave')[0].selectedIndex
var pname = $('#selectSave')[0].options[selected].value
$('#selectSave')[0].remove(selected);
localStorage.removeItem(pname);
//console.log(pname);
loadSaveStates();
}

Categories