Change DIV content based on Toggle button clicked - javascript

If user click "Twin Bed" or "King Bed", Content inside "demand-message" have to change either "high demand" or "Only ??? rooms left".
ID will be same for button because of existing logic. Now my message to display on "demand-message" is not changing if i click "King Bed". It displays correctly for "Twin Bed".
Is it possible to change message by getting ID with data-bed-type attribute to match and change the message (either high demand or No. of rooms left)?
HTML:
<div class="col-lg-4 col-md-12 col-sm-12 col-12 left-container">
<div class="demand-message--wrapper">
<div class="demand-message"></div>
</div>
<div class="left-column">
<div class="btn-group">
<button type="button" data-bed-container-id="deluxe-balcony-room" data-bed-max="190" data-bed-type="twin">Twin Bed</button>
<button type="button" data-bed-container-id="deluxe-balcony-room" data-bed-max="90" data-bed-type="king">King Bed</button>
</div>
</div>
JS:
function onToggleBed(e) {
var thisButton = $(e.currentTarget);
var bedTypeSelected = thisButton.data('bed-type');
var bedValueSelected = thisButton.data('bed-value');
var roomContianerId = thisButton.data('bed-container-id');
var buttonMaxRoom = thisButton.data('bed-max');
var message = '';
if (buttonMaxRoom < 100) {
message = 'Only ' + buttonMaxRoom + ' rooms left';
} else if (buttonMaxRoom > 100) {
message = 'In high demand';
}
if (message == '') {
$('#' + roomContianerId + ' .demand-message').hide();
} else {
$('#' + roomContianerId + ' .demand-message').show();
$('#' + roomContianerId + ' .demand-message').html(message);
}
}

As I mentioned in my comment, hypens will removed and turned into camelCase.
In this case use:
var bedTypeSelected = thisButton.data('bedType');
Let's console.log(thisButton.data()); to see your data items.

Related

HTML Button does not call the onclick event

When I run this webpage I cannot get the Buttons to run the click event. I am creating the contents of the page via javascript in the window.onload function but the event handlers for the buttons are not working. I can't get the buttons to write to the console.
var items = [
"Item 1",
"Item 2",
"item 3",
"item ......etc"
];
window.onload = function() {
// Get container element to append the new element
var container = document.getElementById("myContainer");
// create an HTML element row for each item in the array
for (let i = 0; i < items.length; i++) {
console.log(items[i]);
let strItem = items[i];
// Create a new div element
let newDiv = document.createElement('div');
newDiv.innerHTML = '<div class="row mx-auto py-1"> \
<div class="col-12 col-sm-8 px-5"> \
<label>' + (i + 1) + ' ' + strItem + '</label> \
</div> \
<div class="col-12 col-sm-4 d-inline-block"> \
<button id="btn' + (i + 1) + '" class="btn btn-primary btn-block btn-sm d-sm-none">Button ' + (i + 1) + '</button> \
<button id="btn' + (i + 1) + '" class="btn btn-primary btn-sm d-none d-sm-inline-block">Button ' + (i + 1) + '</button> \
</div> \
</div>';
// Append the new element
container.appendChild(newDiv);
// Get the button element
let button = document.getElementById('btn' + (i + 1));
// Add an event listener to the button
button.addEventListener('click', function() {
// Do something when the button is clicked
console.log('Button ' + (i + 1) + ' was clicked');
});
}
};
<section id="myContainer"></section>
The first issue is, that your buttons don't have a unique ID. That's why only the first button work.
Then you should move the eventListener out of the for loop and use querySelectorAll to select all your buttons. Then you use the forEach iteration to add the eventListener to all those buttons.
Last but not least use an Event Delegation (parameter inside the function of the eventListener). With that you can read out the id of the clicked button with: parameter.target.id.
var items = [
"Item 1",
"Item 2",
"item 3",
"item 4"
];
window.addEventListener('DOMContentLoaded', function() {
// Get container element to append the new element
const CONTAINER = document.getElementById('myContainer');
// create an HTML element row for each item in the array
for (let i = 1; i < items.length + 1; i++) {
let strItem = items[i-1];
// Create a new div element
let newDiv = document.createElement('div');
newDiv.innerHTML = `<div class="row mx-auto py-1">
<div class="col-12 col-sm-8 px-5">
<label>${i} ${strItem}</label>
</div>
<div class="col-12 col-sm-4 d-inline-block">
<button id="btn${i}-1" class="btn btn-primary btn-block btn-sm d-sm-none">Button ${i}-1</button>
<button id="btn${i}-2" class="btn btn-primary btn-sm d-none d-sm-inline-block">Button ${i}-2</button>
</div>
</div>`;
// Append the new element
CONTAINER.appendChild(newDiv);
}
//gets all the buttons
const BUTTONS = document.querySelectorAll('button');
//adds an EventListener to all the buttons
BUTTONS.forEach(button =>
button.addEventListener('click', function(element) {
let buttonID = element.target.id;
console.log(`Button ${buttonID} was clicked`);
})
)
});
<section id="myContainer"></section>
I refactored your code to be cleaner and up to current standards.

