Struggling with repeating code with JavaScript and DOM - javascript

For an assignment i need to create a website which outputs mobile phone contracts based on the users preferences. I am currently stuck at the DOM part of the assignment.
I would like to output the results into a list, which i have managed to do, though i'm sure there's a better way to do it using less code.
This is what i have so far: https://jsfiddle.net/fn2ewtck/
The code i am trying to improve is this:
function search() {
var userBrandCtrl = document.getElementById("userBrand");
var userBrand = userBrandCtrl.value;
var userModelCtrl = document.getElementById("userModel");
var userModel = userModelCtrl.value;
var userNetworkCtrl = document.getElementById("userNetwork");
var userNetwork = userNetworkCtrl.value;
for (var i = 0; cont.length; i++) {
if (userBrand === cont[i].brand && userModel === cont[i].model && userNetwork === cont[i].network) {
var body = document.body;
var ulCont = document.createElement("ul");
var liBrand = document.createElement("li");
var liModel = document.createElement("li");
var liNetwork = document.createElement("li");
var liMins = document.createElement("li");
var liTexts = document.createElement("li");
var liData = document.createElement("li");
var liUpfront = document.createElement("li");
var liMonthly = document.createElement("li");
var liLength = document.createElement("li");
var textBrand = document.createTextNode("Brand: " + cont[i].brand);
var textModel = document.createTextNode("Model: " + cont[i].model);
var textNetwork = document.createTextNode("Network " + cont[i].network);
var textMins = document.createTextNode("Mins: " + cont[i].mins);
var textTexts = document.createTextNode("Texts: " + cont[i].texts);
var textData = document.createTextNode("Data: " + cont[i].data);
var textUpfront = document.createTextNode("Upfront: " + cont[i].upfront);
var textMonthly = document.createTextNode("Monthly: " + cont[i].monthly);
var textLength = document.createTextNode("Length: " + cont[i].length);
liBrand.appendChild(textBrand);
liModel.appendChild(textModel);
liNetwork.appendChild(textNetwork);
liMins.appendChild(textMins);
liTexts.appendChild(textTexts);
liData.appendChild(textData);
liUpfront.appendChild(textUpfront);
liMonthly.appendChild(textMonthly);
liLength.appendChild(textLength);
ulCont.appendChild(liBrand);
ulCont.appendChild(liModel);
ulCont.appendChild(liNetwork);
ulCont.appendChild(liMins);
ulCont.appendChild(liTexts);
ulCont.appendChild(liData);
ulCont.appendChild(liUpfront);
ulCont.appendChild(liMonthly);
ulCont.appendChild(liLength);
body.appendChild(ulCont);
}
}
};
How could i do this better?
Thanks.

You could create an array of the properties you want to display from the object and loop over them like this:
var arr = ['brand', 'model', 'network', 'mins']
for (i = 0; i < arr.length; i++) {
//Upercase first letter
var label = arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
//create html elements
var li = document.createElement("li"),
text = document.createTextNode(label + ": " + cont[i][arr[i]]);
li.appendChild(text);
ulCont.appendChild(li);
}
//append to body after loop
body.appendChild(ulCont);

You should look at Backbone and Dust. They'll help you templatize the HTML you're trying to write.

Related

Correct Way To Re-Use HTML Blocks and Insert Dynamic Content With Javascript

