DOM createElement() dynamically with click event to div specific url element - javascript

I am attempting to build a 9 divs (cards) dynamically containing information about store branch locations. Each card has a unique URL associated with it that links to each branches specific URL.
This approach, within the function, appends the first (0) URL to all the cards:
$("div").click(function() {
window.location = $(this).find("a").attr("href");
return false;
});
This approach appends the last URL (8) to all the cards:
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(prop.pages_url);
})
Code I'm working with:
function buildLocationList(data) {
for (i = 0; i < 9; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
//Create Card
var branches = document.getElementById('branches');
var url = branches.appendChild(document.createElement('a');
url.setAttribute('href', prop.pages_url);
)
var branch = branches.appendChild(document.createElement('div'));
branch.className = 'card';
branch.id = "branch-" + i;
branch.url = prop.pages_url;
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(prop.pages_url);
})
//Append Branch Card Details
v
var company = branch.appendChild(document.createElement('h5'));
company.innerHTML = prop.name + '<br />';
var distancePhone = branch.appendChild(document.createElement('p'));
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
distancePhone.innerHTML = '<span class="miles">Approx. ' + roundedDistance + ' miles</span>' + '<span class="location-phone">' + prop.phone_number + '</span>';
}
else {
distancePhone.innerHTML = prop.phone_number;
}
var address = branch.appendChild(document.createElement('p'));
if (prop.address_line_2) {
address.innerHTML += prop.address_line_1 + ', ' + prop.address_line_2 + '<br />';
}
else {
address.innerHTML += prop.address_line_1 + '<br />';
};
address.innerHTML += prop.address_city + ', ' + prop.address_state + ' ' +prop.address_postal_code + '</p>';
}
}
I would like the card to be clickable with a redirect to each branch's unique URL.

You're storing the URL on the card element:
branch.url = prop.pages_url
All you need to do in the click handler is access the property:
branch.addEventListener("click", function(e){
e.preventDefault();
window.open(e.currentTarget.url);
})
In the context of the event handler, e.currentTarget is the element to which the handler is attached. If you were interested in which element fired the event, you'd use e.target.
Here's your code snippet modified below. I don't think the links will open on here though due to the sandboxed iframe.
function buildLocationList(data) {
for (i = 0; i < data.features.length; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
//Create Card
var branches = document.getElementById('branches');
var url = branches.appendChild(document.createElement('a'));
url.setAttribute('href', prop.pages_url);
var branch = branches.appendChild(document.createElement('div'));
branch.className = 'card';
branch.id = "branch-" + i;
branch.url = prop.pages_url;
branch.addEventListener("click", function(e){
e.preventDefault();
console.log(e.currentTarget.url);
window.open(e.currentTarget.url);
})
//Append Branch Card Details
var company = branch.appendChild(document.createElement('h5'));
company.innerHTML = prop.name + '<br />';
var distancePhone = branch.appendChild(document.createElement('p'));
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
distancePhone.innerHTML = '<span class="miles">Approx. ' + roundedDistance + ' miles</span>' + '<span class="location-phone">' + prop.phone_number + '</span>';
}
else {
distancePhone.innerHTML = prop.phone_number;
}
var address = branch.appendChild(document.createElement('p'));
if (prop.address_line_2) {
address.innerHTML += prop.address_line_1 + ', ' + prop.address_line_2 + '<br />';
}
else {
address.innerHTML += prop.address_line_1 + '<br />';
};
address.innerHTML += prop.address_city + ', ' + prop.address_state + ' ' +prop.address_postal_code + '</p>';
}
}
buildLocationList({features:[{
properties: {
distance: 100,
name: 'Google',
pages_url: 'https://www.google.com',
phone_number: '123-456-7890',
address_line_1: '1234 Street',
address_city: 'Citytown',
address_state: 'State',
address_postal_code: '12345'
}
},{
properties: {
distance: 200,
name: 'Microsoft',
pages_url: 'https://www.microsoft.com',
phone_number: '123-456-7890',
address_line_1: '1234 Street',
address_city: 'Citytown',
address_state: 'State',
address_postal_code: '12345'
}
}]})
.card {
border: 1px solid #ccc;
padding: 10px;
max-width: 50%;
margin: 10px;
}
<div id="branches"></div>

