Delete a product on cart and localStorage - javascript

I'm currently on student project where I'm stuck on delete product on cart page I have no problem to delete them on the front page but when it come to remove it too on localStorage honestly I don't know what to do.
I know that using localStorage.setItem allow to update it when necessary but on the code that I wrote I don't know where to put correctly.
I wrote this :
// Targeting arrays
let deleteButton = document.querySelectorAll('.deleteItem');
let localStorageProducts = localStorage.getItem('Produits');
for (let i = 0; i < deleteButton.length; i++) {
// Get all remove buttons
let buttons = deleteButton[i];
// Link to his parent
let myData = deleteButton[i].closest('article');
let getStorageProducts = JSON.parse(localStorageProducts);
buttons.addEventListener("click",() =>
{
getStorageProducts.forEach(localStorageProducts =>{
if(localStorageProducts.id === myData.dataset.id){
// Delete the product
myData.remove();
localStorage.setItem('Produits',(JSON.stringify([localStorageProducts])));
}
})
})
}
<section id="cart__items">
<article class="cart__item" data-id="{product-ID}" data-color="{product-color}">
<div class="cart__item__img">
<img src="../images/product01.jpg" alt="Photographie d'un canapé">
</div>
<div class="cart__item__content">
<div class="cart__item__content__description">
<h2>Nom du produit</h2>
<p>Vert</p>
<p>42,00 €</p>
</div>
<div class="cart__item__content__settings">
<div class="cart__item__content__settings__quantity">
<p>Qté : </p>
<input type="number" class="itemQuantity" name="itemQuantity" min="1" max="100" value="42">
</div>
<div class="cart__item__content__settings__delete">
<p class="deleteItem">Supprimer</p>
</div>
</div>
</div>
</article>
</section>
An example , here I have 4 products : Products in Localstorage
When I click on one of the remove button it's gonna delete 3 of them and one left :
Product left
How could I delete them one by one ?

I refactored your logic in this way (please read comments on commented lines) :
//LOCAL TEST START: i used these lines to test with static local logics you can ignore this
let prods = [{id: 1, prodname: 'prod1'}, {id: 2, prodname: 'prod2'}, {id: 3, prodname: 'prod3'}];
localStorage.setItem('Produits',JSON.stringify(prods));
//LOCAL TEST END.
// i used getElementsByClassName because it's native function which is supported in all browsers even old ones.
let viewArticles = document.getElementsByClassName('cart__item');
let localStorageProducts = localStorage.getItem('Produits');
let products = JSON.parse(localStorageProducts);
// looping on Articles instead of Buttons to be able to get product ID easily
for (let article of viewArticles) {
article.addEventListener("click",function (ev)
{
// by {capturing: true}, i can access to the high clicked element
// (which is the <article> tag in our case) by .currentTarget property
const currentArticle = ev.currentTarget;
// by {capturing: true}, i can access to the exactly clicked child element
//(which is the delete button in this case by performing a check test using .target property class
const isDeleteBtnClicked = ev.target.classList.contains('deleteItem');
// if the child element is the delete button then
// delete the product and update the local storage
if(isDeleteBtnClicked){
// access to product id of the article
const productId = currentArticle.dataset.id;
products = products.filter(prd => prd.id.toString() !== productId.toString());
localStorage.setItem('Produits',JSON.stringify(products));
}
}, {capture: true}); // enable capturing instead of bubbling (top to bottom propagation)
}
for more informations about Capturing and Bubbling you can check this

Related

Removed object in local storage array reappears when adding new object to array

