Need to pass values in associative array in jquery - javascript

What I am trying to achieve is to get all products name from page its position and than store it in an array which than I can use in next part of the code. Here is that I have done so far
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"> </script>
<script type="text/javascript">
jQuery(document).ready(function($) {
var i = 1;
$(".product-name").each(function() {
var pnameforostock = $(this).text();
var positionp = i++;
alert(pnameforostock);
});
});
</script>
<body>
<li class="item">
<a href="product1.php" title="Sample Product Name" class="product-image">
<span class="sale-item">Sale!</span>
<div class="cat-mouseover"></div>
<img src="/images/product1.png" alt="Sample Product Name"></a>
<h2 class="product-name">Sample Product Name</h2>
<div class="price-box">
<p class="old-price">
<span class="price-label">For:</span>
<span class="price" id="old-price-426">
199,- </span>
</p>
<p class="special-price">
<span class="price-label"></span>
<span class="price" id="product-price-426">
Now 139,- </span>
</p>
</div>
<div class="actions">
<button type="button" title="Buy Now" class="button btn-cart" onclick="setLocation('http://www.google.com/')"><span><span>Buy</span></span></button>
</div>
</li>
<li class="item">
<a href="product1.php" title="Sample Product Name" class="product-image">
<span class="sale-item">Sale!</span>
<div class="cat-mouseover"></div>
<img src="/images/product1.png" alt="Sample Product Name"></a>
<h2 class="product-name">Sample Product Name 2</h2>
<div class="price-box">
<p class="old-price">
<span class="price-label">For:</span>
<span class="price" id="old-price-426">
199,- </span>
</p>
<p class="special-price">
<span class="price-label"></span>
<span class="price" id="product-price-426">
Now 139,- </span>
</p>
</div>
<div class="actions">
<button type="button" title="Buy Now" class="button btn-cart" onclick="setLocation('/checkout/cart/add/uenc/aHR0cDovL3d3dy52aXRhLm5vLw,,/product/426/')"><span><span>Buy</span></span></button>
</div>
</li>
</body>
</html>
From the above jquery code I am able to get the product names but not able to place them in array so that it will look something like this
name: product1, name: product2
I tried a lot to get some results in array but no success. Please advise.

