Checking Each Cart Heading Items For Specific Style Names - javascript

I am in the process of developing an AB Test for an e-commerce cart page. We have a list of about 100 stylenames that we are not going to be accepting returns on.
We have messaging displayed on those particular styles' product display pages, but we would also like to have this message reinforced on the cart page if any product in the cart matches the list of stylenames that qualify.
I have started by creating an array variable of all qualified stylenames (shortened here for example). I then loop through each cart item heading tag & check the .text() of that element. IF the .text() matches one of the stylenames I am looking for, I would then want to go ahead and append the message below the cart item heading tag.
Here is the script I have written, however, I don't see the result expected when running this locally in my devtools snippet:
var styleList = ['Astawia Loafer','Another Style','So On','So Forth'];
var finalSaleMessage = '<span><strong>Final sale! </strong>No returns on our best deals.</span>'
function checkStyleName(value,arr){
var result = false;
for (var i = 0; i < arr.length; i++){
var name = arr[i];
if(name == value){
result = true;
break;
}
}
return result;
}
$('.crt-heading--item').each(function(){
if (checkStyleName($('.crt-heading--item').text(),styleList) == true) {
// append the message
}
})
Any input here from the community would be greatly appreciated. Please let me know if you would need further information.
Thanks!

Can be simplified a little.
No need to send array everytime.
Usage of includes.
Looks like the text is in the format of BRAND PRODUCT_NAME CATEGORY. You may want to split or do something to get the PRODUCT_NAME.
Usage of this as pointed out by devmiguelopz
var styleList = ['Astawia Loafer','Another Style','So On','So Forth'];
var finalSaleMessage = '<span><strong>Final sale! </strong>No returns on our best deals.</span>'
// OLD SUGGESTION
/*
$('.crt-heading--item').each(function(){
if (styleList.includes($(this).text()) {
// append the message
}
*/
// This will iterate on the elements
$('.crt-heading--item').each(function(){
// Iterate on the styleList
var styleListLength = styleList.length;
for(var i = 0, i < styleListLength; i++){
// Check if the name has entry from styleList
if($(this).text().includes(styleList[i])){
// DO STUFF
}
}
})
// We re running a loop inside a loop in this case.
// There may be better ways of doing this with .some/.filter/.map
Check here for what .includes can do for you : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