<div>
w3schools
</div>
<script>
$("div").click(function() {
window.location = $(this).find("a").data("value");
});
</script>

Related

Why isn't this code save data in local storage (undefined)

When creating new div with data from input form, the first div save the data that i inputed, but next, when i input new data, div display undefined value.
first attempt second attempt
0: {name: "Milk", amount: "30"}
name: "Milk"
amount: "30"
1: "expense"
2: "expense"
3: "expense"
document.getElementById('expenseInput').addEventListener('submit', saveExpense);
function saveExpense(e) {
let expenseName = document.getElementById('expenseNameInput').value,
expenseAmount = document.getElementById('expenseAmountInput').value;
let expenseStorage = {
name: expenseName,
amount: expenseAmount,
}
if (localStorage.getItem('expenses') == null) {
let expenses = [];
expenses.push(expenseStorage);
localStorage.setItem('expenses', JSON.stringify(expenses));
} else {
let expenses = JSON.parse(localStorage.getItem('expenses'));
expenses.push('expenseStorage');
localStorage.setItem('expenses', JSON.stringify(expenses));
}
document.getElementById('expenseInput').reset();
fetchExpense();
e.preventDefault();
}
function fetchExpense() {
let expenses = JSON.parse(localStorage.getItem('expenses')),
expensesList = document.getElementById('expensesList');
expensesList.innerHTML = '';
for (let i = 0; i < expenses.length; i++) {
let name = expenses[i].name,
amount = expenses[i].amount;
expensesList.innerHTML += '<div class="well" id="expense-item">' +
'<h3>' + name + '</h3>' +
'<h3>' + amount + '</h3>' +
'Delete' +
'</div>';
}
}
I'm rewriting code many times but it doesnt's work.
Try replacing expenses.push('expenseStorage') to expenses.push(expenseStorage).
So your code will look like this:
document.getElementById('expenseInput').addEventListener('submit', saveExpense);
function saveExpense(e) {
let expenseName = document.getElementById('expenseNameInput').value,
expenseAmount = document.getElementById('expenseAmountInput').value;
let expenseStorage = {
name: expenseName,
amount: expenseAmount,
}
if (localStorage.getItem('expenses') == null) {
let expenses = [];
expenses.push(expenseStorage);
localStorage.setItem('expenses', JSON.stringify(expenses));
} else {
let expenses = JSON.parse(localStorage.getItem('expenses'));
expenses.push(expenseStorage);
localStorage.setItem('expenses', JSON.stringify(expenses));
}
document.getElementById('expenseInput').reset();
fetchExpense();
e.preventDefault();
}
function fetchExpense() {
let expenses = JSON.parse(localStorage.getItem('expenses')),
expensesList = document.getElementById('expensesList');
expensesList.innerHTML = '';
for (let i = 0; i < expenses.length; i++) {
let name = expenses[i].name,
amount = expenses[i].amount;
expensesList.innerHTML += '<div class="well" id="expense-item">' +
'<h3>' + name + '</h3>' +
'<h3>' + amount + '</h3>' +
'Delete' +
'</div>';
}
}

Clear previous results from query