Currently a favorites function I have created with Vanilla JS works by storing the selected objects in local storage. But, when an object is removed, and then a new item is added to that same favorites array, both the original (removed) object and the newly added favorite show up in the viewport. I can confirm that both objects are removed from the array providing the data for the favorites section and then both show up when only one new object is added, but I do not know why this issue is occurring.
I have made sure to check that there is no overlap between my arrays. I print all objects that are added to the DOM into local storage for access with the favorites function and later cart functions. Included is the code for a favorites section-
Created item from original array object below-
function feetCard(array){
document.getElementById('mainpageSectionforJS').innerHTML = "";
let footCard = document.querySelector('#mainpageSectionforJS');
console.log(array,"array name");
localStorage.setItem("feetarray", JSON.stringify(array));
console.log(array, "array name");
let data = JSON.parse(localStorage.getItem("feetarray"));
console.log(data, "item data");
data.forEach(component => {
localStorage.setItem(component.valAssign, JSON.stringify(component))
});
data.forEach(component => {
footCard.innerHTML = footCard.innerHTML +
`<div class="card card-margin" id="${component.valAssign}">
<div class="card-header">
<h4> ${component.name} </h4>
<a class="kneeClick btn btn-primary" onclick="footFavorites(${component.valAssign})" > Add To Favorites </a>
<div class="card-body">
<img class="card-image" src="${component.image}"></img>
<h5> Product Description </h5>
<div>${component.manufacturer}</div>
<div>${component.lcode1}</div>
<div>${component.lcode2}</div>
<div>${component.lcode3}</div>
<div>${component.lcode4}</div>
<div>${component.hdcode}</div>
<div>$${component.cost}</div>
<div>${component.reimbursement}</div>
<div>${component.percent}</div>
<div>${component.pdac}</div>
<a class="btn btn-primary" href="${component.link}" target="_blank">${component.linkname}</a>
<input type="button" class="additionSelectButton"></input>
</div>
</div>
</div>`;
console.log("Created", component.card, "Cards");
});
console.log("Card Creation Complete");
};
Next, after clicking the favorites button-
footFavoritesArray = [];
function footFavorites(foot){
console.log(foot, "foot object");
console.log(foot.id, "foot id object");
let getStoredFavorite = JSON.parse(localStorage.getItem(foot.id));
console.log(getStoredFavorite, "retrieved cart item from local storage");
// retrieve the stored favorite item
footFavoritesArray.push(getStoredFavorite);
console.log(footFavoritesArray, "local storage array with favorite item");
// add the item to the cart array
localStorage.setItem("Foot Favorites", JSON.stringify(footFavoritesArray))
// push the cartArray to local storage
let getFavorites = JSON.parse(localStorage.getItem("Foot Favorites"));
console.log(getFavorites, "local storage favorite array");
// retrieve the stored array to check the values
document.getElementById('footItemSectionJS').innerHTML = "";
// clear the favorites viewport so the older items are removed, and redisplayed as a new one is added
let favoritesLocation = document.querySelector('#footItemSectionJS');
// document.getElementById('footItemSectionJS').innerHTML = getFavorites;
// set the location where the favorite should show in the new configuration
getFavorites.forEach(component => {
favoritesLocation.innerHTML = favoritesLocation.innerHTML +
`<div class="card favorites card-margin" id="${component.valAssign}">
<a class="footClick btn-small btn btn-primary" onclick="footCartItem(${component.valAssign})" > + Cart </a>
<img class="card-image" src="${component.image}"></img>
<div class="card-header">
<h4 id=""> ${component.name} </h4>
<a class="footClick btn btn-primary" onclick="removeFavorites(${component.valAssign})" > Remove Favorite </a>
<div id="">HD Code: ${component.hdcode}</div>
<h5><u> L-Codes </u></h5>
<div class="lcodes">
<div id="${component.lcode1}">${component.lcode1}</div>
<div id="${component.lcode2}">${component.lcode2}</div>
<div id="${component.lcode3}">${component.lcode3}</div>
<div id="${component.lcode4}">${component.lcode4}</div>
<div id="${component.lcode5}">${component.lcode5}</div>
<div id="${component.lcode6}">${component.lcode6}</div>
</div>
</div>
</div>
</div>`;
console.log("Created", component.card, "Cards");
});
}
Then, remove that favorite-
function removeFavorites(item){
console.log(item[0].id, "item [0].id");
let getfavorite = JSON.parse(localStorage.getItem("Favorites"));
console.log(getfavorite, "local storage favorite array");
// the favorites array to be modified
let favoriteSpread = {...getfavorite};
console.log(favoriteSpread, "favoriteSpread");
let parts = JSON.parse(localStorage.getItem(item[0].id));
console.log(parts, "parts, the item created from the array item in local storage ");
let indexItem = getfavorite.map(object => object.valAssign).indexOf(item[0].id);
console.log(indexItem, "Index Item")
getfavorite.splice(indexItem, 1);
console.log(getfavorite, "getfavorite Array spliced")
// splice out the item from the favorite array.
localStorage.setItem("Favorites", JSON.stringify(getfavorite));
// push the modified favoriteArray back to local storage
let showfavorite = JSON.parse(localStorage.getItem("Favorites"));
console.log(showfavorite, "local storage favorite array");
// retrieve the favorite array back from local storage
document.getElementById('footItemSectionJS').innerHTML = "";
// clear the favorites viewport so the older items are removed, and redisplayed as a new one is added
let favoritesLocation = document.querySelector('#footItemSectionJS');
// document.getElementById('footItemSectionJS').innerHTML = getFavorites;
// set the location where the favorite should show in the new configuration
showfavorite.forEach(component => {
favoritesLocation.innerHTML = favoritesLocation.innerHTML +
`<div class="card card-margin" id="${component.valAssign}">
<a class="kneeClick btn-small btn btn-primary" onclick="cart(${component.valAssign})" > + Cart </a>
<img class="card-image" src="${component.image}"></img>
<div class="card-header">
<h4 id=""> ${component.name} </h4>
<a class="kneeClick btn btn-primary" onclick="removeFavorites(${component.valAssign})" > Remove Favorite </a>
<div id="">HD Code: ${component.hdcode}</div>
</div>
</div>
</div>`;
console.log("Created", component.card, "Cards");
});
// display the retrieved array items in the "favorite"
// reload the favorite and display it anew
}
last, here is a snapshot of what is occurring in my local storage-
First, saved favorite-
[
{
"valAssign": "abc",
"manufacturer": "abc",
"name": "abc",
}
]
Second, removed-
[]
Third, add favorite of another item-
[
{
"valAssign": "abc",
"manufacturer": "abc",
"name": "abc",
},
{
"valAssign": "def",
"manufacturer": "def",
"name": "def",
}
]
also, in my local storage, the Value of the key/value pair looks like [,...] where other times it will be an object showing up in that line. Trying to provide as much information as possible.
Thanks for your help, this has stumped me.
as Layhout above answered for me, it was an issue of scope. I was not modifying the global array, only the locally stored one. That means that whenever I added a new item to the array I also added any globally stored array objects to local storage and those showed up on my viewport. Where I differed in his fix, which took me down the right path, is I am keeping the global array global, but modifying it with the function to remove a favorite. As follows-
footFavoritesArray = [];
function footFavorites(foot){
HERE IS THE ADDING FAVORITES FUNCTION (you can see the code above in the
intial post)
});
footFavoritesArray = getFavorites;
console.log(footFavoritesArray, "This is the modified global foot favorite
array")
// change the global value of the array above
// Above is the code to change the global array through the function,
notice the closing bracket is below this text.
}
function removeFootFavorites(item){
THIS IS THE LOCATION OF THE REMOVE FAVORITE CODE
});
footFavoritesArray = showfavorite;
console.log(footFavoritesArray, "This is the modified global foot favorite
array")
// change the global value of the array above
// Above is the most important code, to change the global array to the value
established by local storage.
}

