Add class to divs after reload by targeting the "data" attribute - javascript

I have four cards with the class of "card", but each one has a different data attribute: eyes, torso, arms and legs.
<div class="card" data-lesson="eyes">eyes</div>
<div class="card" data-lesson="torso">torso</div>
<div class="card" data-lesson="arms">arms</div>
<div class="card" data-lesson="legs">legs</div>
Everytime the user clicks on a card, that card is given the class of "reading". Also, the browser looks at the data attribute of that card and stores it in an array, locally.
$(".card").click(function(){
$(this).addClass("reading")
localStorage.setItem("readingCards" , readingCards)
});
What I'm trying to do is: after the page reloads, give every card that matches the data attribute stored in the array the class of "reading" so that when the page refreshes the same cards will have this class.

You can just iterate through all elements having the card class with each() and check if the corresponding data attribute is included in the comma separated local storage string.
You can try this
https://jsfiddle.net/jL6o7dc4/1/
$(document).ready(function(){
var readingCards = localStorage.getItem("readingCards")!==null?localStorage.getItem("readingCards"):'';
$(".card").each(function(){
if(readingCards.includes($(this).data("lesson"))){
$(this).addClass("reading");
}
});
$(".card").click(function(){
$(this).addClass("reading");
if(!readingCards.includes($(this).data("lesson"))){
readingCards+=(readingCards.length>0?',':'')+$(this).data("lesson");
localStorage.setItem("readingCards",readingCards);
}
});

You can try this-
The HTML is
<div class="card" data-lesson="eyes">Card 1</div>
<div class="card" data-lesson="torso">Card 2</div>
<div class="card" data-lesson="arms">Card 3</div>
<div class="card" data-lesson="legs">Card 4</div>
The Javascript is-
// On ready get the localStorage item and set the readings
var readingCards = localStorage.getItem('readingCards');
readingCards = typeof readingCards === 'string' && readingCards.length > 0 ? JSON.parse(readingCards) : [];
if (readingCards.length > 0) {
$('.card').each(function(index) {
let lesson = $(this).data('lesson');
if (readingCards.indexOf(lesson) > -1) {
$(this).addClass('reading');
}
});
}
$('.card').on('click', function() {
if (!$(this).hasClass('reading')) {
$(this).addClass('reading');
}
let lesson = $(this).data('lesson');
if (readingCards.indexOf(lesson) === -1) {
readingCards.push(lesson);
}
localStorage.setItem('readingCards', JSON.stringify(readingCards));
});

Use the css selector ".card[data-lesson='AAA']" to uniquely identify the cards while iterating over the stored values.
var storedCards = localStorage.getItem("readingCards") || "";
storedCards = storedCards.split(',');
$.each(storedCards, function( index, value ) {
$(".card[data-lesson='" + value + "']").addClass("reading");
});

Store it as an array in localstorage and then it is a simple loop to set the class by selecting items by the attribute.
$(document).ready(function() {
// read the localstorage and obtain the stored cards
// if no value, just use an empty array
var readingCards = JSON.parse(localStorage.getItem('readingCards') || '[]')
// loop over the array and add the classes to our elements
readingCards.forEach(function(value) {
$('[data-lesson="' + value + '"]').addClass('reading')
})
// add the click event to the cards
$(".card").on('click', function() {
// get the card and toggle the class
var card = $(this)
card.toggleClass('reading')
// select all the cards that are active and turn them into an array
readingCards = $(".card.reading").map(function() {
return this.dataset.lesson
}).get()
// set the array to localstorage
localStorage.setItem('readingCards', JSON.stringify(readingCards))
})
})

Related

javascript remove multiple objects from canvas with unique attribute

i'm using fabric js and trying to remove group of items when try to remove the parent item of group. following is my code.
jQuery(document).on('click', ".deleteBtn", function () {
if (canvas.getActiveObject()) {
var product_id = canvas.getActiveObject().get('product_id');
}
var canvasObj = canvas.getObjects();
for(var i = 0; i < canvasObj.length; i++){
var objRef = canvasObj[i];
var accessoryId = objRef.get('accessory_product_id');
var product_type = objRef.get('product_type');
if(accessoryId == product_id && product_type == "accessory"){
canvas.remove(objRef);
}
}
});
code is actually working, but not removing all items with same accessoryId and product_type parent item which is the active object trying to remove and two other items are removing properly. only two items left on canvas. there are all 5 items in group. those are images. i'm unable to find the issue please help. thanks!
HTML code
<div id="content-tab-3" class="visualiser-product-category content-tab active">
<ul>
<li>
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter_Spice.png" class="visualizer-product-img" alt="Placeholder" data-quantity="1" data-product_type="parent" data-product_id="343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Desk-Floral.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Garland.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Tabletop.jpg" class="hide accessory-343">
<img src="http://localhost/green_live/wp-content/uploads/2016/07/Winter-Spice-Wreath.jpg" class="hide accessory-343">
</li>
</ul>
</div>
Hello i noticed on your code that you try to get the active's object id, but no matter if there is active object or not you proceed to the loop, to delete the objects!!
Maybe, that causes the problem.
I'm going to show an example with forEach() function, but proceed to delete objects ONLY if there is active object:
jQuery(document).on('click', ".deleteBtn", function () {
//only if there is active object, do i delete objects
if (canvas.getActiveObject()) {
//get productId of active object
var product_id = canvas.getActiveObject().product_id;
//loop on the canvas objects
canvas.getObjects().forEach(function (object) {
if(object.accessoryId == product_id && object.product_type == "accessory"){
canvas.remove(object);
}
});//end forEach
}//end if
});//end 'click'
Hope helps, good luck.

jQuery find not working with object array

This code doesn't work
var next = $("#orders").find(".next");
if (next.length == 1) {
var address = $(next[0]).find(".directionsAddress");
var destination = $(address[0]).text();
}
<div id="orders" class="ui-sortable">
<div id="companyAddress" class="noDisplay">101 Billerica Avenue, North Billerica, MA</div>
<div id="companyPhone" class="noDisplay">9788353181</div><div class="next"></div>
<div class="lat">42.616007</div>
<div class="lng">-71.31187</div>
<div id="section1611" class="sectionMargin borderRad">
<div class="directionsAddress noDisplay">92+Swan+Street+Lowell+MA</div>
It is suppose to find one div with a class of "next" that I know exists on the page, then within that one item of the result set array, there will be one div with a class name of directionsAddress.
The "next" array is coming back with a length of 1, so it looks like the problem is with my $(next[0]).find because the address array is coming back as 0 length and I am making a syntax error of some sort that I don't understand.
This should do what you want. You need to find the parent (or alternatively, the sibling of .next) then try to find the applicable .directionsAddress.
var next = $("#orders").find(".next");
if (next.length == 1) {
var destination = $(next).parent().find(".directionsAddress");
alert($(destination).text());
}
Working fiddle: https://jsfiddle.net/00fgpv6L/

Add new values to attribute of the same object

I have a button that needs to add some values to an object attribute. The problem I have found is that I'm creating new objects on every click.
And what I need is to add new values to a specific attribute of a specific object.
I'm getting this
Object { id=0, title="Rolling Stones", sessionsBegin="1443564000000"}
Object { id=0, title="Rolling Stones", sessionsBegin="1443564000001"}
Object { id=0, title="Rolling Stones", sessionsBegin="1443564000002"}
What I need to generate is this
Object { id=0, title="Rolling Stones",sessionsBegin="1443564000000, 1443564000001,1443564000002"}
This on the controller part:
$scope.addItem = function(indexItem, title) {
$scope.cart = {
"id" : indexItem,
"title" : title
}
if ($scope.cart.id==indexItem){
$scope.cart.sessionsBegin=$scope.sessions[indexItem].date;
console.log($scope.cart);
}
}
This on the partial view side:
<div class="row" >
<div class="large-6 columns" >
<div class="panel">
<div ng-repeat="session in sessions">
{{event.id}} Date: {{session.date }} &nbsp
Availability: {{session.availability}} &nbsp
<a ng-click="addItem($index, session.title);" ng-show="addMore">ADD </a>
</div>
</div>
</div>
</div>
You need to concat a string to your current value, like that:
// Add a comma if needed:
$scope.cart.sessionsBegin += ($scope.cart.sessionsBegin) ? ', ' : '';
// and then add the value itself:
$scope.cart.sessionsBegin += $scope.sessions[indexItem].date;
Btw. usually you'd want a list of those sessionsBegin values to be an array - it will be much easier to work with. In that case I'd suggest:
if (!$scope.cart.sessionsBegin) {
$scope.cart.sessionsBegin = [];
}
$scope.cart.sessionsBegin.push($scope.sessions[indexItem].date);
Wouldn't changing $scope.cart.sessionsBegin=$scope.sessions[indexItem].date; to $scope.cart.sessionsBegin+=$scope.sessions[indexItem].date; do the trick?
In your code you redefine the cart object every time you press 'add' though. Hence why your console.log shows new objects every time.
$scope.cart = { ... } // this bit of code means you delete the 'old' $scope.cart and redefine it with new values
Does this work for you?
$scope.addItem = function(indexItem, title) {
$scope.cart = $scope.cart || {
"id" : indexItem,
"title" : title
}
if ($scope.cart.id==indexItem){
var sessionAsArray = $scope.cart.sessionsBegin.split(',');
sessionAsArray.push($scope.sessions[indexItem].date);
$scope.cart.sessionsBegin=sessionAsArray.join(',');
console.log($scope.cart);
}
}

How to use specific data from arrays - Example of click

I have the following JQuery code:
var test = new Array();
$(".quiz_list_row").each(function(index){
// Gets the data necessary to show game chosen
$quiz_list_id = $(this).data("quizlistId");
$quiz_level_reached = $(this).data("quizlevelReached");
test.push($quiz_list_id,$quiz_level_reached);
$(this).click(function(){
alert("test: "+test);
});
});
The divs (using html5 to send data):
<div class="quiz_list_row" data-quizlist-id="1" data-quizlevel-reached="5">
<div class="inline quiz_list_cell" id="quiz_list_cell_row0_id1">Quiz 1</div>
<div class="inline quiz_list_cell" id="quiz_list_cell_row0_id2">Current level: 5</div>
</div>
<div class="quiz_list_row" data-quizlist-id="2" data-quizlevel-reached="7">
<div class="inline quiz_list_cell" id="quiz_list_cell_row1_id1">Quiz 2</div>
<div class="inline quiz_list_cell" id="quiz_list_cell_row1_id2">Current level: 7</div>
</div>
The problem is that I need to find out how to use the data in the array test when the user clicks on a specific row (I want to use $quiz_list_id and $quiz_level_reached).
Unless there is a specific reason you're extracting the attributes and putting them into an array, I think you're taking some unecessary steps to achieving what you want. Take away the complexity from this, you have access to the data attributes with the .data() method at any time you have access to the elements jQuery object, one of those times is within the click handler itself.
var quizRows = $(".quiz_list_row");
quizRows.click(function(event) {
var self = $(this);
//As the element clicked on has it's data attributes defined
//You would just need to retrieve it when the element is clicked on
var id = self.data('quizlist-id'),
level = self.data('quizlevel-reached');
console.log("id is " + id);
console.log("level is " + level);
}

sorting elements using jquery

I have a div, #containerDiv, which contains elements related to users like first name, last name etc. in separate divs. I need to sort the contents of the container div based on the last name, first name etc. values.
On searching google the examples I got all are appending the sorted results and not changing the entire HTML being displayed. They are also not sorting by specific fields (first name, last name).
So please help me in sorting the entire content of #containerDiv based on specific fields and also displaying it.
The Page looks Like something as mentioned Below:
<div id="containerDiv">
<div id="lName_1">dsaf</div><div id="fName_1">grad</div>
<div id="lName_2">sdaf</div><div id="fName_2">radg</div>
<div id="lName_3">asdf</div><div id="fName_3">drag</div>
<div id="lName_4">fasd</div><div id="fName_4">gard</div>
<div id="lName_5">dasf</div><div id="fName_5">grda</div>
<div id="lName_6">asfd</div><div id="fName_6">drga</div>
</div>
On getting sorted by last name div values, the resulted structure of the container div should look like:
<div id="containerDiv">
<div id="lName_3">asdf</div><div id="fName_3">drag</div>
<div id="lName_6">asfd</div><div id="fName_6">drga</div>
<div id="lName_5">dasf</div><div id="fName_5">grda</div>
<div id="lName_1">dsaf</div><div id="fName_1">grad</div>
<div id="lName_4">fasd</div><div id="fName_4">gard</div>
<div id="lName_2">sdaf</div><div id="fName_2">radg</div>
</div>
Now I think you all can help me in a better way.
this is a sample example:
html:
<div id="containerDiv">
<div>2</div>
<div>3</div>
<div>1</div>
</div>
js
$(function() {
var container, divs;
divs = $("#containerDiv>div").clone();
container = $("#containerDiv");
divs.sort(function(divX, divY) {
return divX.innerHTML > divY.innerHTML;
});
container.empty();
divs.appendTo(container);
});
you may set your divs.sort function param depend on your goal.
jsFiddle.
and a jQuery Plugin is suitable
I suggest you read the div values so you get an array of objects (persons for example) or just names and perform a sort operation on that. Than...output the result to the initial div (overwriting the default values).
I have built a jQuery sort function in which you can affect the sort field.
(it rebuilds the html by moving the row to another location).
function sortTableJquery()
{
var tbl =$("#tbl tr");
var store = [];
var sortElementIndex = parseFloat($.data(document.body, "sortElement"));
for (var i = 0, len = $(tbl).length; i < len; i++)
{
var rowDom = $(tbl).eq(i);
var rowData = $.trim($("td",$(rowDom)).eq(sortElementIndex).text());
store.push([rowData, rowDom]);
}
store.sort(function (x, y)
{
if (x[0].toLowerCase() == y[0].toLowerCase()) return 0;
if (x[0].toLowerCase() < y[0].toLowerCase()) return -1 * parseFloat($.data(document.body, "sortDir"));
else return 1 * parseFloat($.data(document.body, "sortDir"));
});
for (var i = 0, len = store.length; i < len; i++)
{
$("#tbl").append(store[i][1]);
}
store = null;
}
Every time I need to sort lists I use ListJs.
It's well documented, has good performance even for large lists and it's very lightweight (7KB, despite being library agnostic).

Categories

Resources