Hyperlinks Don't Work After Creating DIVs On The Fly - javascript

I have an app that can save user input locations in localStorage. When a user goes to the saved locations page in the app, the JavaScript creates divs for each saved location and displays the key text. I want to be able to click each location and run a function. I'm stuck on getting the divs to have hyperlinks. I think the problem is in my loop. "JavaScript:Void(0)" is just a placeholder for the moment.
Here is what I have so far:
myApp.onPageInit('saved_locations', function (page) {
var fragment = document.createDocumentFragment();
var parent = document.getElementById("saved");
// iterate localStorage
for (var i = 0; i < localStorage.length; i++) {
// set iteration key name
var key = localStorage.key(i);
// use key name to retrieve the corresponding value
var value = localStorage.getItem(key);
// console.log the iteration key and value
console.log('Key: ' + key + ', Value: ' + value);
//var idNum = i.toString();
let node = document.createElement("div");
let a = document.createElement("a");
a.textContent = key;
a.href = "JavaScript:Void(0)";
node.appendChild(a);
fragment.appendChild(node);
};
parent.appendChild(fragment);
var myForm = document.getElementById("enter_location");
myForm.addEventListener('submit', function saveSearchLocation() {
var lat = document.getElementById('Latitude').value;
var lon = document.getElementById('Longitude').value;
var locationStr = document.getElementById('Location').value;
//Save location parameters to local storage
savedLocationParams = [lat, lon, locationStr];
window.localStorage.setItem(locationStr, JSON.stringify(savedLocationParams));
document.getElementById("saved").onsubmit = function(){
window.location.reload(true);
}
});
});
Here is the HTML page:
<body>
<div class="pages">
<div data-page="saved_locations" id="saved" class="page navbar-through no-
toolbar" align="center">
<h2><br><u>Enter A Location<br><br></u>
<form id="enter_location">
Latitude: <input type="text" id="Latitude" value=""><br>
Longitude: <input type="text" id="Longitude" value=""><br>
Location: <input type="text" id="Location" value=""><br>
<input type="submit" value="Submit">
</form>
<h2><u>Saved Locations</u></h2>
</div>
</div>

You have to create the a elements, and then assign the text you want to them, and then you have to put the a elements in the div.
let a = document.createElement("a");
a.textContent = "this is the link text";
a.href = "JavaScript:Void(0)";
node.appendChild(a);
If you want the value text to be linked, you can do this instead of creating the text node:
a.textContent = key;
I modified your code slightly to show an example. Just click on the "Click Here" to see the effects of the function :
//myApp.onPageInit('saved_locations', function (page) {
var clickMeToDoLoad = function() {
var fragment = document.createDocumentFragment();
var parent = document.getElementById("saved");
var fakeLocalStorage = {
"key0": "value0",
"key1": "value1",
"key2": "value2"
};
// iterate localStorage
//for (var i = 0; i < localStorage.length; i++) {
for (var i = 0; i < 3; i++) {
// set iteration key name
//var key = localStorage.key(i);
// use key name to retrieve the corresponding value
//var value = localStorage[key);
// set iteration key name
let key = Object.keys(fakeLocalStorage)[i];
// use key name to retrieve the corresponding value
let value = fakeLocalStorage[key];
// console.log the iteration key and value
console.log('Key: ' + key + ', Value: ' + value);
let idNum = i.toString();
let node = document.createElement("div");
let a = document.createElement("a");
a.textContent = key;
a.href = "JavaScript:Void(0)";
node.appendChild(a);
fragment.appendChild(node);
}
parent.appendChild(fragment);
}
<div class="pages">
<div data-page="saved_locations" id="saved" class="page navbar-through no-
toolbar" align="center">
<h2><br/><u>Enter A Location<br /><br /></u></h2>
<form>
Latitude: <input type="text" name="Latitude" value=""><br> Longitude: <input type="text" name="Longitude" value=""><br> Location: <input type="text" name="Location" value=""><br>
<input type="submit" value="Submit" onclick="return false;">
</form>
<h2><br /><u>Saved Locations</u></h2>
<button onclick="clickMeToDoLoad();">Click to demo function</button>
</div>
</div>

Related

Parsing text area line that comma separated using Jquery or Js