You would want an array of objects (JS doesn't have associative arrays)
var products = $(".product-name a").map(function() {
return { name: $(this).text() }
}).get();
.map reference: http://api.jquery.com/jquery.map/

Related

Getting the ID and inner text of the element (children) inside a div

I have multiple div's that represent some products, example below :
<div class="special" id="special">
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span id="pdctName">12v XXXXXXXXXXXXXXX</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta!</span>
</span>
Ofertas especiales
<span class="special-price">200,00 €</span>
<del style="margin-top: -9px;">250,00 €</del>
+ Add to cart
</p>
</div>
Troubles getting the ID (so the value) of some elements inside this division (div id="special") :
i want for example to get the ID of <span id="pdctName"> and <span class="special-price">.
The element that triggers my function is
+ Add to cart.
i tried document.querySelector('#special span#pdctName').innerText, it works only for the first occurence of this div, but i want to retrieve those elements for the selected division.
Yes getElementById always give you first element. You have to find element using this object
Example is as follow
var buttons=document.getElementsByClassName("js-cd-add-to-cart");
[].slice.call(buttons).forEach(x=>{
x.addEventListener('click',function(obj){
console.log(this.closest("#special").innerText);
return false;
})
})
<div class="special" id="special">
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span id="pdctName">12x XXXXXXXXXXXXXXX</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta1</span>
</span>
Ofertas especiales1
<span class="special-price">300,00 €</span>
<del style="margin-top: -9px;">450,00 €</del>
+ Add to cart
</p>
</div>
<div class="special" id="special">
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span id="pdctName">12v XXXXXXXXXXXXXXX</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta1</span>
</span>
Ofertas especiales
<span class="special-price">600,00 €</span>
<del style="margin-top: -9px;">150,00 €</del>
+ Add to cart
</p>
</div>
First, you have to attach event on every add(+) button
Then call parent div element using this.parentElement.parentElement
Then get values using querySelector
function addtocart(){
event.preventDefault();
var spanid = this.parentElement.parentElement.querySelector("a h3 span").id;
var price = this.parentElement.parentElement.querySelectorAll("p span")[2].innerText;
console.log(spanid);
console.log(price);
}
[...document.querySelectorAll(".special-add")].forEach((btn)=>{
btn.addEventListener("click",addtocart);
});
<div class="special" id="special">
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span id="pdctName">12v XXXXXXXXXXXXXXX</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta!</span>
</span>
Ofertas especiales
<span class="special-price">200,00 €</span>
<del style="margin-top: -9px;">250,00 €</del>
+ Add to cart
</p>
</div>
This is best practice when data is dynamically added to pages.
I have a couple suggestions on how you could improve the structure of your special elements.
Data
If you want to extract data from a HTML element, and you have multiple pieces of data to extract, then consider using a form with input type="hidden" elements in there. They will not be visible to the user and can hold information that will be easy for you to use.
In combination with the FormData API you can access all of the input values in your form and add them to your cart if you need to.
If you do use the form element than change the <a class="special-add.. link to a button. I doesn't link anywhere anyway, so it probably should be a button.
IDs
It seems that you have multiple id attributes with the same values on your page, assuming you have more than one special. If that is the case, remove them or make them totally unique.
It's also the reason why getElementById doesn't work properly. It always finds the first element with the matching id.
Check the example below. If you have any questions please let me know.
function addSpecialToCart(event) {
/**
* Get all the inputs in the form.
*/
const formData = new FormData(event.target);
/**
* Show all data in the current form.
* Loop over the items in formData and
* show the name and value of each input.
*/
for (const [ name, value ] of formData) {
console.log(name, value);
}
/**
* Or get a single value by the name of the input.
*/
const productName = formData.get('product-name');
console.log(productName);
event.preventDefault();
};
document.addEventListener('submit', addSpecialToCart);
<div class="special">
<form class="special-form">
<input type="hidden" name="product-name" value="Product 1"/>
<input type="hidden" name="product-category" value="Ofertas especiales1"/>
<input type="hidden" name="special-price" value="150"/>
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span class="pdctName">Product 1</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta1</span>
</span>
Ofertas especiales1
<span class="special-price">150,00 €</span>
<del style="margin-top: -9px;">250,00 €</del>
<button type="submit" class="special-add cd-add-to-cart js-cd-add-to-cart">+ Add to cart</button>
</p>
</form>
</div>
<div class="special">
<form class="special-form">
<input type="hidden" name="product-name" value="Product 2"/>
<input type="hidden" name="product-category" value="Ofertas especiales2"/>
<input type="hidden" name="special-price" value="300"/>
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span class="pdctName">Product 2</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta1</span>
</span>
Ofertas especiales2
<span class="special-price">300,00 €</span>
<del style="margin-top: -9px;">450,00 €</del>
<button type="submit" class="special-add cd-add-to-cart js-cd-add-to-cart">+ Add to cart</button>
</p>
</form>
</div>
<div class="special">
<form class="special-form">
<input type="hidden" name="product-name" value="Product 3"/>
<input type="hidden" name="product-category" value="Ofertas especiales3"/>
<input type="hidden" name="special-price" value="1200"/>
<a href="12v.html" class="special-link">
<p class="special-img">
<img src="img/25.png" alt="">
</p>
<h3><span class="pdctName">Product 3</span></h3>
</a>
<p class="special-info">
<span class="ribbon2 animated swing infinite">
<span>Oferta1</span>
</span>
Ofertas especiales3
<span class="special-price">1200,00 €</span>
<del style="margin-top: -9px;">1450,00 €</del>
<button type="submit" class="special-add cd-add-to-cart js-cd-add-to-cart">+ Add to cart</button>
</p>
</form>
</div>

List.js finds the element but still keeps others too

its my first time using List.js. I have the following structure:
var options = {
valueNames: ['name']
};
var coursesList = new List('courses-list', options);
coursesList.on('updated', function(list) {
console.info(list.matchingItems);
if (list.matchingItems.length > 0) {
$('.no-result').hide()
} else {
$('.no-result').show()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<div id="courses-list">
<input class="search">
<div id="collectionView" class="list">
<div class="row1">
<div class="large-6 small-12 columns" >
<a href="link/to/somewhere" target="_blank">
<span class="name">Demokurs Französisch A2 Online</span>
<p class="description">blabla</p>
</a>
</div>
<div class="large-6 small-12 columns" >
<a href="link/to/somewhere" target="_blank">
<span class="name">Französisch</span>
<p class="description">blabla</p>
</a>
</div>
</div>
<div class="row2">
<div class="large-6 small-12 columns" >
<a href="link/to/somewhere" target="_blank">
<span class="name">Kurs A</span>
<p class="description">blabla</p>
</a>
</div>
<div class="large-6 small-12 columns" >
<a href="link/to/somewhere" target="_blank">
<span class="name">Kurs B<span>
<p class="description">blabla</p>
</a>
</div>
</div>
</div>
</div>
Well now if I search for the term A2 it show correctly the content of the firstdiv in row1 BUT also the second div with all of its content. List.js hides row2 as wished.
How can I make it work that it also hides all other divs in a row?
I have also checked if really only matching is there with:
coursesList.on('updated', function(list) {
console.info(list.matchingItems);
if (list.matchingItems.length > 0) {
$('.no-result').hide()
} else {
$('.no-result').show()
}
})
The logs show that list.matchingItems finds only object.
List.js isn't designed to work this way, it doesn't support nested lists, it only counts a list item down 1 level, so its sees the whole of the <div class="row1"> as a single list item and <div class="row2"> as another.
If you want it to work properly I suggest removing the <div class="row1"> and<div class="row2"> so that all the relevant <div> are at the same level. Like shown below:
var options = {
valueNames: ['name']
};
var coursesList = new List('courses-list', options);
coursesList.on('updated', function(list) {
console.info(list.matchingItems);
if (list.matchingItems.length > 0) {
$('.no-result').hide()
} else {
$('.no-result').show()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>
<div id="courses-list">
<input class="search">
<div id="collectionView" class="list">
<div class="large-6 small-12 columns">
<a href="link/to/somewhere" target="_blank">
<span class="name">Demokurs Französisch A2 Online</span>
<p class="description">blabla</p>
</a>
</div>
<div class="large-6 small-12 columns">
<a href="link/to/somewhere" target="_blank">
<span class="name">Französisch</span>
<p class="description">blabla</p>
</a>
</div>
<div class="large-6 small-12 columns">
<a href="link/to/somewhere" target="_blank">
<span class="name">Kurs A</span>
<p class="description">blabla</p>
</a>
</div>
<div class="large-6 small-12 columns">
<a href="link/to/somewhere" target="_blank">
<span class="name">Kurs B</span>
<p class="description">blabla</p>
</a>
</div>
</div>
</div>
If you absolutely require the nested lists then you should instead use jQuery, in a similar way to this question and not use List.js.

jQuery - Get <p> text by variable ID

Here is my code:
var itemCount = 0;
var addTo = "";
$(".add").click(function(){
alert($(this).attr('id'));
var itemClicked = $(this).attr('id');
var a = parseInt(itemClicked);
alert($(".price").find('#' + a).text());
itemCount = itemCount + 1;
});
and
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header" id="1">iPhone</h3>
<p>...</p>
<p class="hidden" id="1">1</p>
<p class="price" id="1">19.95</p>
<p><button class="btn btn-primary add" role="button" id="1">Add to cart</button> More</p>
</div>
</div>
</div>
What I want to do is write a function takes figures out which button triggered the function, and retrieves the according price to the button. In this case I pressed 1, and I want the price according to Item 1.
When I perform alert(a); then I retrieve the number of 1. So I suppose something is wrong with the following line, just cant figure out what...
alert($(".price").find('#' + a).text());
Maybe you should add a data-price attribute (or something to reference to your actual data). I don't think it's a good practice to be dependant on the value of some paragraph tags. Better is to have a separation of display data and internal data.
You can access the data-price like this:
$('.button').click(function(e) {
console.log(e.target.getAttribute('data-price'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Shop</h1>
<p>iPhone 7</p>
<p>price € 110</p>
<button data-price="110" class="button">Add</button>
You don't need id:
$("button.add").click(function(){
var $card = $(this).parents("div.caption");
alert("adding good id:"+$card.children("input.good-id").val() + " with price: " + $card.children("p.price").text());
/* note - don't send price to backend,
it can be easily corrected in browser before click,
send only id of the good, and get price from DB */
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header">iPhone</h3>
<p>...</p>
<input type="hidden" class="good-id" name="goodId" value="1">
<p class="price">19.95</p>
<p><button class="btn btn-primary add" role="button">Add to cart</button> More</p>
</div>
</div>
</div>
I updated your html markup to use data attributes. In that way it will be easier for you to select the needed prices of certain items:
<p class="hidden" data-item="1">1</p>
<p class="price" data-price="1">19.95</p>
Demo:
$('.add').on('click', function() {
var itemId = $(this).attr('id');
var itemPrice = $('.price[data-price="'+ itemId +'"]').text();
alert(itemPrice);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-5 col-md-4 col-sm-2">
<div class="thumbnail">
<img src="..." alt="...">
<div class="caption">
<h3 class="item-header" id="1">iPhone</h3>
<p>...</p>
<p class="hidden" data-item="1">1</p>
<p class="price" data-price="1">19.95</p>
<p>
<button class="btn btn-primary add" role="button" id="1">Add to cart</button> More</p>
</div>
</div>
</div>

Why ng-show is not working?

HTML
<div class="col-sm-1">
<a class="a" ng-click="aa()">
<span name="yesLink"></span>
</a>
</div>
<div class="col-sm-1">
<a class="a" ng-click="bb()">
<span name="NoLink"></span>
</a>
</div>
<div id="nnn" class="col-sm-7" align="left" >
<p ng-show="yes"> Text for yes</P>
<p ng-show="no"> Text for no</P>
</div>
JS
yesLink.onclick()=function()
{
scope.yes=true;
}
noLink.onclick()=function()
{
scope.no=true;
}
I have used the above code.I want to display message according to click.But it is not working. What is wrong with this code?
If yesLink is clicked, "Text for yes" should come and if NoLink is clicked ,"Text for no" should come.
I think, there is no need to add onclick method. just do this
<div class="col-sm-1">
<a class="a" ng-click="yes=true">
<span name="yesLink"></span>
</a>
</div>
<div class="col-sm-1">
<a class="a" ng-click="yes=false;">
<span name="NoLink"></span>
</a>
</div>
<div id="nnn" class="col-sm-7" align="left" >
<p ng-show="yes"> Text for yes</P>
<p ng-hide="yes"> Text for no</P>
</div>
I see Angular is being used in the above code so the HTML part will be
your controller part should be something like
Considering bb() and aa() as a click function
$scope.bb = function(){
$scope.yes = true;
}
$scope.aa = function(){
$scope.no = true;
}
The value you are checking against is a boolean but the value you are assigning to the variable is a string. You have two options>
OPTION 1:
Tell the ng-hide/show value to look for the string value,
ng-show="yes === 'true'".
OPTION 2:
In your function swap out the strings for boolean values,
scope.yes = true and NOT scope.yes="true"
No need for jquery, you can use ng-click, ng-click triggers the function in controler
<div class="col-sm-1">
<a class="a" ng-click="aa()">
<span name="yesLink"></span>
</a>
</div>
<div class="col-sm-1">
<a class="a" ng-click="bb()">
<span name="NoLink"></span>
</a>
</div>
<div id="nnn" class="col-sm-7" align="left" >
<p ng-show="yes"> Text for yes</P>
<p ng-show="no"> Text for no</P>
</div>
JS
scope.aa() = function(){
scope.yes = true;
}
scope.bb() = function(){
scope.no = true;
}

Find then Replace Class and text to Button

Given script find text from .label (text1 or any text), then it add class class="text1" to parent list <li> like this: <li class="text1">
Jquery:
$('.label a').each(function() {
$(this).closest('li').addClass($(this).text());
});
HTML:
<div id="main-id">
<button class="one"></button>
<button class="two"></button>
<ul>
<li> <!--List 1-->
<span class="meta">
<div class="label">
text1 <!--This text-->
</div>
</span>
</li>
<li> <!--List 2-->
<span class="meta">
<div class="label">
text2 <!--This text-->
</div>
</span>
</li>
</ul>
</div>
By this Script we get Result:
<ul>
<li class="text1"> <!--Got New class to List 1-->
<span class="meta">
<div class="label">
text1
</div>
</span>
</li>
<li class="text2"> <!--Got New class List 2-->
<span class="meta">
<div class="label">
text2
</div>
</span>
</li>
</ul>
Please See Example Fiddle >
Now following my question i'm trying to replace Class and Text to Buttons, there have two buttons like <button class="one"></button> and <button class="two"></button>, now want to place class/text .text1 (or any class) inside button,
like: <button class="one text1">text1</li></button> and <button class="two text2">text2</li></button> by same jquery given above.
I have tried this Replace text script, but i'm unable to do that. Any suggestion for other way to do this?
Thanks in advance.
Not sure exactly what you are going for but you could try something like this.
<html>
<body>
<div id="main-id">
<button class="one"></button>
<button class="two"></button>
<ul id="main-list">
<li>
<span class="meta">
<div class="label">
text1
</div>
</span>
</li>
<li>
<span class="meta">
<div class="label">
text2
</div>
</span>
</li>
</ul>
</div>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(function(){
var btns = ['.one', '.two'];
$('#main-list li').each(function(k,el){
// use clone if you don't want to remove original dom element
var $li = $(el).clone();
var className = $li.find('a').text();
$li.addClass(className)
.empty()
.text(className);
var $btn = $(btns[k]);
$btn.append($li);
});
});
</script>
</body>
</html>

Categories