How to add multiple objects to local storage with the same key

I have this piece of code that reads data from an excel sheet, turns them into objects and then display their details in a neat product card
let allHoodies = [
['Hoodie', 'Purple', 'Cotton', '$39.99', 'image/items/hoodies/hoodie(1).jpg'],
['Hoodie', 'Blue', 'Cotton', '$39.99', 'image/items/hoodies/hoodie(2).jpg'],
['Hoodie', 'Green', 'Cotton', '$39.99', 'image/items/hoodies/hoodie(3).jpg']
]
allHoodies.forEach((element, index) => {
let obj = {}
obj.id = index
obj.type = element[0]
obj.color = element[1]
obj.material = element[2]
obj.price = element[3]
obj.imagesrc = element[4]
allHoodies[index] = obj
})
//Evaluating each hoodie and displaying its information in HTML
allHoodies.forEach(function(hoodie) {
let card = `
<div class="card">
<img class="product-image" src="${hoodie.imagesrc}">
<h1 class="product-type">${hoodie.type}</h1>
<p>Color: ${hoodie.color}</p>
<p>${hoodie.material} Read more </p>
<p class="price">${hoodie.price}</p>
<p><button>Buy</button></p>
</div>
`;
// Add the card to the page
document.getElementById('product-container').innerHTML += card;
});
What I'm trying to do is, upon clicking "Buy", it adds multiple items to the local storage although I'm struggling to do it and add multiple ones, it keeps on adding only 1 of them and overwriting the previous one (I'm assuming due to the fact that they have the same key)
Here's what I've tried (which works, but its not my goal):
function addToCart(id){
let hoodie = hoodies[id];
localStorage.setItem('item', JSON.stringify(hoodie));
}
and then I simply add the addToCart() function to the button, would someone guide me and help me figure out how I could actually add multiple ones to the local storage and not just keep overwriting?
Expected result:
Runnable JSFiddle snippet
You can use localStorage#getItem to get the current list, and JSON#parse to convert it to an array of objects. Then, use Array#push to add the current item, and finally, use localStorage#set and JSON#stringify to save the updated list:
function addToCart(id) {
try {
const hoodie = allHoodies[id];
if(hoodie) {
const items = JSON.parse(localStorage.getItem('items') || "[]");
items.push(hoodie);
localStorage.setItem('items', JSON.stringify(items));
}
} catch(e) {
console.log('error adding item');
}
}
Function to show the saved list:
function displayProductsinCart() {
const products = JSON.parse(localStorage.getItem("item") || "[]");
document.getElementById("item-container").innerHTML = products.reduce((cards, product) =>
cards + `<div class="card">
<img class="item-image" src="${product.image}">
<h1 class="product-type">${product.type}</h1>
<p>Color: ${product.color}</p>
<p>${product.description}</p>
<p class="price">${product.price} </p>
<p><button>Buy</button></p>
</div>
`, '');
}

Can't print correct innerHTML message within a nested function

I'm working on a recipes page where you have a series of buttons and posts that are interconnected. The buttons have names of recipe categories such as Pie and Cake. When you click on a 'Pie' button, you are only shown the posts that are categorized as 'Pie'. Both the buttons and the posts have data attributes that have their recipe category on there.
I am able to get this to work, however, I'm having issues for when you click on a recipe category button, and there are no corresponding posts. For this, I created an empty '#message' div that would output a message if there were no recipe posts found, and an empty string if there were recipe posts.
When I click on a recipe button that does have posts, I get the 'No Recipes' text in the message. Also weird that it looks like it's applying the correct message only to the last button/post which in this example is 'Cake'.
Can someone explain why this is not working? I get it's probably a scope/closure issue, but I'm unsure what's going on.
//BUTTONS
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
postsArr.filter(function(post, i) {
if (post.dataset.postcategory == match) {
posts[i].style.display = "grid";
<-- message not working properly -->
message.innerHTML = "";
} else {
posts[i].style.display = "none";
<-- message not working properly -->
message.innerHTML = "Sorry No Recipes Available";
}
});
}
});
look at how your filter is running. you'll always get ones that match and ones that don't - so both the if and the else code will always run
What you want to do is hide/display posts in the filter, returning true for displayed and false when hidden
That way, the resulting array length will be 0 if no match, and 1 or more if there is a match
Then another if/else after determining if there is anything displayed to show/hide the message
let posts = document.querySelectorAll(".recipe");
let postsArr = Array.from(posts);
let btn = document.querySelectorAll(".recipe_button");
let btnArray = Array.from(btn);
let message = document.getElementById("message");
btnArray.forEach((button) => {
button.onclick = (el) => {
let match = el.target.dataset.btncategory;
let found = postsArr.filter(function(post) {
if (post.dataset.postcategory == match) {
post.style.display = "grid";
return true;
} else {
post.style.display = "none";
return false;
}
}).length;
message.innerHTML = found ? "" : "Sorry No Recipes Available";
}
});
<section>
<button class="recipe_button" data-btncategory="Pie">
Pie
</button>
<button class="recipe_button" data-btncategory="Cake">
Cake
</button>
</section>
//POSTS
<div id="message"></div>
<section class="recipe" data-postcategory="Pie">
<h2>Pie Recipe</h2>
</section>
<section class="recipe" data-postcategory="Cake">
<h2>Cake Recipe</h2>
</section>
Having said all that, the message would NEVER display Sorry No Recipes Available since your buttons guarantee that there will be one displayed
Here's a straightforward way to make your idea work.
It uses an event listener with event delegation.
See the in-code comments for further clarifications.
// Identifies DOM elements
const
btnsDiv = document.getElementById("btns"),
posts = [...document.getElementsByClassName("recipe")],
message = document.getElementById("message");
// Calls `filterPosts` when btnsDiv is clicked
btnsDiv.addEventListener("click", filterPosts);
// Defines `filterPosts`
function filterPosts(event){
// Ignores irrelevant clicks
if(!event.target.classList.contains("btn")){ return; }
// Shows message while there is no match
let match = false;
message.classList.remove("hidden");
// Remembers category
const category = event.target.dataset.category;
// Iterates through recipes
posts.forEach( (post) => {
// Hides recipe until it matches
post.classList.add("hidden");
// If recipe matches, shows it and notes the match
if(post.dataset.category == category) {
post.classList.remove("hidden");
match = true;
}
});
// If any match occurred, hides message
if(match == true){
message.classList.add("hidden");
}
}
.hidden{ display: none; }
<div id = "btns">
<button class="btn" data-category="Pie">Pie </button>
<button class="btn" data-category="Cake"> Cake </button>
<button class="btn" data-category="Pasta"> Pasta </button>
</div>
<div id="message" class="hidden">Sorry No Recipes Available</div>
<div class="recipe hidden" data-category="Pie">
<h2>Pie Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 1</h2>
</div>
<div class="recipe hidden" data-category="Cake">
<h2>Cake Recipe 2</h2>
</div>