Through the attached code I do a search on youtube based on the username and the results are shown. If I search twice, the results add up. I would like previous results to be deleted. I try with htmlString = card; but it show only one result.Thanks to everyone who wants to help me solve this problem.
var musicCards = [];
jQuery(document).ready(function() {
jQuery("#searchButton").on("click", function() {
var query = jQuery("#queryInput").val();
if (query != "") {
loadYoutubeService(query);
console.log(query + "");
}
});
});
function loadYoutubeService(query) {
gapi.client.load('youtube', 'v3', function() {
gapi.client.setApiKey('ADADADADADA');
search(query);
});
}
function search(query) {
var request = gapi.client.youtube.search.list({
part: 'snippet',
q: query,
type: 'channel',
maxResults: 15
});
request.execute(function(response) {
jQuery.each(response.items, function(i, item) {
if (!item['']) {
var musicCard = {};
musicCard._id = item['snippet']['customUrl'];
musicCard.title = item['snippet']['title'];
musicCard.linkprofilo = item['snippet']['channelId'];
musicCard.url = "https://www.youtube.com/channel/";
musicCard.description = item['snippet']['description'];
musicCard.immagine = item['snippet']['thumbnails']['high']['url'];
musicCards.push(musicCard);
}
});
renderView();
});
}
function renderView() {
var htmlString = "";
musicCards.forEach(function(musicCard, i) {
var card = createCard(musicCard._id, musicCard.title, musicCard.description, musicCard.url,musicCard.immagine, musicCard.linkprofilo);
htmlString += card;
});
jQuery('#youtube-utente').html(htmlString);
}
function createCard(_id, title, description, url, immagine, linkprofilo) {
var card =
'<div class="card">' +
'<div class="info">' +
'<img src="' + immagine + '" alt="' + description + '">' +
'</div>' +
'<div class="content">Clicca per selezionare:' +
'<h3>' + title + '</h3>' +
'<a class="seleziona" href="' + url +linkprofilo+'">'+ url +linkprofilo+'</a>' +
'<p>' + description + '</p>' +
'</div>' +
'</div>';
return card;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
Solved using :
request.execute(function(response) {
musicCards.length = 0; // clear array

Error unexpected token }, Unexpected identifier

When i click click_profile_list i get error
or Uncaught SyntaxError: Unexpected identifier
function click_profile_list(choice, profileid, i_array) {
if(choice==0) {
alert("Profile", i_array.firstname);
}
else {
alert("Profile 2" , i_array.firstname);
}
}
for(var key in msg.db) {
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email,
};
//html = '<div class="rows" onclick=click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');>' ;
html = '<div class="rows" onclick="click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');">' ;
html += msg.db[key].id + ' - ';
html += msg.db[key].firstname + ' - ';
html += msg.db[key].lastname + ' - ';
html += msg.db[key].fallback;
html += '</div>' ;
$('#show_list_window_body').append(html);
}
EDIT: , is removed, onclick="function();" added
$('#show_list_window_body').html(html);
for(var key in msg.db) {
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email
};
var tmp_id = 'iDontKnow' + msg.db[key].id;
html = '<div class="rows" id="' + tmp_id + '">' ;
html += msg.db[key].id + ' - ';
html += msg.db[key].firstname + ' - ';
html += msg.db[key].lastname;
html += '</div>' ;
$('#show_list_window_body').append(html);
let $elem = $("<div class='rows' id='" + tmp_id + "'>");
$elem.click( () => click_profile_list(input, msg.db[key].id, bypass) );
}
Remove the extra comma at the end of your object :
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email, // <-- Remove this comma
};
Then, add double quotes around your onclick function :
html = '<div class="rows" onclick="click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');">'
Or (much) better, attach a click handler instead of inline javascript :
let $elem = $("<div class='rows'>")
$elem.click( () => click_profile_list(input, msg.db[key].id, bypass) )
let $clickme = $("<div>Click me!</div>")
$clickme.click(() => alert("it works!"))
$("#main").append($clickme)
#main * {
font-size: x-large;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main"></div>
Here's a proper jQuery solution:
const msg = {};
msg.db = {
alice: {
firstname: "Alice",
lastname: "Bob",
user_email: "alice#bob.com",
id: 1,
fallback: "fallback"
},
charlie: {
firstname: "Charlie",
lastname: "Delta",
user_email: "charlie#delta.com",
id: 2,
fallback: "fallback2"
}
};
function click_profile_list(e) {
$el = $(e.target);
var choice = 0; // get from whatever sets this
var user = msg.db[$el.data("key")];
if (choice == 0) {
alert(user.firstname);
}
}
var input = 0;
for (var key in msg.db) {
var user = msg.db[key];
$user = $("<div>").addClass("rows").data("key", key);
$user.text([user.id, user.firstname, user.lastname, user.fallback].join(" - "));
$('#show_list_window_body').append($user);
}
$('#show_list_window_body').on("click", ".rows", click_profile_list);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="show_list_window_body"></div>
The list doesn't get awkward inline onclick code that tries to pass an object; instead each list item gets a data-key attribute referencing the database key. When clicked, the key is read back; this is used to grab the relevant data from the db.
You have two syntactical mistakes. One in your JavaScript and one in the HTML markup you produce.
JS
var bypass = {
firstname: msg.db[key].firstname,
lastname: msg.db[key].lastname,
email: msg.db[key].user_email, // <--- here is your issue, you should not use a comma after the last object element
};
HTML
html = '<div class="rows" onclick=click_profile_list(' + input + ',' + msg.db[key].id + ',' + bypass + ');>' ;
You must wrap the value of the attribute onclick with single or double quotes. In your code, just wrap it with double quotes onclick="...;"
Look #Jeremy Thille's answer for a better way to do this.