Button generated inside javascript code to onclick insert value in input type text in form

I have a very nice SEO-keyword suggestion tool working with CKeditor, it displays the most used word in the text while writing. The problem is that I want to make these generated keywords clickable one by one. So when you click on a keyword, it auto-fills an input-type text.
Here is the HTML code:
<!-- Textarea -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Insert your text here </label>
<div class="col-md-10">
<textarea class="form-control" id="editor1" name="editor1"><p>text example with ahöäåra</p></textarea>
</div>
</div>
<!-- KW density result -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Suggested SEO keywords</label>
<div class="col-md-10">
<div id="KWdensity" ></div>
</div>
</div>
Here is the javascript code:
<script type="text/javascript">
$(document).ready(function() {
CKEDITOR.replace('editor1');
$(initKW);
CKEDITOR.instances.editor1.on('contentDom', function() {
CKEDITOR.instances.editor1.document.on('keyup', function(event) {
$(initKW);
});
});
function KeyDensityShow(srctext, MaxKeyOut, keylenMin) {
var Output;
var words = srctext.toLowerCase().split(/[^\p{L}\p{M}\p{N}]+/u)
var positions = new Array()
var word_counts = new Array()
try {
for (var i = 0; i < words.length; i++) {
var word = words[i]
if (!word || word.length < keylenMin) {
continue
}
if (!positions.hasOwnProperty(word)) {
positions[word] = word_counts.length;
word_counts.push([word, 1]);
} else {
word_counts[positions[word]][1]++;
}}
word_counts.sort(function(a, b) {
return b[1] - a[1]
})
return word_counts.slice(0, MaxKeyOut)
} catch (err) {
return "";
}}
function removeStopWords(input) {
var stopwords = ['test', ];
var filtered = input.split(/\b/).filter(function(v) {
return stopwords.indexOf(v) == -1;
});
stopwords.forEach(function(item) {
var reg = new RegExp('\\W' + item + '\\W', 'gmi');
input = input.replace(reg, " ");
});
return input.toString();
}
function initKW() {
$('#KWdensity').html('');
var TextGrab = CKEDITOR.instances['editor1'].getData();
TextGrab = $(TextGrab).text();
TextGrab = removeStopWords(TextGrab);
TextGrab = TextGrab.replace(/\r?\n|\r/gm, " ").trim();
TextGrab = TextGrab.replace(/\s\s+/g, " ").trim();
if (TextGrab != "") {
var keyCSV = KeyDensityShow(TextGrab, 11, 3);
var KeysArr = keyCSV.toString().split(',');
var item, items = '';
for (var i = 0; i < KeysArr.length; i++) {
item = '';
item = item + '<b>' + KeysArr[i] + "</b></button> ";
i++;
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"><span class="badge">' + KeysArr[i] + "</span> " + item;
items = items + item;
}
$('#KWdensity').html(items);
}}});
</script>
And here is some extra HTML for the input that needs to be auto-filled.
The keywords box:
<input type="text" id="thebox" value="" style="width:80%;height:30px;background:#000;color:#fff;"/>
<br><input type="button" value="this one is working" onclick="document.getElementById('thebox').value='test button is working';">
So if you write something, it will generate keywords buttons. When you click on one of these buttons, the keyword must be entered in the input text like this
keyword,
Here is a Fiddle DEMO.
Any idea how to fix that? I added a document.getElementById('thebox'). but it does not return anything
Your code in
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"><span class="badge">' + KeysArr[i] + "</span> " + item;
Will add to the DOM (in other words, to the HTML of the page), the following bit:
<button
class="btn btn-default btn-xs"
type="button"
onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"
>
Now, the resulting onclick above has some problems. First, notice that the quotes it uses in the string after .value= are actually closing the onclick declaration because they are not escaped. I mean, instead of
onclick="document.getElementById(thebox).value="head of gwyneth paltrow";"
^--- problem here ^--- and here
It should've been
onclick="document.getElementById(thebox).value=\"head of gwyneth paltrow\";"
^--- fixed here ^--- and here
Secondly, the argument to .getElementById(thebox) is thebox. Notice here that the way it is now, thebox is actually a variable, not a string. So instead of the above, what you want is:
onclick="document.getElementById(\"thebox\").value=\"head of gwyneth paltrow\";"
^--- ^--- fixed here
These fixes should be enough to make the clicks on the words set the "head of gwyneth paltrow" value in the textbox.
I believe, though, you want to actually set the key when the button is clicked. To do that, instead of having "head of gwyneth paltrow" after the .value, you should have the text of the key. All in all, here's how that line could be:
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(\'thebox\').value=\'' + key + '\';"><span class="badge">' + KeysArr[i] + "</span> " + item;
^-- ^-- ^^^^^^^^^^^^^^--- changed here (notice in the demo below I declare the key variable before using it here)
Updated fiddle here. Running demo below as well.
$(document).ready(function() {
CKEDITOR.replace('editor1');
$(initKW);
CKEDITOR.instances.editor1.on('contentDom', function() {
CKEDITOR.instances.editor1.document.on('keyup', function(event) {
$(initKW);
});
});
function KeyDensityShow(srctext, MaxKeyOut, keylenMin) {
var Output;
var words = srctext.toLowerCase().split(/[^\p{L}\p{M}\p{N}]+/u)
var positions = new Array()
var word_counts = new Array()
try {
for (var i = 0; i < words.length; i++) {
var word = words[i]
if (!word || word.length < keylenMin) {
continue
}
if (!positions.hasOwnProperty(word)) {
positions[word] = word_counts.length;
word_counts.push([word, 1]);
} else {
word_counts[positions[word]][1]++;
}
}
word_counts.sort(function(a, b) {
return b[1] - a[1]
})
return word_counts.slice(0, MaxKeyOut)
} catch (err) {
return "";
}
}
function removeStopWords(input) {
var stopwords = ['test', ];
var filtered = input.split(/\b/).filter(function(v) {
return stopwords.indexOf(v) == -1;
});
stopwords.forEach(function(item) {
var reg = new RegExp('\\W' + item + '\\W', 'gmi');
input = input.replace(reg, " ");
});
return input.toString();
}
function initKW() {
$('#KWdensity').html('');
var TextGrab = CKEDITOR.instances['editor1'].getData();
TextGrab = $(TextGrab).text();
TextGrab = removeStopWords(TextGrab);
TextGrab = TextGrab.replace(/\r?\n|\r/gm, " ").trim();
TextGrab = TextGrab.replace(/\s\s+/g, " ").trim();
if (TextGrab != "") {
var keyCSV = KeyDensityShow(TextGrab, 11, 3);
var KeysArr = keyCSV.toString().split(',');
var item, items = '';
var previousKeys = [];
for (var i = 0; i < KeysArr.length; i++) {
item = '';
var key = KeysArr[i];
previousKeys.push(key);
item = item + '<b>' + key + "</b></button> ";
i++;
item = '<button class="btn btn-default btn-xs" type="button" onclick="document.getElementById(\'thebox\').value=\'' + previousKeys.join(', ') + '\';"><span class="badge">' + KeysArr[i] + "</span> " + item;
items = items + item;
}
$('#KWdensity').html(items);
}
}
});
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="//cdn.ckeditor.com/4.6.1/standard/ckeditor.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Insert your text here </label>
<div class="col-md-10">
<textarea class="form-control" id="editor1" name="editor1"><p>text example with ahöäåra</p></textarea>
</div>
</div>
<!-- KW density result -->
<div class="form-group">
<label class="col-md-2 control-label" for="editor1">Suggested SEO keywords</label>
<div class="col-md-10">
<div id="KWdensity" ></div>
</div>
</div>
The keywords box: <input type="text" id="thebox" value="" style="width:80%;height:30px;background:#000;color:#fff;"/>
<br><input type="button" value="this one is working" onclick="document.getElementById('thebox').value='test button is working';">

Why reset my value after create new textarea?

I have following problem, with this code i can create a room with a textarea, after i fill this with values and create a new room and fill again will resets all first textarea's only the last have values...
var rooms = {};
function addRoom(name, data) {
rooms[name] = data;
}
function updateRoom(name, key, value) {
rooms[name][key] = value;
}
var Room = function() {
this.description = 0;
};
function createroom() {
var roomname = document.getElementById('innerhtml').value;
var coldiv = document.createElement('div');
coldiv.className = "col-md-6 mb-3";
coldiv.setAttribute("id", `room_col_${roomname}`);
var room = document.createElement('div');
room.className = "text-center roombox";
room.innerHTML = roomname;
room.setAttribute("id", `room_count_${roomname}`);
room.setAttribute("data-toggle", `modal`);
room.setAttribute("data-target", `#room${roomname}`);
var roomnamehidden = document.createElement('input');
roomnamehidden.setAttribute("name", "roomname");
roomnamehidden.setAttribute("type", "hidden");
roomnamehidden.setAttribute("value", `${roomname}`);
document.getElementById("rooms").appendChild(coldiv).appendChild(room);
document.getElementById("rooms").appendChild(roomnamehidden);
document.getElementById("rooms").innerHTML += '<div class="modal fade" id="' + `room${document.getElementById('innerhtml').value}` + '" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" xmlns="http://www.w3.org/1999/html"><div class="modal-dialog modal-lg" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="exampleModalLabel">Inventar für <b>' + `${document.getElementById('innerhtml').value}` + '</b> hinzufügen</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="modal-body"><textarea name="description" class="form-control" rows="5" placeholder="description here..." id="' + `${document.getElementById('innerhtml').value}_description` + '"></textarea></div><div class="modal-footer"><button data-dismiss="modal" aria-label="Close" class="btn btn-primary" onclick="updateRoomItems(\'' + `${document.getElementById('innerhtml').value}` + '\')" id="' + `saveall${document.getElementById('innerhtml').value}` + '">Gegenstände Speichern</button></div></div></div></div>';
document.getElementById('innerhtml').value = '';
}
function numKeys(obj) {
var count = 0;
for (var prop in obj) {
count++;
}
return count;
}
function updateRoomItems(a) {
var roomname = a;
if (rooms[`${roomname}`] === undefined) {
var roomData = new Room();
roomData.description = document.getElementById(`${roomname}_description`).value;
addRoom(`${roomname}`, roomData);
console.log(rooms);
} else {
updateRoom(`${roomname}`, "description", document.getElementById(`${roomname}_description`).value);
}
how i say i got every time only the last value of the textarea, I need all values, why reset the other values? What have i wrong?
This statement is causing the problem:
document.getElementById("rooms").innerHTML += '<div ... // etc
The innerHTML property of the rooms element is read, concatenated with the right hand side of += and written back. When read, it returns the tags of textarea elements already in the rooms element, but not their content. So every time you add a new room it recreates existing textareas with nothing in them.
The Element​.insert​Adjacent​HTML() method was introduced to solve this exact issue. Stylistically I would not recommend the use of "innerhtml" as an element id.

JQuery append doesn't load css for toggle button

I'm trying to use a toggle button with jquery appended content. The appended content uses Labelauty jQuery Plugin to load the check boxes and its working fine.
But the toggle button is not loading the relevant css properly.
Here is my html code for the panel which includes the toggle button.
<div class="col-md-6">
<div class="panel">
<div class="panel-body container-fluid">
<div id="testcases" class="accordion js-accordion">
<h4>Test<i class="fa fa-thumbs-o-down"></i> <small>CASES</small>
<div class="toggle-wrap w-checkbox">
<input class="toggle-ticker w-checkbox-input" data-ix="toggle-switch" data-name="Toggle Switch" id="Toggle-Switch" name="Toggle-Switch" type="checkbox" onclick="toggle()">
<label class="toggle-label w-form-label" for="Toggle-Switch"> </label>
<div class="toggle">
<div class="toggle-active">
<div class="active-overlay"></div>
<div class="top-line"></div>
<div class="bottom-line"></div>
</div>
</div>
</div>
</h4>
</div>
<br>
<button type="button" class="btn btn-info float-right" onclick="loadplan()">Add to Plan</button>
</div>
</div>
</div>
<!--TestPlan Panel-->
<div class="Panel">
<div class="col-md-13">
<div class="panel">
<div class="panel-body container-fluid">
<h4>Test<i class="fa fa-thumbs-o-down"></i> <small>PLAN</small></h4>
<!-- Start list -->
<ul id="testplan" class="list-group"></ul>
</div>
<!-- End list -->
</div>
</div>
</div>
Which output this
before jquery append
Here is my jquery to append content
//Load TestCase List to Accordion
var testSuiteList;
var currentTestSuite;
function loadtestcases(testSuite, testcases) {
currentTestSuite = testSuite;
var testcases = testcases.split(",");
// $("#testcases").empty();
$("#testcases div:not(:first)").remove();
var id = 0;
// $("#testcases").append("<h4>Test<i class='fa fa-thumbs-o-down'></i> <small>CASES</small></h4>")
testcases.forEach(function(entry) {
id = id + 1;
$("#testcases").append("<div class='accordion__item js-accordion-item'>" +
"<div class='accordion-header js-accordion-header'>" +
"<input type=\"checkbox\" class='to-labelauty-icon' name=\"inputLableautyNoLabeledCheckbox\" data-plugin=\"labelauty\" data-label=\"false\" id=\"labelauty-" + id + "\" value=\"" + entry + "\"> " + entry + "</div>" +
"<div class='accordion-body js-accordion-body'>" +
"<div class='accordion-body__contents'>" +
"data-table" +
"</div>" +
"</div>" +
"</div>" +
"<div class='accordion__item js-accordion-item active'>" +
"</div>")
});
//accordion js for appended div
var accordion = (function() {
var $accordion = $('.js-accordion');
var $accordion_header = $accordion.find('.js-accordion-header');
var $accordion_item = $('.js-accordion-item');
// default settings
var settings = {
// animation speed
speed: 400,
// close all other accordion items if true
oneOpen: false
};
return {
// pass configurable object literal
init: function($settings) {
$accordion_header.on('click', function() {
accordion.toggle($(this));
});
$.extend(settings, $settings);
// ensure only one accordion is active if oneOpen is true
if (settings.oneOpen && $('.js-accordion-item.active').length > 1) {
$('.js-accordion-item.active:not(:first)').removeClass('active');
}
// reveal the active accordion bodies
$('.js-accordion-item.active').find('> .js-accordion-body').show();
},
toggle: function($this) {
if (settings.oneOpen && $this[0] != $this.closest('.js-accordion').find('> .js-accordion-item.active > .js-accordion-header')[0]) {
$this.closest('.js-accordion')
.find('> .js-accordion-item')
.removeClass('active')
.find('.js-accordion-body')
.slideUp()
}
// show/hide the clicked accordion item
$this.closest('.js-accordion-item').toggleClass('active');
$this.next().stop().slideToggle(settings.speed);
}
}
})();
$(document).ready(function() {
accordion.init({
speed: 300,
oneOpen: true
});
$(":checkbox").labelauty({
label: false
});
});
}
//Load the selected testcases on TestPlan
function loadplan() {
currentTestSuite;
//Map the selected testcases to an array
var selectedtclist = [];
$('input[class="to-labelauty-icon labelauty"]:checked').each(function() {
selectedtclist.push(this.value);
});
for (var i = 0; i < selectedtclist.length; i++) {
var tc_name = selectedtclist[i];
var searchWord = currentTestSuite + " " + "|" + " " + tc_name;
// see if element(s) exists that matches by checking length
var exists = $('#testplan li:contains(' + searchWord + ')').length;
if (!exists) {
//Append selected testcases to TestPlan
$("#testplan").append("<li class='list-group-item list-group-item-info'>" + currentTestSuite + " " + "|" + " " + tc_name + "</li>");
}
};
};
which output this
after loading jquery appended content
How can I load the styles for toggle button properly?
You use append() for the selector $("#testplan"), but I cannot find that ID id="testplan" for any element in your HTML code, so therefore JS can't find it and thus cannot "appand" anything to it.

Trying to reload page after clicking similar product

Im pulling items from a JSON file. I have a class called "showProduct" and once clicked it executes a function and shows the item information on the page. I am trying to call this same function again later in my code on the similar product. I need the page to refresh with that new items contents. Below is my code really hope someone can help me out im not sure what I am doing wrong. I did not include the JSON but i hope just by looking at the class and my code someone will know why it wont work.
function openNav() {
document.getElementById("productsSideBar").style.width = "250px";
}
function closeNav() {
document.getElementById("productsSideBar").style.width = "0";
}
'use strict';
$.ajax({
dataType: "jsonp",
url: '',
success: function(json){
//check for window hash and display appropriate product category
var currentHash = window.location.hash;
switch(currentHash)
{
case '#tomatoes':
displayTomatoes();
break;
default:
displayAll();
break;
}
//display all products function
function displayAll() {
var categoryImage = '';
$.each(json, function (i, item) {
if (item.itemBrandLetter == "C") {
categoryImage += '<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">' + '' + '<img class="img-responsive img-hover productImagesCategory" src="' + item.imageURL + '">' + '<h3>' + item.itemName + '</h3>' + '' + '</div>';
}
});
$('#imagesCategoryProducts').hide().html(categoryImage).fadeIn('slow');
//show individual product function on click
$(".showProduct").click(function(event){
//hide all current products
$('#productCategories').hide();
//get passed data from other function
var clickedItemName = '<h1>' + $(this).data('itemname') + '</h1>';
var clickedItemUPC = $(this).data('itemupc');
var clickedItemOZ = '<h2>' + $(this).data('itemoz') + '</h2>';
var clickedItemDescription = '<p>' + $(this).data('itemdescription') + '</p>';
var clickedItemImage = '<img class="img-responsive img-rounded center-block" src="' + $(this).data('itemimage') + '">';
var clickedItemGluten = $(this).data('itemgluten');
var clickedItemBPA = $(this).data('itembpa');
var clickedItemGMO = $(this).data('itemgmo');
var clickedItemPageURL = $(this).data('itempageurl');
//check if clicked data equals correct item
$.each(json, function (i, item) {
if (item.itemName === clickedItemName) {
clickedItemName
}
if (item.itemFullUPC === clickedItemUPC) {
clickedItemUPC
}
if (item.itemPackSize === clickedItemOZ) {
clickedItemOZ
}
if (item.itemDescription === clickedItemDescription) {
clickedItemDescription
}
if (item.imageURL === clickedItemImage) {
clickedItemImage
}
if (item.itemGlutenFree === clickedItemGluten) {
clickedItemGluten
}
if (item.itemBPAFree === clickedItemBPA) {
clickedItemBPA
}
if (item.itemGMOFree === clickedItemGMO) {
clickedItemGMO
}
//assign window hash to each product
if (item.itemName === clickedItemPageURL) {
event.preventDefault();
clickedItemPageURL = clickedItemPageURL.replace(/\s/g, '');
window.location.hash = clickedItemPageURL;
}
});
//remove extra characters from UPC
var originalUPC = clickedItemUPC;
var strippedUPC = '<h2>' + originalUPC.slice(1, -1); + '</h2>';
//show individual product information
$('#productSocialShare').show();
$('#individualProduct').show();
$('#relatedProducts').show();
//append product information to appropriate DIV
$('#productTitle').html(clickedItemName);
$('#productUPC').html(strippedUPC);
$('#productOZ').html(clickedItemOZ);
$('#productDescription').html(clickedItemDescription);
$('#productImage').html(clickedItemImage);
//check if gluten free is true and show image
if (clickedItemGluten == "Y") {
clickedItemGluten = '<img class="img-responsive img-rounded img-margin" src="../images/misc/gluten_free_test.jpg">';
$('#productGlutenFree').html(clickedItemGluten);
$('#productGlutenFree').show();
} else {
$('#productGlutenFree').hide();
}
//check if bpa free is true and show image
if (clickedItemBPA == "Y") {
clickedItemBPA = '<img class="img-responsive img-rounded img-margin" src="../images/misc/bpa_free_test.jpg">';
$('#productBPAFree').html(clickedItemBPA);
$('#productBPAFree').show();
} else {
$('#productBPAFree').hide();
}
//check if gmo free is true and show image
if (clickedItemGMO == "Y") {
clickedItemGMO = '<img class="img-responsive img-rounded img-margin" src="../images/misc/gmo_test.jpg">';
$('#productGMOFree').html(clickedItemGMO);
$('#productGMOFree').show();
} else {
$('#productGMOFree').hide();
}
//show random recipe for each item
var url = '';
$.getJSON(url, function(json) {
var randomRecipe = json[Math.floor(Math.random() * json.length)];
randomRecipe += '<div>' + '' + '<img class="img-responsive img-hover similarProductImagesCategory" src="' + randomRecipe.recipeImageCategoryURL + '">' + '' + '' + '<h3 class="similarProductSubCategoryImgCaption">' + randomRecipe.recipeName + '</h3>' + '' + '</div>';
$('#featuredRecipe').append(randomRecipe);
});
//show similar products
var categoryItems = [];
$.each(json, function(i, item){
if(window.location.hash.indexOf('Tomatoes') >= 0) {
if(item.itemCommodity == '1120' && item.itemBrandLetter == "C") categoryItems.push(item);
}
if(window.location.hash.indexOf('Olive') >= 0) {
if(item.itemCommodity == '2120' && item.itemBrandLetter == "C") categoryItems.push(item);
}
});
var similarProduct= '';
$.each(json, function(i,item){
similarProduct = categoryItems[Math.floor(Math.random()*categoryItems.length)];
similarProduct += '<div>' + '' + '<h3 class="similarProductSubCategoryImgCaption">' + similarProduct.itemName + '</h3>' + '' + '</div>';
});
$('#productSimilar').append(similarProduct);
});
closeNav();
}
}
});
});
<section>
<div id="productsSideBar" class="sidenav">
×
<h3>View All</h3>
Tomatoes
Sauce
Olive Oil
Red Wine Vinegar
Balsamic Vinegar
Peppers
Artichokes
Olives
Beans
Capers & Pignoli Nuts
Specialties
Spices
Fish
Broth, Stocks & Soups
Breadcrumbs
Grated Cheese
</div>
</section>
<section id="productCategories">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<br>
<span class="expandSidebar" onclick="openNav()">☰ Categories</span>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div id="imagesCategoryProducts"></div>
</div>
</div>
</div>
</section>
<!-- Product Row Start -->
<section id="individualProduct">
<div class="container topmargin">
<div class="row">
<div class="col-md-7 col-sm-6">
<!-- Product Title Div -->
<div id="productTitle"></div>
<!-- Product UPC Div -->
<div class="displayInlineBlock" id="productUPC"></div>
<span class="displayInlineBlock"><h2>•</h2></span>
<!-- Product OZ Div -->
<div class="displayInlineBlock" id="productOZ"></div>
<span class="displayInlineBlock"><h2>•</h2></span>
<!-- Where to Buy Icon -->
<div class="displayInlineBlock"><h3><span rel="popover" data-content="View Product Availability"><span class="fa-stack"><i class="fa fa-square fa-stack-2x"></i><i class="fa fa-map-marker fa-stack-1x fa-inverse"></i></span></span></h3></div>
<hr>
<!-- Product Description Div -->
<div id="productDescription"></div>
<div class="row center">
<!-- Gluten Free Div -->
<div class="displayInlineBlock" id="productGlutenFree"></div>
<!-- BPA Free Div -->
<div class="displayInlineBlock" id="productBPAFree"></div>
<!-- GMO Div -->
<div class="displayInlineBlock" id="productGMOFree"></div>
</div>
</div>
<div class="col-md-5 col-sm-6">
<!-- Product Image Div -->
<div id="productImage"></div>
</div>
</div>
</div>
</section>
<!-- Product Row End -->
<section id="relatedProducts">
<div class="container topmargin">
<div class="row">
<div class="col-md-7">
<h1 class="center">Featured Recipe</h1>
<div id="featuredRecipe"></div>
</div>
<div class="col-md-5">
<h1 class="center">Similar Product</h1>
<br>
<div id="productSimilar"></div>
</div>
</div>
</div>
</section>
Ok, there are a lot of things that are wrong in the code but I am not going to into that right now. To do what you want to achieve is rather simple, you already got all the code you need, you just need to make some adjustments to make it work.
Step one. Bind the click events to the body instead of to the element.
$("body").on('click', ".showProduct", function(event){
That way, any element on the page with the class showProduct that is clicked will trigger the function, not just the elements that were bound to when the initial function ran.
The rest is really simple, you already have the similar product's information available, you just didn't put it in the data attributes when you created the element. Now obviously there are better ways of doing this... but here is how you would do it:
similarProduct = '<div>' +
'<a href="#" class="showProduct"' +
'data-itempageurl="' + similarProduct.itemFullUPC + '"' +
'data-itemgmo="' + similarProduct.itemGMOFree + '"' +
'data-itembpa="' + similarProduct.itemBPAFree + '"' +
'data-itemgluten="' + similarProduct.itemGlutenFree + '"' +
'data-itemlowsodium="' + similarProduct.itemLowSodium + '"' +
'data-itemorganic="' + similarProduct.itemOrganic + '"' +
'data-itemimage="' + similarProduct.imageURL + '"' +
'data-itemname="' + similarProduct.itemName + '"' +
'data-itemoz="' + similarProduct.itemPackSize + '"' +
'data-itemdescription="' + similarProduct.itemDescription + '"' +
'data-itemupc="' + similarProduct.itemFullUPC + '"' + '>' +
'<img class="img-responsive img-hover similarProductImagesCategory" src="' + similarProduct.imageURL + '">' +
'<h3 class="similarProductSubCategoryImgCaption">' + similarProduct.itemName +
'</h3>' + '</a>' + '</div>';
});
That should do it... now you will notice when you click on one of the similar products it should show you the information like you wanted, however it will add the new similar product to the already existing similar product list and this will keep on growing the more you click. I am sure you can figure out how to clear the list. If not just shout.
Here is the codepen: http://codepen.io/anon/pen/oYJpve
EDIT: As a side note... normally you want to store the json data with the product id as key. Then you only save the key inside the data attribute. On click you simply use the product id (key) to access the information in your stored object.
It is really easy to do. Just create a global variable
var product_data = {};
Then you populate the object when you get the data with a function. So on success of your ajax call you could have something like this:
product_data = json;
or even better you could have a function that changes the data into the structure you want:
product_data = restructureDataFunction(json);
Then you have a nice data set which you can pull from. If you need to make updates to the dataset you can do it in one place instead of in each element.
If you want, have a look at Angular 2, it should teach you a lot and also help you with future projects. It is really strong tool especially if you have html elements representing data.

Categories