I have a server that collects data from 10 sources and constantly pushes JSON data to a webpage. The page uses JSON.Parse to get it into an object widgetData. The object widgetData has 10 properties that I want to display in the "widget".
So, the server is pushing WidgetData1, WidgetData2, etc..
For each widgetData, I want to create/instantiate a new widget and show the data. If widget1 exists, then update the widget. Also, the widgets should be sorted by some text property(e.g. widgetdata.name).
Here's what I've done so far, but the it doesn't seem that robust:
<script type="text/javascript">
var properties = ["MachineID", "p1","p2,"p3","p4"];
var currentWidget;
function CreateBlock(widgetData)
{
var widgetID = widgetData.MachineID.replace(/ /g,"_");
var myWidget = document.getElementById('widget-' + widgetID);
if (myWidget == null)
{
CreateCard(widgetID);
}
var currentDate = new Date();
var day = currentDate.getDay();
var month = currentDate.getMonth(); //Be careful! January is 0 not 1
var year = currentDate.getFullYear();
var hour = currentDate.getHours();
var min = currentDate.getMinutes();
var sec = currentDate.getSeconds();
var dateString = year + "-" + ZeroPad(month+1,2) + "-" + day + " " + ZeroPad(hour,2) + ":" + ZeroPad(min,2) + ":" + ZeroPad(sec,2);
var data;
for (let i = 0; i < properties.length; i++)
{
data = widgetData[properties[i]];
AddDataElement(widgetID,properties[i],data);
}
AddDataElement(widgetID,"Timestamp",dateString);
}
//create the card
function CreateCard(cardID)
{
var parent
var newdiv
var cardElement = document.createElement("div");
cardElement.className = "card";
cardElement.id = "widget-" + cardID;
cardElement.style = "height:500px;";
parent=cardElement;
newdiv = document.createElement("div");
newdiv.className = "card-header";
parent.appendChild(newdiv);
//parent=newdiv;
newdiv = document.createElement("div");
newdiv.className = "card-body";
newdiv.id = "cardbody";
parent.appendChild(newdiv);
parent=newdiv;
newdiv = document.createElement("div");
newdiv.className = "card-title";
newdiv.id = "title";
newdiv.textContent = "title";
parent.appendChild(newdiv);
newdiv = document.createElement("div");
newdiv.className = "card-sub-title";
newdiv.id = "subtitle";
newdiv.textContent = "subtitle";
parent.appendChild(newdiv);
newdiv = document.createElement("div");
parent.appendChild(newdiv);
//last add to the parent div
var parent = document.getElementById("Cards");
parent.appendChild(cardElement);
}
//Add a data element
function AddDataElement(machineID, title, value)
{
var cardElement = document.getElementById("widget-" + machineID);
var cardElementBody = findChild("widget-" + machineID, "cardbody");
var dataElement = findChild2(cardElementBody, title);
if (dataElement == null)
{
dataElement = document.createElement("div");
dataElement.id = title;
dataElement.className = "card-item";
}
dataElement.innerText = title + ": " + value;
cardElementBody.appendChild(dataElement);
}
function CreateElement(parentDivObject, childName)
{
var dataElement = document.createElement('DIV');
dataElement.id = childName;
dataElement.textContent = childName;
parentDivObject.appendChild(dataElement);
}
function findChild(idOfElement, idOfChild)
{
let element = document.getElementById(idOfElement);
return element.querySelector('[id=' + idOfChild + ']');
}
function findChild2(parentElement, idOfChild)
{
//let element = document.getElementById(idOfElement);
return parentElement.querySelector('[id=' + idOfChild + ']');
}
function ZeroPad(num, places)
{
var zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}
</script>
<script type="text/javascript">
var widgetList = new Set(); //hold list of widgets
var start = function () {
var inc = document.getElementById('incomming');
var wsImpl = window.WebSocket || window.MozWebSocket;
var form = document.getElementById('sendForm');
var input = document.getElementById('sendText');
inc.innerHTML += "connecting to server ..<br/>";
// create a new websocket and connect
window.ws = new wsImpl('ws://localhost:8181/');
//when data is comming from the server, this method is called
//ws.onmessage = function (evt) {
// inc.innerHTML += evt.data + '<br/>';
//};
ws.onmessage = function (evt)
{
var machineStatus = JSON.parse(evt.data);
if (!widgetList.has(machineStatus.MachineID))
{
widgetList.add(machineStatus.MachineID)
}
CreateBlock(machineStatus)
}
// when the connection is established, this method is called
ws.onopen = function () {
inc.innerHTML += '.. connection open<br/>';
};
// when the connection is closed, this method is called
ws.onclose = function () {
inc.innerHTML += '.. connection closed<br/>';
}
form.addEventListener('submit', function(e){
e.preventDefault();
var val = input.value;
ws.send(val);
input.value = "";
});
}
window.onload = start;
</script>
What is an alternative, proper way, or best practice to accomplish this?

Clearing localStorage of a page without affecting other localStorage

In my code i have set multiple items in local storage, when i use localStorage.clear() it resets the variable of my other webapps as well, and i do not want to remove each item one by one, i want to reset the specific container of my localStorage of that page, whole storage of my browser.
here is my code
if (localStorage.container) {
var i = parseInt(localStorage.container);
} else {
localStorage.setItem('container', "0");
var i = parseInt(localStorage.container);
}
var caseNum = $("#caseNum").val();
localStorage.setItem('caseNum' + i, caseNum);
var empName = checkName()
localStorage.setItem('empName' + i, empName);
var emp = $("#emp").val();
localStorage.setItem('emp' + i, emp);
var trigTime = $("#trigTime").val();
localStorage.setItem('trigTime' + i, trigTime);
var country = $("#country").val();
localStorage.setItem('country' + i, country);
var date = $("#date").val();
localStorage.setItem('date' + i, date);
var caseDate = $("#date").val();
localStorage.setItem('caseDate' + i, caseDate);
var doneTime = currTime();
localStorage.setItem('doneTime' + i, doneTime);
var dispo = $("#dispo").val();
localStorage.setItem('dispo' + i, dispo);
var subDispo = $("#subDispo").val();
localStorage.setItem('subDispo' + i, subDispo);
var caseCount = $("#caseCount").val();
localStorage.setItem('caseCount' + i, caseCount);
var A1 = '';
localStorage.setItem('A1' + i, A1);
var A2 = '';
localStorage.setItem('A2' + i, A2);
var A3 = '';
localStorage.setItem('A3' + i, A3);
var project = $("input[type='radio'][name='project']:checked").val();
localStorage.setItem('project' + i, project);
var prefix = '';
if (country == "Kenya") {
prefix = "KY";
}
localStorage.setItem('prefix' + i, prefix);
var called1 = '';
if ($("#called0").prop("checked") == true) {
called1 = "Yes";
} else if ($("#called0").prop("checked") == false) {
called1 = "No";
}
localStorage.setItem('called1' + i, called1);
i++;
localStorage.setItem('container', i);
that code is for my dynamic table, do it is creating an array of entries in tablerow.
i tried to use localStorage.removeItem(container); but does not work. Any suggestions please ?

for var in key loop displaying the same property instead of 4 different ones

Im trying to make an addressbook in javascript and the issue I have is that the properties of my objects are not giving me the info I need. I want 4 different property and not 4 loops of same property.
The for loop is makes a loop of 4 lis list items thats gonna be inserted from the info I have in the objects.
But instead I got EMAIL all the loops.
Hope you understand and can help me.
Here is the code.
//Contactlist funktion
function Contact(fname, lname, address, email) {
this.fname = fname;
this.lname = lname;
this.address = address;
this.email = email;
}
// Contacts
var tony = new Contact("Tony", "Stark", "Avengers 123", "i.am.ironman#hotmail.com");
var steve = new Contact("Steve", "Rogers", "Avengers 12", "cap.america#hotmail.com");
//All contacts
var contacts = [tony, steve];
// Appending the objects
var body = document.getElementsByTagName('body')[0];
var ul = document.createElement('ul');
body.appendChild(ul);
function theContacts() {
var li = document.createElement('li');
li.innerHTML = tony.fname + ' ' + stark.lname;
ul.appendChild(li);
for (i = 0; i < 4; i++) {
li = document.createElement('li');
for (var key in tony) {
li.innerHTML = key;
}
ul.appendChild(li);
}
}
// Calling the object
theContacts();
Thanks for your help!
This will output all contacts with their properties as nested unordered lists. I have given classnames to the elements for easy styling. Start just below your var contacts.
function theContacts() {
var body = document.getElementsByTagName('body')[0],
outerUL = document.createElement('ul'),
length = contacts.length;
outerUL.className = 'contactlist';
for (var i = 0; i < length; i++) {
var cont = contacts[i],
li = document.createElement('li'),
ul = document.createElement('ul');
li.className = 'contact'; li.innerHTML = cont.fname + ' ' + cont.lname;
ul.className = 'infos';
for (var key in cont) {
var info = document.createElement('li');
info.className = key;
info.innerHTML = cont[key];
ul.appendChild(info);
}
li.appendChild(ul); outerUL.appendChild(li);
}
body.appendChild(outerUL);
}
The problem you had results from confusion with var li inside theContacts().

Spliting String and getting appropriate value in JavaScript

I have a string where |||| means next to it is the directory. ||| means the user is allowed to access this directory and || means the files allocated to these users follow.
I need to find allocated file names of a specific user from this string. I have tried to split the string and assign values to an array but I am not able to get the result I'm looking for.
This is the string:
||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,
And here is my attempt:
function getData() {
var user = 'km11285c';
var value = "||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,";
var users = null;
var files = null;
var Dir = value.split("||||");
var arrayLength = Dir.length;
for (var i = 0; i < arrayLength; i++) {
users = Dir[i].split("|||");
}
return users;
}
console.log(getData());
and the jsFiddle
I changed your jsfiddle example a bit so maybe you need to change the code here and there, but something like this should work:
function buildTree(data) {
var tree = [];
var dirs = data.split("||||");
// Remove the first entry in the array, since it should be empty.
dirs.splice(0, 1);
for (var i = 0; i < dirs.length; ++i) {
var tempArray = dirs[i].split("|||");
var dirName = tempArray[0];
var usersAndFiles = tempArray[1];
tempArray = usersAndFiles.split("||");
var users = tempArray[0];
var files = tempArray[1];
var treeDir = { name: dirName };
treeDir.users = users.split(",");
treeDir.files = files.split(",");
tree.push(treeDir);
}
return tree;
}
function getData() {
var user = 'km11285c';
var value="||||Root|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,||||1400842226669|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,||||1401191909489|||adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,km11285c,km61052,km61639c,adil001,kl04707c,km47389,km58184,km61052,kq61023c,||LimitTest_20140528164643.xlsx,testTask2_20140528140033.xlsx,testTask1_20140528135944.xlsx,testTask2_20140528140033.xlsx,LimitTest_20140528164643.xlsx,";
var tree = buildTree(value);
for (var i = 0; i < tree.length; ++i) {
var dir = tree[i];
if (dir.users.indexOf(user) >= 0) {
console.log("User '" + user + "' has access to directory '" + dir.name + "', which contains these files: " + dir.files.join(","));
}
}
}
getData();

Trouble hiding/showing divs in using DOM/js/css

I am trying to make a debugger that will be dynamiaclly created with some variables. The names on the left div need to show a div for the corresponding variables Description,Variable ID, and initial Value as well as another div that will show history and lock status when variables are updated later. Where I am having trouble is properly adding the show/hide to the dom I think. Everything starts hidden and then when I click a name the Variables for that name show up but the next click doesn't hide the values from the former. Also any cleanup/optimization advice?
<script type="text/javascript">
var variableIDArray = {};
function loadVariables(variables) {
if (typeof variables != "object") { alert(variables); return; }
var namearea = document.getElementById('namearea');
var description = document.getElementById('description');
var varid = document.getElementById('varid');
var initialvalue = document.getElementById('initialvalue');
var valuelock = document.getElementById('valuelock');
for (var i = 0; i < variables.length - 1; i++) {
var nameDiv = document.createElement('div');
nameDiv.id = variables[i].variableID + "namearea";
nameDiv.className = "nameDiv";
nameDiv.onclick = (function (varid) {
return function () { showvariable(varid); };
})(variables[i].variableID);
nameDiv.appendChild(document.createTextNode(variables[i].name));
namearea.appendChild(nameDiv);
var descriptionDiv = document.createElement('div');
descriptionDiv.id = variables[i].variableID + "description";
descriptionDiv.className = "descriptionDiv";
descriptionDiv.appendChild(document.createTextNode("Description : " + variables[i].description));
description.appendChild(descriptionDiv);
var varidDiv = document.createElement('div');
varidDiv.id = variables[i].variableID + "varid";
varidDiv.className = "varidDiv";
varidDiv.appendChild(document.createTextNode("Var ID : " + variables[i].variableID));
varid.appendChild(varidDiv);
var initialvalueDiv = document.createElement('div'); ;
initialvalueDiv.id = variables[i].variableID + "initialvalue";
initialvalueDiv.className = "initialvalueDiv";
initialvalueDiv.appendChild(document.createTextNode("Initial Value : " + variables[i].value));
initialvalue.appendChild(initialvalueDiv);
var valuelockDiv = document.createElement('div');
valuelockDiv.id = variables[i].variableID + "valuelock";
valuelockDiv.className = "valuelockDiv ";
valuelockDiv.appendChild(document.createTextNode("Value : " + variables[i].value));
valuelockDiv.appendChild(document.createTextNode("Lock : " + variables[i].locked.toString()));
valuelock.appendChild(valuelockDiv);
variableIDArray[variables[i].variableID];
}
};
function showvariable(varid) {
for (v in variableIDArray)
hide(variableIDArray[v]);
show(varid + "description");
show(varid + "varid");
show(varid + "initialvalue");
show(varid + "valuelock");
}
function show(elemid) {
document.getElementById(elemid).style.display = "block";
}
function hide(elemid) {
document.getElementById(elemid).style.display = "none";
}
Yes. jQuery. Will reduce your code to about 6 lines. :) http://jquery.com

Categories