How to get next row of HTML table based on some condition using jQuery?

Ok, I am new to JQuery and I have requirement to do some manipulation on table based on rows.
The table consists of rows which belong to 3 different style classes Brand have category and category have products.
var table = $("table tbody");
table.find(".brand").each(function(i) {
var $tdsBrand = $(this).find("td"),
brand = $tdsBrand.eq(0).text(),
atyBrand = $tdsBrand.eq(1).text(),
alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (i + 1) + ':\nBrand Name: ' + brand + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var brandClass = $(this).attr("class");
console.log('brand class : ' + brandClass);
if (this row has next row as category) {
//if(brand.next($( "tr[class='category']" ))) {
//if ("(.band):has(.category)") {
//if ($(this).parents(".category").length == 1) {
table.find(".category").each(function(i) {
var catClass = $(this).attr("class");
console.log('category class : ' + catClass);
var $tdsCategory = $(this).find("td"),
category = $tdsCategory.eq(0).text(),
atyCategory = $tdsCategory.eq(1).text(),
alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row ' + (i + 1) + ':\nCategory Name: ' + category + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
if (This row has next row as product) {
//if(next($( "tr[class='product']" ))) {
//if ("(.category):has(.product)") {
//if ($(this).parents("product").length == 1) {
table.find(".product").each(function(i) {
var proClass = $(this).attr("class");
console.log('product class : ' + proClass);
var $tds = $(this).find("td"),
product = $tds.eq(0).text(),
aty = $tds.eq(1).text(),
aly = $tds.eq(2).text();
console.log('Product Row ' + (i + 1) + ':\nProduct Name: ' + product + '\nActual TY: ' + aty + '\nActual LY: ' + aly);
});
}
});
}
});
What I want to do is, I have to sum up Actual TY values of products and display them on their category. Then sum up Actual TY of categories (which has been calculated from products for different categories) to their brand.
Please refer http://jsfiddle.net/cfhhz0zr/46/ for clear understanding of my requirement and code which I've tried till now.
Thank you.
Just modified a bit your code and it seems that is doing what you are looking for. See also the http://jsfiddle.net/88prg1dt/
I refactored a bit and renamed some variables to make a bit more sense so should be fairly clear now. If you want to calculate the total for a product / category now should be really super simple.
Here is the JS code:
var $table = $("table tbody");
$table.find(".brand").each(function (brandIndex) {
var $brandRow = $(this);
var $tdsBrand = $(this).find("td");
var brandName = $tdsBrand.eq(0).text();
var atyBrand = $tdsBrand.eq(1).text();
var alyBrand = $tdsBrand.eq(2).text();
console.log('Brand Row ' + (brandIndex + 1) + ':\nBrand Name: ' + brandName + '\nActual TY: ' + atyBrand + '\nActual LY: ' + alyBrand);
var $categoryRows = $brandRow.nextUntil('.brand').filter('.category');
$categoryRows.each(function (categoryIndex) {
var $categoryRow = $(this);
var $tdsCategory = $categoryRow.find("td");
var categoryName = $tdsCategory.eq(0).text();
var atyCategory = $tdsCategory.eq(1).text();
var alyCategory = $tdsCategory.eq(2).text();
console.log('Category Row: ' + (categoryIndex + 1) + ':\nCategory Name: ' + categoryName + '\nActual TY: ' + atyCategory + '\nActual LY: ' + alyCategory);
var $productRows = $categoryRow.nextUntil('.brand, .category').filter('.product');
$productRows.each(function (productIndex) {
var $productRow = $(this);
var $tdProducts = $productRow.find("td");
var productName = $tdProducts.eq(0).text();
var atyProduct = $tdProducts.eq(1).text();
var aly = $tdProducts.eq(2).text();
console.log('Product Row ' + (productIndex + 1) + ':\nProduct Name: ' + productName + '\nActual TY: ' + atyProduct + '\nActual LY: ' + aly);
});
});
});
I played a bit with jQuery nextUntil() method as the documentation:
Description: Get all following siblings of each element up to but not
including the element matched by the selector, DOM node, or jQuery
object passed.
Is this answering your question ?