I have a textarea with data like this (UserId,Name,Gender), and I want to parsing that data
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
i want all IDs only , Names only And i want to get Names&Gender from text area above ,
i tried to separated this data but if failed .
This my JS code :
var data = $('#data').val();
console.log(fbdata[0]);
Split your trimmed string by newlines to create an array of strings.
Then, depending on the desired output use Array.prototype.map() or Array.prototype.reduce()
const elData = document.querySelector("#data");
const str = elData.value.trim();
const lines = str.split(/\n/);
// Example 1: create array or data objects
const list = lines.map(str => {
const [id, name, gender] = str.split(",");
return {id, name, gender};
});
// console.log(list); // get 'em all
console.log(list[1]); // get by index
// Log only names
list.forEach((user) => {
console.log(user.name);
});
// example 2: create Object of items - by ID
const listById = lines.reduce((acc, str) => {
const [id, name, gender] = str.split(",");
acc[id]= {id, name, gender};
return acc;
}, {});
// console.log(listById); // get 'em all
console.log(listById[731490]) // Get specific by ID
<textarea class="form-control" id="data" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
You could also do it like this.
var results = [];
var data = $('#data').val().trim();
if(data) {
// Create an array by splitting the textarea.value by newline
data = data.split(/\r?\n/);
// Loop through indivdual rows, and split by comma / ,
for(var i = 0; i < data.length; i++) {
var temp = data[i].trim();
if(temp) {
// Create an array from the values in the current line
temp = temp.split(",");
// Separate the first and last names
var pairs = temp[1].split(/ (.*)/s);
// if there's no last name, pairs[1]
// will be undefined, so we set it to
// and empty string, to avid errors
if(typeof pairs[1] === 'undefined') {
pairs[1] = '';
}
var personsObj = {};
personsObj.id = temp[0];
personsObj.firstName = pairs[0].trim();
personsObj.lastName = pairs[1].trim();
personsObj.gender = temp[2].trim();
results.push(personsObj);
}
}
}
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
EDIT
If you want to replace the contents of the textarea with specific values from the processed array of objects (results, in my example), you could do that like this.
Please note that you do not need extra textareas, like in the following example. I am using them to show you what you would get for different combinations. In reality, you would replace the contents of the #data element with the new content.
var results = [];
var data = $('#data').val().trim();
if(data) {
// Create an array by splitting the textarea.value by newline
data = data.split(/\r?\n/);
// Loop through indivdual rows, and split by comma / ,
for(var i = 0; i < data.length; i++) {
var temp = data[i].trim();
if(temp) {
// Create an array from the values in the current line
temp = temp.split(",");
// Separate the first and last names
var pairs = temp[1].split(/ (.*)/s);
// if there's no last name, pairs[1]
// will be undefined, so we set it to
// and empty string, to avid errors
if(typeof pairs[1] === 'undefined') {
pairs[1] = '';
}
var personsObj = {};
personsObj.id = temp[0];
personsObj.firstName = pairs[0].trim();
personsObj.lastName = pairs[1].trim();
personsObj.gender = temp[2].trim();
results.push(personsObj);
}
}
}
// This doesn't have to be here, you can use the logic in the loop above
// which would a better, more efficient way of doing it
// I'm doing this separately, so you can better understand how it works
// That's why there are 6 additional textareas - in reality, you would
// change the contents of your original textarea
var tmpNames = "", tmpIdsNames = "",
tmpGenders = "", tmpIdsGenders = "",
tmpNamesGenders = "", tmpIdsNamesGenders = "";
for(var i = 0; i < results.length; i++) {
tmpNames += results[i].firstName+ "\r\n";
tmpIdsNames += results[i].id + "," + results[i].firstName + "\r\n";
tmpGenders += results[i].gender + "\r\n";
tmpIdsGenders += results[i].id + "," + results[i].gender + "\r\n";
tmpNamesGenders += results[i].firstName + "," + results[i].gender + "\r\n";
tmpIdsNamesGenders += results[i].id + "," + results[i].firstName + "," + results[i].gender + "\r\n";
}
$("#justNames").val(tmpNames);
$("#idsNames").val(tmpIdsNames);
$("#justGenders").val(tmpGenders);
$("#idsGenders").val(tmpIdsGenders);
$("#namesGenders").val(tmpNamesGenders);
$("#idsNamesGenders").val(tmpIdsNamesGenders);
textarea {
width: 100%;
}
.results {
display: inline-block;
width: 30%;
margin-right: 15px;
}
.results textarea {
min-height: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label style="display:block; width:100%">Original data
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
</label>
<label class="results">Just names
<textarea style="display:block" id="justNames" name="justNames"></textarea>
</label>
<label class="results">IDs and names
<textarea style="display:block" id="idsNames" name="idsNames"></textarea>
</label>
<label class="results">Just genders
<textarea style="display:block" id="justGenders" name="justGenders"></textarea>
</label>
<label class="results">IDs and genders
<textarea style="display:block" id="idsGenders" name="idsGenders"></textarea>
</label>
<label class="results">Names and genders
<textarea style="display:block" id="namesGenders" name="namesGenders"></textarea>
</label>
<label class="results">IDs, names and genders
<textarea style="display:block" id="idsNamesGenders" name="idsNamesGenders"></textarea>
</label>
You can also experiment with this fiddle.
See String.prototype.split() and Array.prototype.map().
var data = $('#data').val().split("\n").map(line => line.split(",")[0]);
// ['097544', '731490', '130578', '87078148', '932484', '093779', '39393']

Repeating a div based on user input (JavaScript solution preferred)

Looking for the simplest implementation of the following problem:
I have a user input number field like:
<input type="number" id="numInput" name="numInput" value="1" onchange="myFunc()">
<div id="demo">*** TEST ***</div>
I want to replicate the #demo div based on the #numInput value entered by the user, e.g. if the user enters '5', there would be five #demo divs displayed on the page. At the moment, I'm using the following function:
function myFunc() {
var newArray = [];
var numInput = document.getElementById('numInput').value;
var x = document.getElementById('demo').innerHTML;
for(var i=0; i<numInput; i++) {
newArray.push(x);
}
document.getElementById('demo').innerHTML = newArray;
}
but this is adding to the existing array rather than outputting the exact number of divs based on user input. Please advise. Thanks.
There should not be multiple same id values.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newDiv = document.createElement('div');
newDiv.setAttribute('id', 'demo' + i);
newDiv.innerHTML = '*** TEST ***';
numInput.parentNode.insertBefore(newDiv, numInput.nextSibling);
}
}
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
+Edit
You can also manipulate <form> with javascript.
function myFunc() {
let numInput = document.getElementById("numInput");
while (numInput.nextSibling) {
numInput.nextSibling.remove();
}
let numInputval = document.getElementById('numInput').value;
for(var i=numInputval; i>0; i--) {
var newInput = document.createElement('input');
newInput.setAttribute('id', 'demoInput' + i);
newInput.setAttribute('type', 'text');
newInput.setAttribute('name', 'demoInputName' + i);
newInput.setAttribute('onchange', 'myFormChangeListener(this)');
numInput.parentNode.insertBefore(newInput, numInput.nextSibling);
numInput.parentNode.insertBefore(document.createElement('br'), numInput.nextSibling);
}
}
function myFormChangeListener(element) {
console.log(element);
console.log(element.value);
myForm.action = 'http://the.url/';
myForm.method = 'post';
console.log(myForm);
//myForm.submit;
}
<form id="myForm">
<input type="number" id="numInput" name="numInput" onchange="myFunc()">
</form>