sessionStorage return null

Im trying to achieve this piece of code but in my console it says thing is null which is weird because when I look in the console, sessionStorage isn't empty...
$(".btn-alert").click(function(){
var identifierOfSpan = $(this > "span").text();
for(var prop in sessionStorage){
var thing = JSON.parse(sessionStorage.getItem(prop))
if(thing.id == identifierOfSpan){
sessionStorage.removeItem(prop);
}
}
$(this).closest(".voyages").remove();
if(sessionStorage.length == 0){
alert("Message!");
location.href="reservation.html"
}
});
the button is supposed to delete the div and the sessionStorage item which looks like this
Html :
<div class="voyages">
<button class="btn btn-alert btn-md mr-2" tabindex="-1">delete the flight</button>
<span>ID : 4224762</span>
<div class="infos">
<img src="img/angleterre.jpg" alt="maroc">
<div>
<ul>
<li><h5>Angleterre, Londres (LON)</h5></li>
<li><h5>2 adulte(s)</h5></li>
<li><h5> Aucun enfants </h5></li>
<li><h5>Type : Couple</h5></li>
</ul>
</div>
</div>
<hr>
<h3>Options</h3>
<ul>
<li>voiture : 0</li>
<li>Hotel : 0 </li>
</ul>
<hr>
<h3>Prix :3713$</h3>
If I'm reading your question correctly, you want to...
Click on a button
Find the first sibling <span> element and parse a number out of its text content
Remove all sessionStorage items (JSON serialized objects) with matching id properties
For the ID, I highly recommend adding some data directly to the <button> to help you identify the right record. If you can, try something like
<button class="btn btn-alert btn-md mr-2" data-voyage="4224762"...
Try something like this
$('.btn-alert').on('click', function() {
const btn = $(this)
const id = btn.data('voyage')
// or, if you cannot add the "data-voyage" attribute
const id = btn.next('span').text().match(/\d+$/)[0]
// for index-based removal, start at the end and work backwards
for (let i = sessionStorage.length -1; i >= 0; i--) {
let key = sessionStorage.key(i)
let thing = JSON.parse(sessionStorage.getItem(key))
if (thing.id == id) {
sessionStorage.removeItem(key)
}
}
// and the rest of your code
btn.closest(".voyages").remove();
if(sessionStorage.length === 0) {
alert("Message!");
location.href = 'reservation.html'
}
})
The problem with using a for..in loop on sessionStorage is that you not only get any item keys added but also
length
key
getItem
setItem
removeItem
clear

