I have a function which is triggered on by the click of an update button. When the button is clicked all the elements in a list from a particular div are captured. Each list has about 3 to 4 data attributes. I want create an array in jquery or javascript where the created array is grouped by certain data attributes. Below is the function am using
<div>
<ul id="listDiv" >
<li style="" id="id1" data-type="edit" data-seq="1" data-name="name1">Name1</li>
<li style="" id="id2" data-type="edit" data-seq="2" data-name="name2">Name2</li>
<li style="" id="id3" data-type="create" data-seq="3" data-name="name3">Name3</li>
</ul>
</div>
<a class='upBtn' > Update </a>
$('.upBtn').on('click', function(){
var data = [];
$('#lisDiv li').each(function() {
var id = $(this).attr('id');
var type = $(this).attr('data-type');
data[type]= [];
data[type][id] = [];
data[type][id]['type'] = $(this).attr('data-type');
data[type][id]['seq'] = $(this).attr('data-sequence');
data[type][id]['name'] = $(this).attr('data-name');
});
console.log(data);
})
I tried using push as much as possible. But I am not getting the result I intended. I want the result to be like the format, below:
[edit] => [id1] => ('type') => 'edit',
('seq') => 2,
('name') => 'name1'
[id2] => ('type') => 'edit',
('seq') => 1,
('name') => 'name2'
[create] => [id3] => ('type') => 'edit',
('seq') => 3,
('name') => 'name3'
[id4] => ('type') => 'edit',
('seq') => 4,
('name') => 'name4
'
But whenever I try the array is not getting pushed. I am not sure how to use push here. Any help is highly appreciated.
You need to take objects instead of arrays.
By taking array, you get still the properties, but you can neither see them with console.log, nor stringify them, because an array is stringified with the numerical (positive 32 bit integer) indices.
var data = {};
// ...
data[type] = data[type] || {};
data[type][id] = {};
In your code, you have the wrong identifier, it should be listDev and you need to use a default value for assigning the type.
$('.upBtn').on('click', function() {
var data = {};
$('#listDiv li').each(function() { // listDiv spelling
var id = $(this).attr('id'),
type = $(this).attr('data-type');
data[type] = data[type] || {}; // prevent overwriting the object
data[type][id] = {
type: $(this).attr('data-type'),
seq: $(this).attr('data-seq'), // seq instead of sequence
name: $(this).attr('data-name')
};
});
console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul id="listDiv">
<li style="" id="id1" data-type="edit" data-seq="1" data-name="name1">Name1</li>
<li style="" id="id2" data-type="edit" data-seq="2" data-name="name2">Name2</li>
<li style="" id="id3" data-type="create" data-seq="3" data-name="name3">Name3</li>
</ul>
</div>
<a class='upBtn'>Update</a>
Related
I have an unordered list, each element of which I want to put in an array.
<div id='main'>
<ul>
<li>First</li>
<li>Second</li>
</ul>
</div>
I need to transfer it to JSON object like this:
"type": "list",
"data": ["* First", "* Second"]
For now, i have function which return all data from list in string:
let newObj = document.createElement("div");
newObj.innerHTML = document.getElementsByTagName('UL')[0].innerHTML;
[...newObj.querySelectorAll("li")].forEach(ele => ele.parentNode.replaceChild(document.createTextNode("* "+ele.textContent)),ele);
return newObj
You can select all of the li. Then map it getting textContent and adding * as prefix
const items = document.querySelectorAll('#main li');
const result = {
type: 'list',
data: Array.from(items).map(el => `* ${el.textContent}`),
}
console.log(result)
<div id="main">
<ul>
<li>First</li>
<li>Second</li>
</ul>
</div>
You can use jquery:
let $li = $('#main').find('li') //returns a collection
let array = $.map($li, e => '* ' + e.textContent)
Converting to JSON:
let toJson = JSON.stringify(array)
i want the product pages marked as PageType = 'item' (inside only one category) to display different HTML code according to language mutation of a webpage. What i've achieved so far is that on every mutation page is the same content X times (x = object items such as "eng": "categoryname" )
var html = `
<div class="">
<a class="" href="#" target="_blank">
<img src="different images with site language mutation" alt="banner">
</a>
</div>
`;
var langcode = $('html').attr('lang');
var maincat = [];
$(".breadcrumbclass").each(function() {
var vat = $(this).text();
maincat.push(vat);
});
var mycategory = maincat[1];
$.each(langmutations, function(key, val) {
if (((PageType == 'item') || (PageType === 'category')) && (mycategory === langmutations[langcode])) {
$('.classForPastingMyHtml').after(html);
}
});
//This is what i have in JS
var langmutations0 = {
eng: 'categoryname',
de: 'kategoriename',
ru: 'categorija'
};
//or
var langmutations1 = [
["eng", "categoryname"],
["de", "kategoriename"],
["ru", "categorija"]
];
//I believe this is PHP style
var langmutations2 = ['eng' => 'categoryname', 'de' => 'kategoriename', 'ru' => 'categorija'];
//This could be multiple array in PHP style ? I want to have this in JS
var multiple = [eng => [“cat” => “categoryname”, “banner” => “link”], de => [“cat” => “kategoriename”, “banner” => “link”], ru => [“cat” => “categorija”, “banner” => “link”]];
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think that i should use something like multiple array, but don't know if that exists in JS or how to structure it. Or maybe javascript object that would respond to that PHP style.
Here is some simple code to get you started:
var multiple = {
eng : {"cat" : "categoryname", "banner" : "link"},
de : {"cat" : "Kategoriename", "banner" : "link"},
ru : {"cat" : "categorija", "banner" : "link"}
};
var language = 'de';
var translations = multiple[language];
var cat = translations.cat;
console.log(cat);
//Show all translations
$.each(multiple, function(language,translations){
var cat = translations.cat;
console.log(cat);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
It uses objects inside objects with language as keys.
JavaScript
var sessions = [];
$('.rightDiv').each(function(index) {
var session = $.trim($(this).text().slice(0, -1)).split("×");
var sessionData = [];
for (var i = 0; i < session.length; i++) {
var ids = $(this).find('li').data('id');
var s = {
subjectOrder: i,
subjectID: ids
};
sessionData.push(s);
}
var ses = {
sessionNo: index,
sessionData: sessionData
};
sessions.push(ses);
});
HTML
<ul id="form_builder_sortable_sample" class="sortable rightDiv session4 ui-sortable">
<li class="draggable" data-id="1" name="Counting" >Counting<button onclick="deleteElement(event)" class="delbtn">×</button></li>
<li class="draggable" data-id="2" name="Priorities" >Priorities" class="delbtn">×</button></li>
</ul>
JSON
{"sessionNo":"0","sessionData":[{"subjectOrder":"0","subjectID":"1"},{"subjectOrder":"1","subjectID":"1"}]}
My Problem
What the code above does, is retrieves the session no from the ul class: class="sortable rightDiv session4" and each id of the li from data-id.
In this case it loops fine through the li items, but it only displays the id of the first li element.
It should be:
{"sessionNo":"0","sessionData":[{"subjectOrder":"0","subjectID":"1"},{"subjectOrder":"1","subjectID":"2"}]}
Any idea what's wrong?
Since you are using $(this).find('li').data('id');, it will always return the value of first li data attribute.
Use .each() to iterate and create an array
var sessionData = [];
$(this).find('li').each(function (index, elem) {
sessionData.push({
subjectOrder: index,
subjectID: $(elem).data('id')
});
})
change:
var ids = $(this).find('li').data('id');
to:
var ids = $(this).find('li').eq(i).data('id');
I'm trying to convert something like this HTML snippet:
<ul>
<li><span>Frank</span><img src="pic.jpg"></li>
<li><span>Steve</span><img src="pic2.jpg"></li>
</ul>
into a JavaScript objects that contain the name and the image's url. How can I do that?
Use map() method
var res = $('ul li').map(function() { // select all li and iterate
// return as required format of array elemnt
return {
name: $('span', this).text(), // get text in span
src: $('img', this).attr('src') // get src attribute
}
}).get(); // get array from jquery object
console.log(res);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><span>Frank</span>
<img src="pic.jpg">
</li>
<li><span>Steve</span>
<img src="pic2.jpg">
</li>
</ul>
UPDATE : If you want to generate an object which has key as span text and value as src attribute then use each() method and iterate over elements and generate object.
var res = {};
$('ul li').each(function() { // select all li and iterate
res[$('span', this).text().trim()] = $('img', this).attr('src');
})
console.log(res);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><span>Frank</span>
<img src="pic.jpg">
</li>
<li><span>Steve</span>
<img src="pic2.jpg">
</li>
</ul>
var objs = document.querySelectorAll('.to-js-obj li');
var objs_arr = [];
if (objs) {
for (var i = 0; i < objs.length; i++) {
var name = objs[i].querySelector('span').innerText;
var url = objs[i].querySelector('img').src;
objs_arr.push({
name: name,
src: url
});
}
console.log(JSON.stringify(objs_arr));
}
<ul class="to-js-obj">
<li><span>Frank</span>
<img src="pic.jpg">
</li>
<li><span>Steve</span>
<img src="pic2.jpg">
</li>
</ul>
Using jQuery
var $list = $('ul'), // get the list (ideally, add an ID)
$listItems = $list.find('li'); // find list items
if( $listItems.length > 0 ) { // if list items exist
var images = []; // create empty array to store objects
$.each( $listItems, function( index ) { // loop through the list items
var $item = $( $listItems[index] ); // save item as jQuery element
var name = $item.find('span').text(); // Get name from span
var imageSrc = $item.find('img').attr('src'); // Get img src
images[index] = {}; // Create new object in array
images[index].name = name; // Add name
images[index].imageSrc = imageSrc; // Add source
});
}
Returns
[Object {
imageSrc: "pic.jpg",
name: "Frank"
}, Object {
imageSrc: "pic2.jpg",
name: "Steve"
}]
You can use this:
var image_pairs = [];
$("ul li").each(function() {
image_pairs.push({
name: $(this).find("span").text(),
url: $(this).find("img").attr("src")
});
});
console.log(image_pairs);
<ul>
<li><span>Frank</span><img src="pic.jpg"></li>
<li><span>Steve</span><img src="pic2.jpg"></li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I want want to display and count only batter in batters at index 0.
i.e id = 1001 type = regular
and count should be "4"
Maybe this updated JSFiddle will give you an idea.
HTML
<div ng-app="myApp" ng-controller="customersCtrl">
<ul ng-repeat="x in myData">
<li ng-repeat = "batter in x.batters.batter | filter: {'id': 1001, 'type': 'Regular'}">
{{ batter.id }} - {{ batter.type }}
</li>
</ul>
{{countBatters(1001, 'Regular')}}
</div>
Added function in controller:
$scope.countBatters = function(id, type) {
return $scope.myData.filter(function(obj) {
var batter = obj.batters.batter[0];
return batter.id == id && batter.type == type
}).length;
}
Use array filter method..
var getBatter1001 = (item) => { return item.batters.batter.filter((x) => {x.id === '1001'}); }
var batter1001 = $scope.myData.filter(getBatter1001);
console.log('Count of objects with batter id 1001: '+batter1001.length); // Logs 3