How to populate multiple HTML DOM elements with local storage values

I want to display contents in the last <div> element when a click event occurs but now it only shows 1st 2 elements. Is there something I am not doing right somewhere?
Here is my code so far:
JS
const iname = document.getElementById("name");
const iemail = document.getElementById("email");
const iphone = document.getElementById("phone");
const submit = document.getElementById("submit");
const storage = document.getElementById("storage");
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
localStorage.setItem(name, "");
localStorage.setItem(email, "");
localStorage.setItem(phoneno, "");
location.reload();
}
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `Name : ${key}<br />Email : ${value}`;
}
localStorage.clear()
HTML
<p>Name</p>
<input id="name" autocomplete="off">
<p>Email</p>
<input id="email" autocomplete="off">
<p>Phone no</p>
<input id="phone" autocomplete="off">
<button id="submit">Let's go</button>
<div id="storage" class="box">
<h1>Is this correct?</h1></div>
I think you are setting the values in localstorage the wrong way.
The syntax for storing stuff in there is localstorage.setItem(keyName, keyValue).
And your code is setting the keyName argument to the value you are getting from the form and keyValue argument to an empty string; not what you need.
Make the following changes and you should be good to go (see comments):
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
// set local storage values
localStorage.setItem("name", name); // modified
localStorage.setItem("email", email); // modified
localStorage.setItem("phoneno", phoneno); // modified
location.reload();
}
console.log(localStorage); // new (maybe unnecessary)
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `${upFirst(key)}: ${value}<br>`; // modified
}
localStorage.clear();
/**
* new: making the first letter an upper case (for labels in the output div).
* See usage in 'for loop' above.
*/
function upFirst(stringValue) {
return stringValue.slice(0, 1).toUpperCase() + stringValue.slice(1);
}

javascript: changing the name attribute dynamically