Can I assign multiple data-id values to one attribute in one element?

I use WordPress. I have an audio player on my site. When a user clicks the play button on an individual song, it will play the song. The post ID is how the player determines which song to play.
So in the DIV that wraps the button tag, I assign an attribute: data-id which is the post id of the song. My app then grabs the MP3 file that is associated with that post ID. Simple.
My play button tag is essentially this:
<div class="item item-action" data-id="1161">
<button class="btn-playpause"></button>
</div>
The important parts of my player.js file that handles the click event and plays the song is below:
Simulate the play button
// simulate the play btn
$(document).on('click.btn', '.btn-playpause, .btn-queque', function(e){
e.stopPropagation();
var self = $(this),
item = $(this).closest('.item'),
id = item.attr('data-id'),
type = item.data('user-id') ? 'user' : 'post',
play = true;
if(!player){
getItem(id, type).done(function(obj){
if(obj.status == 'success'){
mep.mepPlaylistTracks = obj.tracks;
initPlayer();
player && player.mepSelect(0, true);
}
});
return;
}
if(self.is('.btn-queque')){
play = false;
self.parent().dropdown('toggle');
}
if( self.hasClass('is-playing') ){
self.removeClass('is-playing');
player.pause();
}else{
var index = player.find(id);
if( index !== -1){
var track = player.mepGetCurrentTrack();
if(track && track.id == id && !play) return;
player.mepSelect(index, true);
}else{
getItem(id, type).done(function(obj){
if(obj.status == 'success'){
addToPlay(obj.tracks, play);
}
});
}
}
});
getItem() function
function getItem(id, type){
return $.ajax({
type : "post",
dataType : "json",
url : ajax.ajax_url,
data : {action: "ajax_music", id : id, type: type, nonce: ajax.nonce}
});
}
addToPlay() function
function addToPlay(obj, play){
if(obj.length == 1){
player.mepAdd( obj[0], play );
}else if(obj.length > 1){
if(play){
player.options.mepPlaylistTracks = obj;
player.updatemepList();
player.mepSelect(0, true);
}else{
for(var i=0; i<obj.length; i++){
player.mepAdd( obj[i] );
}
}
}
}
You can see that once I click the play button, depending on a condition, it fires the getItem() function. getItem() takes the data-id attribute defined earlier as the id variable and begins to play the song.
The addToPlay() function will add another song to the playlist if there is already an instance of the player open. And when a user clicks another play button, it will add that new song to the list and begin to play that song.
Is it possible to modify this code so that I can add multiple data-id values to my button code so that my script will recognize there is more than one song id and add those to my playlist, using the addToPlay() function?
I'd like to do something like this
<div class="item item-action" data-id="1161, 1288, 1456">
<button class="btn-playpause"></button>
</div>
The reason I want to do this, is I would like to add a feature that will allow my users to Play All Songs on the current page they're viewing. Some of our pages, like the catalog page, displays dozens of songs that fit a certain criteria and I'd like the option to play all songs on the page.
Can anyone help push me in the right direction?
Thanks.
You could store a JSON encoded array in the data-id tag. Like:
<div class="item item-action" data-id='[1161, 1288, 1456]'>
<button class="btn-playpause"></button>
</div>
Then you can parse the array, and loop over its contents, adding each id to the queue.
See an example of parsing here: https://gist.github.com/charliepark/4266921
Here I present a alternative method.
In your markup, you can set the data-id='[1234] attribute as an encoded array. You can then collect those properties and set them as the data id property on a given element using jQuery as I illustrate here:
let someElement = $('.item');
let setItems = someElement.data('id');
let thisItem = someElement.attr('data-id');
IMPORTANT: the someElement.data('id') returns the same as the someElement.attr('data-id') (except as a string) IF nothing for that element has been set with someElement.data('id',[567,890]); which sets the property id for someElement. So, once set that way
let x = someElement.data('id'); // returns the array 567,890
let org = someElement.attr('data-id'); // still returns the [1234]
This code illustrates:
let someElement = $('.item').first();
let setItems = someElement.data('id');
let thisItemS = someElement.attr('data-id');
// make an array of the string
let thisItem = JSON.parse(thisItemS);
console.log(typeof setItems, setItems, typeof thisItemS, thisItemS, typeof thisItem, thisItem);
someElement.data('id', [567, 890]);
let x = someElement.data('id'); // returns and gets the array 567,890
let org = JSON.parse(someElement.attr('data-id')); // still returns the string [1234] made into an array
// merge with no duplicates, in the other code I used .map()
let z = Array.from(new Set(x.concat(org)));
console.log(x, org, z);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class='item' data-id='[1234]'>me the item</div>
This code show a set of elements using the concepts introduced above plus:
Set some check boxes for selection
Get the values (all)
Get the values (checkbox checked)
You can combine any of this for your original purpose, but you will need to manage that addition of new items values (and subsequently how to remove perhaps) on a given element. You might even add to a <select> element so the user then can pick some to remove perhaps...
function showPicks(choicedata) {
let ul = $('#choices').append('<ul />');
//ul.remove('li');
ul.html('empty');
ul.text('choices:');
$.each(choicedata, function(index, choice) {
let c = $('<li/>').html(choice);
ul.append(c);
});
}
$(function() {
let mydata = $('.item').map(function() {
return $(this).data('id');
}).get();
$('.all-items').data("id", mydata);
showPicks(mydata); //now do what is desired
});
$('item.item-action').filter(':not(".some-items")')
.on('click', '.btn-playpause', function() {
let setItems = $(this).closest('.item').data('id');
let thisItem = $(this).closest('.item').attr('data-id');
// do what you wish here, I show them
showPicks(setItems);
});
$('.some-items').on('click', '.btn-playpause', function(event) {
let mydata = $('.item-select').filter(':checked')
.add(this) // set an additional one from the button
.closest('.item')
.map(function() {
return $(this).data('id');
}).get();
$(event.delegatedTarget).data("id", mydata);
let setItems = $(event.delegatedTarget).data('id');
// the original pick
let thisItem = $(event.delegatedTarget).attr('data-id');
// do what you wish here
showPicks(mydata);
});
.btn-playpause {
height: 2em;
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="item item-action" data-id="[1161]">
<button class="btn-playpause" type="button"></button>
<input type="checkbox" class="item-select" />
</div>
<div class="item item-action" data-id="[1163]">
<button class="btn-playpause"></button>
<input type="checkbox" class="item-select" />
</div>
<div class="item item-action" data-id="[9961,7744]">
<button class="btn-playpause" type="button"></button>
<input type="checkbox" class="item-select" />
</div>
<div class="item item-action all-items" data-id="[42]">
<button class="btn-playpause" type="button">Play All</button>
</div>
<div class="item item-action some-items" data-id="[95]">
<button class="btn-playpause" type="button">Play selected</button>
</div>
<div id="choices">none</div>

Categories