The problem is that you go through all the elements of a certain class and don't refer to every single one of them.
var styleList = ['Astawia Loafer','Another Style','So On','So Forth'];
var finalSaleMessage = '<span><strong>Final sale! </strong>No returns on our best deals.</span>'
function checkStyleName(value,arr){
var result = false;
for (var i = 0; i < arr.length; i++){
var name = arr[i];
if(name == value){
result = true;
break;
}
}
return result;
}
$('.crt-heading--item').each(function(){
if (checkStyleName($(this).text(),styleList) == true) {
// append the message
//test
alert($(this).text())
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class= "crt-heading--item">Astawia Loafer</li>
<li class= "crt-heading--item">Astawia Loafer</li>
<li class= "crt-heading--item">3</li>
<li class= "crt-heading--item">So On</li>
<li class= "crt-heading--item">5</li>
</ul>

Related

Problem with Looping through over a newly created list element by js

I am building a Todo-List Project and i am stuck at looping through my newly created list items.
This is what i am doing:
Created an array.
Made li items for array's each element through looping so that array appears in a list manner.
And then looping through newly created li section to addEventListener on each of li's ( But this one is not working).
var arrList = ["play","learn","walk"];
var list = document.querySelectorAll("li");
var done = false;
//printing array in list manner
for(let i = 0; i < arrList.length; i++){
let el = document.createElement("li")
el.textContent = arrList[i];
document.querySelector("ul").appendChild(el);
}
//looping through each li's to apply if else statement
for(let i = 0; i < list.length; i++){
list[i].addEventListener("click",function(){
if(!done){
this.style.textDecoration = "line-through";
done = true;
}else{
this.style.textDecoration = "none";
done = false;
}
})
}
You're code is mostly correct, however there are a few issues that need to be addressed. First, consider replacing your for loop with iteration based on forEach() as shown below. Using forEach() in this way allows you to leverage "closure" which in this case will greatly simplify your code. For instance, you can use the closure feature to store the done state of each item in your list, rather than storing that state explicitly in an array.
The other issue I noticed was var list = document.querySelectorAll("li"); queries the document for li elements before any are added to your document - later in your script it seems you're iterating that empty query result and expecting it to contain the added li elements.
Here's a working snippet - hope this helps!
var arrList = ["play", "learn", "walk"];
// Iterate the list via forEach
arrList.forEach(function(arrItem) {
// We're now in a new "closure" for this list item
// so we can define some state like "done" that will
// be used exclusively for this list item
var done = false;
// Create li element for this list item as before
var el = document.createElement("li")
el.textContent = arrItem;
// Configure click event
el.addEventListener("click", function() {
// Notice we're able to use the done variable
// in this closure for this list item? The key
// thing to understand is that each list item
// will have it's own unique "done" variable
if (!done) {
el.style.textDecoration = "line-through";
done = true;
} else {
el.style.textDecoration = "none";
done = false;
}
})
document.querySelector("ul").appendChild(el);
});
<ul></ul>
It seems like you only have one done variable that is shared for every item on the todo list. Therefore if you click one of the items all of the items will be crossed out. You will need a boolean variable for every item in your to do list.
Add this line just above the second for loop and remove from the top.
var list = document.querySelectorAll("li");
You are assigning list the values even before they are created.
from the source code I see that the list li item is initialized before new li item been created,
it will cause the list li item not contains the new one,
due to that addEventListener will not working for the new item.
to fix this, just need move init list li item code after creation part :
var arrList = ["play","learn","walk"];
var done = false;
//printing array in list manner
for(let i = 0; i < arrList.length; i++){
let el = document.createElement("li")
el.textContent = arrList[i];
document.querySelector("ul").appendChild(el);
}
var list = document.querySelectorAll("li");
//looping through each li's to apply if else statement
for(let i = 0; i < list.length; i++){
list[i].addEventListener("click",function(){
if(!done){
this.style.textDecoration = "line-through";
done = true;
}else{
this.style.textDecoration = "none";
done = false;
}
})
}
Please, be simple...
var
arrList = ["play","learn","walk"],
UL_arrList = document.querySelector("ul")
;
arrList.forEach (arrItem => {
let el = document.createElement("li");
el.textContent = arrItem;
UL_arrList.appendChild(el);
el.onclick = function(e){
let deco = this.style.textDecoration || 'none';
this.style.textDecoration = (deco==='none') ? 'line-through': 'none';
}
});
<ul></ul>

Onmousehover in more than one section

I'm trying use js onmousehover to hover over an image and in a seperate fixed location tell me the name of said image. I have successfully done this but I can only get it to work on the first element when I have about six that I need to do. here is a sample of my code:
function getElementsById(ids) {
var idList = ids.split(" ");
var results = [], item;
for (var i = 0; i < idList.length; i++) {
item = document.getElementById(idList[i]);
if (item) {
results.push(item);
}
}
return(results);
}
function hover(description) {
console.log(description);
document.getElementsById('content content1').innerHTML = description;
}
and to call it I've been using this:
<div class="product-description-box">
<p>
<div class="colorHeading">colors available: <span class="selectedColor" id="content"></span></div>
<div class="prodColors"></div>
</p>
</div>
I am using different ids for each section. Js is for sure not my strong suit so any help would be appreciated!
A faster way of doing it is to pull your elements collection and then convert it into an array:
Like so:
[].slice.call(document.getElementsByClassName("box"))
.forEach(function(element) {element.addEventListener("mouseover", checkBoxColor);});
This calls slice on the collection of HTML elements returned by getElementsByClassName in order to convert it into an Array. After that I run the forEach method to add the event listener to each HTML element.
Fiddle: https://jsfiddle.net/0saLvq2q/
In your case if you need to return multiple elements by many different ID's you can use querySelectorAll() to pull the elements instead of getElementsByClassName().
'ids' isn't automatically a list. What you want to use is the Arguments Object.
function getElementsById() {
var i, results = [], item;
for (i = 0; i < arguments.length; i++) {
item = document.getElementById(arguments[i]);
if (item) {
results.push(item);
}
}
return(results);

Add values to the cookie using URL

I'm working on my webshop and since I dont want users to have to register to use the webshop, im using javascript cookies to hold the values the user has entered. But I want people who go to the webshop with a different url (for example: http://test.com/index.php?124&342), having 2 values in the cart, I made some functions to work on this. Here is the following code:
function getUrlVars() {
var variabelen = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
var urls = $.cookie($.cookie('cart')) || [];
for (var i = 0; i < variabelen.length; i++) {
urls.push(variabelen[i]);
}
}
if ($.cookie('cart')) {
var Orders = $.parseJSON($.cookie('cart'));
} else {
var Orders = new Array;
}
getUrlVars();
Where "orders" is the json array with the selected product-ID's. Now this is not working as I wanted to. It's not pushing the URL variables into the cart.
Okay UPDATE:
I succeed in pushing the URL variables in the cookie, but now the following problem accurs.
function UpdateTotals() {
ToAddHTML = '<h1>Cart</h1></br>';
console.log(Orders);
TotalPrice = 0;
for (var i = 0; i < Orders.length ; i++) {
var Result = SubMenuItems.filter(function(v) {
return v.submenu_id === Orders[i];
})[0];
TotalPrice += parseFloat(Result.price);
ToAddHTML += '<div class=orderd> <span class="order" Orders='+i+'> </span>'+'€'+zoekresultaat.price+' '+zoekresultaat.title+'</br></div><hr>';
}
The live website is on(nb. im using dutch description so the functions have different names):
Website
If I understand the problem correctly this should do the trick:
// Given: page.html?109&10
// -----------------------
// Split the query string on '&', after the '?' and push
// each value into the array 'Bestellingen'
// -----------------------
$.each(document.location.search.substr(1).split('&'),function(key,value){
Bestellingen.push(value);
});
You can replace your method haalUrlVars with the two lines above and you should find that items 109 & 10 are added to your list as though the were in the cookie when the page loaded.
Does that help?

Javascript scope issue with jquery post and promise

I am trying to build an array from the responses of a jquery post. I have the following code:
categories_names = [];
$(categories).each(function(index, category_id) {
$.post('/modules/blog/add_post_categories', {post_id:result.result, category_id:$(category_id).val()},
function(result)
{
categories_names.push = result;
});
}).promise().done(function() {
var final_cats = categories_names.join("");
console.info(final_cats);
});
The post request inserts the category id into a table and returns the name of that category formatted like <li>Category Name here</li> so that once the array is built and all categories selected (by checkbox in the form previous to this) are entered into the database, the array can be joined and inserted as html to the final view. At the moment the code is just printing it out in the console as you can see but as you've probably guessed, it returns (an empty string)
I know this is most likely a scope issue since that's the area of javascript that still totally baffles me, so I'm hoping someone can shed some light on it.
Your .promise().done(...) isn't doing what you think it is. It's simply resolving instantly because there are no animations on the elements you are iterating over. Also, your syntax for [].push is wrong.
var defArr = $(categories).map(function(index, category_id) {
return $.post('/modules/blog/add_post_categories', {post_id:result.result, category_id:$(category_id).val()});
}).get();
$.when.apply(null,defArr).done(function() {
//var categories_names = [];
//for (var i = 0; i < arguments.length; i++) {
// categories_names.push(arguments[i][0]);
//}
var categories_names = $.map(arguments,function(i,arr) {
return arr[0];
});
var final_cats = categories_names.join("");
console.info(final_cats);
});
categories_names.push = result;
can you try changing this to
categories_names.push(result);
because push is a method, not a variable.

Can anyone help with this (Javascript arrays)?

Hi I am new to Netui and Javascript so go easy on me please. I have a form that is populated with container.item data retuned from a database. I am adding a checkbox beside each repeater item returned and I want to add the container item data to an array when one of the checkboxes is checked for future processing.
The old code used Anchor tag to capture the data but that does not work for me.
<!--netui:parameter name="lineupNo" value="{container.item.lineupIdent.lineupNo}" />
here is my checkbox that is a repeater.
<netui:checkBox dataSource="{pageFlow.checkIsSelected}" onClick="checkBoxClicked()" tagId="pceChecked"/>
this is my Javascript function so far but I want to a way to store the container.item.lineupIdent.lineupNo in the array.
function checkBoxClicked()
{
var checkedPce = [];
var elem = document.getElementById("PceList").elements;
for (var i = 0; i < elem.length; i ++)
{
if (elem[i].name == netui_names.pceChecked)
{
if (elem[i].checked == true)
{
//do some code. }
}
}
}
I hope this is enough info for someone to help me. I have searched the web but could not find any examples.
Thanks.
var checkedPce = new Array();
//some other code
checkedPce[0] = stuff_you_want_to_add
If you merely want to add a value to an array, you can use this code:
var array = [];
array[array.length] = /* your value */;
You may need to use a dictionary approach instead:
var dictionary = {};
function yourCode(element) {
var item = dictionary[element.id];
if (item == null) {
item = /* create the object */;
dictionary[element.id] = item;
}
// Use the item.
}

Categories

Resources