I have this script I'm working on and there's no errors on it but I want to add some functions on it like when I click the button it adds but I want the name attribute of the input text to be changed too.
Here's my script:
javascript:
var a = 1;
function add() {
var fContent = document.getElementById('1');
var sContent = document.getElementById('2');
if (a <= 10) {
a++;
var objTo = document.getElementById('m');
var divtest = document.createElement("div");
divtest.innerHTML = (sContent.innerHTML + a + fContent.innerHTML);
alert(divtest.innerHTML);
objTo.appendChild(divtest);
}
}
html:
<input type="button" onclick="add();" value="+" />
<div id="m">
<div id="1">
<input type="text" name="f">
<input type="text" name="l">
<input type="text" name="m">
</div>
<div id="2"></div>
</div>
OUTPUT:
2
<input type="text" name="f">
<input type="text" name="l">
<input type="text" name="m">
EXPECTED OUTPUT:
2
<input type="text" name="f2">
<input type="text" name="l2">
<input type="text" name="m2">
and so on...
You're not doing anything to change the name attributes. Trying to make those changes with html concatenation will get you into trouble. This will get you started:
(function() {
var a = 1;
// get a reference to the container
var container = document.getElementById("m");
// get a reference to the first row of input
var base = container.children[0];
document.querySelector("button").addEventListener("click", function(e) {
if(++a > 10) return;
// clone the first row of input
var clone = base.cloneNode(1);
// change the number text by setting the span's textContent
clone.children[0].textContent = a;
// set the names of the input fields
clone.children[1].name = "f" + a;
clone.children[2].name = "l" + a;
clone.children[3].name = "m" + a;
// add the new row to the container
container.appendChild(clone);
console.log(clone);
});
})();
<button type="button">+</button>
<div id="m">
<div><span>1</span><input type="text" name="f1"><input type="text" name="l1"><input type="text" name="m1"></div>
</div>
If you'd rather create the elements from scratch...
(function() {
var a = 1;
// get a reference to the container
var container = document.getElementById("m");
var input;
var span;
var div;
document.querySelector("button").addEventListener("click", function(e) {
if(++a > 10) return;
// create our div
div = document.createElement("div");
// create and append our span
span = document.createElement("span");
span.textContent = a;
div.appendChild(span);
// create and append inputs
["f","l","m"].forEach(function(n){
input = document.createElement("input");
input.name = n + a;
div.appendChild(input);
});
// append our div
container.appendChild(div);
console.log(div);
});
})();
<button type="button">+</button>
<div id="m">
<div><span>1</span><input type="text" name="f1"><input type="text" name="l1"><input type="text" name="m1"></div>
</div>

Get the element name attribute in JavaScript

How can I get the element name attribute in JavaScript?
HTML :
<input class="so" name="Name" value="bob"></input>
<input class="so" name="LastName" value="Feyzi"></input>
<input class="so" name="Email"></input>
<input class="so" name="Address"></input>
<input type="submit"></input>
JavaScript :
var person={};
var cars = document.querySelectorAll(".so");
for (i = 0; i < cars.length; i++) {
var elname = document.getElementByClassName('.so')[i].getAttribute('name');
//var eln = document.getElementsByTagName("input")[i].getAttribute("name");
var vala = document.querySelectorAll('.so')[i].value;
//alert(vala);
alert(elname);
}
After I run the script I want the person object to be set with this data:
person {
Name: "bob",
LastName: "Feyzi",
Email: "",
Adderss: ""
}
JSFiddle
Use the collection that you've already found with querySelectorAll to get the values of the value and name attributes :
var person = {}
var cars = document.querySelectorAll(".so")
for (i = 0; i < cars.length; i++) {
person[cars[i].name] = cars[i].value
}
console.log(person)
JSFiddle
Because getElementByClassName does not exist (also it would have no use in your script). Use this:
var person={};
var cars = document.querySelectorAll(".so");
for (i = 0; i < cars.length; i++) {
alert(cars[i].name)
}
Firstly, use cars variable instead of calling querySelectorAll every time.
Secondly, use addEventListener to execute code on click.
Fiddle: http://jsfiddle.net/guyavunf/3/
Code:
// HTML
<input class="so" name="Name" value="bob"></input>
<input class="so" name="LastName" value="Feyzi"></input>
<input class="so" name="Email"></input>
<input class="so" name="Address"></input>
<input class="submit" type="submit"></input>
// JS
document.querySelector('.submit').addEventListener('click', function() {
var person={};
var cars = document.querySelectorAll(".so");
for (i = 0; i < cars.length; i++) {
var name = cars[i].name;
var value = cars[i].value;
alert(name + ': ' + value);
}
});

Categories

Resources