I need Javascript syntax and logic advice

I have a two part question. The first is that I tried to replace all of my document.write with innerHTML and now nothing generates on the page correctly. The second part of my question is that I can't figure out the logic on my toggleCurrent function so that I can hide show the currently displayed view. example - if the thumbnail view is visible I want to hide/show or if the full view is visible I want to hide/show that. http://jsfiddle.net/5M3k7/
//Creating generic Object
function Person(name,age,biog,thumb,char,bg,cider) {
this.fullName = name;
this.age = age;
this.biog = biog;
this.thumb = thumb;
this.char = char;
this.bg = bg;
this.cider = cider;
}
//Creating new Objects
var jay = new Person ("Jay Jones",24,"Story","img","guy","bg","Fleet",true);
var jai = new Person ("Jai Janes",23,"Story","img","gal","bg","Sleet",true);
var dan = new Person ("Dan Dones",19,"Story","img","guy","bg","Leet",true);
var den = new Person ("Den Danes",49,"Story","img","guy","bg","Treat",true);
var dun = new Person ("Dun Dunes",20,"Story","img","guy","bg","Meet",true);
var vim = new Person ("Vim Vanes",22,"Story","img","guy","bg","Meat",true);
//Defining arrays
var characters = [jay, jai, dan, den, dun, vim];
//For loop goes though character array and prints it out.
var thumbs = function() {
var full = document.getElementById('full');
var cLength = characters.length;
for (var i = 0; i < cLength; i++){
full.innerHTML = '<div class="wrap"><div class="cont">' + "Name: " + characters[i].fullName + '<br/>' + 'Age: ' + characters[i].age + '<br/>' + 'Cider: ' + characters[i].cider + '</div></div>';
}
return;
};
var full = function() {
var thumb = document.getElementById('fullthumb');
var cLength = characters.length;
for (var i = 0; i < cLength; i++){
thumb.innerHTML = '<div class="fullwrap"><div class="bg"><div class="fullcont">Name: '
+ characters[i].fullName + '<br/> Age:' + characters[i].age + '<br/>Cider:' + characters[i].cider + '<div class="char"></div></div></div></div>';
}
return;
};
//Toggle Function
function toggleMenuDiv() {
var full = document.getElementById('full');
var thumb = document.getElementById('fullthumb');
var butt = document.getElementById('button');
if (full.style.display == 'none') {
full.style.display = 'block';
thumb.style.display = 'none';
butt.innerHTML = 'THUMB VIEW<span class="arrow-e"></span>';
}
else {
full.style.display = 'none';
thumb.style.display = 'block';
butt.innerHTML = 'FULL VIEW<span class="arrow-e"></span>';
}
}
//Toggle Function
function toggleCurrent() {
var chng = document.getElementById('change');
var thumb = document.getElementById('fullthumb');
var full = document.getElementById('full');
while (full.style.display == 'none')
{
if(thumb.style.display == 'block') {
chng.innerHTML = 'HIDE<span class="arrow-n"></span>';
}else{
thumb.style.display = 'none';
chng.innerHTML = 'SHOW<span class="arrow-s"></span>';
}
}
}
Because you keep overriding the last thing entered in.
full.innerHTML = '<div class="wrap"><div class="cont">' + "Name: " + characters[i].fullName + '<br/>' + 'Age: ' + characters[i].age + '<br/>' + 'Cider: ' + characters[i].cider + '</div></div>';
You are need to append to the innerHTML
full.innerHTML = full.innerHTML + '<div class="...

Categories