I have multiple <ul>-s which has attributes id, data-type and data-value. All id-s have a same prefix.
<ul id='req-*****' data-type='***' data-value='***'>
some <li>-s here
</ul>
. . .
many <ul>-s here
. . .
I have Javascript function where I want to loop through this <ul>-s whose ids starting with 'req' and collect data-type and data-value attribute values like that:
function collect(){
var data = [];
$.each( uls_starting_with_req, function( key, value ) {
data.push({data_type: 'ul_data_type', data_value: 'ul_data_value'});
});
}
So how can I achieve this?
function collect(){
var data = [];
$('ul').each(function(){
var id = $(this).attr('id');
if(id.startsWith('req') ) {
var dataType = $(this).data('type');
var dataValue = $(this).data('value');
data.push({data_type: dataType, data_value: dataValue})
}
})
}
Following is a way to do it:
var data = [];
$("ul[id^='req-']").each(function() {
data.push({ data_type: $(this).data('type'), data_value: $(this).data('value') });
});
The selector selects all the uls which have ID starting with req- and then each loops on them. In each iteration, the value of the data attributes can be fetched using jQuery's data method, which are then pushed to the array data.
Working example:
var data = [];
$("ul[id^='req-']").each(function() {
data.push({
data_type: $(this).data('type'),
data_value: $(this).data('value')
});
});
console.log(data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='1' data-value='1'>
<li></li>
</ul>
<ul id='req-2' data-type='2' data-value='2'>
<li></li>
</ul>
<ul id='req-3' data-type='3' data-value='3'>
<li></li>
</ul>
using attribute starts with selector:
function collect(){
var data = [];
$('ul[id^="req-"]').each(function(){
data.push({data_type: '+ $(this).data("type") +', data_value: '+ $(this).data("value") +'});
})
}
Use jquery attribute selector
function collect() {
var data = [];
var getUL = $('ul[id^="req-"]');
$.each(getUL, function(key, value) {
data.push({
data_type: $(value).data('type'),
data_value: $(value).data('value')
});
});
console.log(data)
}
collect()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='x' data-value='y'></ul>
<ul id='somOtherId' data-type='x2' data-value='y2'></ul>
<ul id='req-3' data-type='x3' data-value='y3'></ul>
Modified brk's answer to use map off of the jQuery object
function collect() {
var getUL = $('ul[id^="req-"]');
var data = getUL.map(function(key, value) {
return {
data_type: $(value).data('type'),
data_value: $(value).data('value')
};
});
console.log(data.get())
}
collect()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='x' data-value='y'></ul>
<ul id='somOtherId' data-type='x2' data-value='y2'></ul>
<ul id='req-3' data-type='x3' data-value='y3'></ul>
jQuery is relevant if you have to deal with browsers different implementations/incompatibilities or if what you would like to achieve is quite verbose using vanilla JavaScript.
But if you target recent browsers, you should consider vanilla JavaScript instead since the required code in this case looks pretty the same.
function collect() {
return Array.prototype.slice.call(document.querySelectorAll('ul[id^="req-"]'))
.map(function(x) {
return {data_type: '+ '+x.dataset.type+' +', data_value: '+ '+x.dataset.value+' +'}
});
}
// ES6 version
function collectES6() {
return Array.from(document.querySelectorAll('ul[id^="req-"]'), x => {
return {data_type: `+ ${x.dataset.type} +`, data_value: `+ ${x.dataset.value} +`}
});
}
console.log('Vanilla version (JavaScript 1.6):', collect());
console.log('Es6 version', collectES6());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="req-x" data-type="XX" data-value="xxvalue"></ul>
<ul id="req-y" data-type="YY" data-value="ffvalue"></ul>
<ul id="req-z" data-type="ZZ" data-value="zzvalue"></ul>
Related
I want to pass(return) data-filter value and children text , I am able to pass the data-filter value but I am unable to pass the children text. My HTML and JQuery as following:
$(document).ready(function() {
$('.sidebar-filter').on('click', function() {
var filterobj = {};
$(".sidebar-filter").each(function(index, ele) {
var filterval = $(this).children('a').text();
var filterkey = $(this).data('filter');
filterobj[filterkey] = Array.from(document.querySelectorAll('li[data-filter=' + filterkey + '].active')).map(function(el) {
return ele.value;
});
});
console.log(filterobj);
});
});
<ul>
<li class="sidebar-filter " data-filter="category" data-value="1">
Item Name
</li>
</ul>
My return will be like:
category: Array [ undefined ]
I want value inside the array instead of undefined.
Your lis don't have attribute value, actually you want to read attribute data-value, you can achieve your goal by converting return ele.value; to return el.getAttribute('data-value');
$(document).ready(function() {
$('.sidebar-filter').on('click', function() {
var filterobj = {};
$(".sidebar-filter").each(function(index, ele) {
var filterval = $(this).children('a').text();
var filterkey = $(this).data('filter');
filterobj[filterkey] = Array.from(document.querySelectorAll('li[data-filter=' + filterkey + '].active')).map(function(el) {
return el.getAttribute("data-value");
});
});
console.log(filterobj);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<ul>
<li class="sidebar-filter active" data-filter="category" data-value="1">
Item Name
</li>
</ul>
Posting answer, might be of help to someone others too
filterobj[filterkey]= Array.from(document.querySelectorAll
('li[data-filter=' + filterkey+'].active')).map(function(el){
return $(el).data("value")
});
I am using angularjs I have two list when I click first one I will push the value into another scope and bind the value to second list. Now my requirement is when first list values which are moved to second list, I need to change the color of moved values in list1
Here I attached my fiddle
Fiddle
You can use findIndex and ng-class together to check if the second list contains the same item as first. If present apply css class to the first list item.
JS:
$scope.checkColor = function(text) {
var index = $scope.linesTwos.findIndex(x => x.text === text);
if (index > -1) return true;
else return false;
}
HTML:
<li ng-click="Team($index,line.text)" ng-class="{'change-color':checkColor(line.text)}">{{line.text}}</li>
Working Demo: https://jsfiddle.net/7MhLd/2659/
You can do something like this:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.lines = [{
text: 'res1'
},
{
text: 'res2'
},
{
text: 'res3'
}
];
$scope.linesTwos = [];
$scope.Team = function(index, text) {
var obj = {};
obj.text = text;
$scope.linesTwos.push(obj)
}
$scope.Team2 = function(index, text2) {
$scope.linesTwos.splice(index, 1)
}
$scope.containsObj = function(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (angular.equals(list[i], obj)) {
return true;
}
}
return false;
};
}
.clicked {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<ul ng-repeat="line in lines">
<li ng-class="{'clicked': containsObj(line,linesTwos)}" ng-click="Team($index,line.text)">{{line.text}}</li>
</ul>
<ul>
<li>__________</li>
</ul>
<ul ng-repeat="line in linesTwos">
<li ng-click="Team2($index,line.text)">{{line.text}}</li>
</ul>
</div>
you have to achieve it using ng-class and create a dynamic class style for pushed data please check my working example fiddle
JS fiddle sample
in HTML nedd to do these changes
<li ng-click="Team($index,line.text,line)" ng-class="{'pushed':line.pushed}">
<li ng-click="Team2($index,line.text,line)">
In css
.pushed{color:red;}
In Controller
`$scope.Team=function(index,text,line){
var obj={};
obj = line;
$scope.linesTwos.push(obj)
line.pushed = true;
}`
`scope.Team2 = function(index,text2,line){
$scope.linesTwos.splice(index,1)
line.pushed = false;
}
`
its because angular two way binding
I have an array where each element refers to a bunch of svgs in another js file. I'm trying to get it so that my alert message uses the same string I use in the array variable.
var illustArr = ['map', 'privacy', 'payment', 'rewards', 'passcode'];
var bmAnim = document.getElementById('illus-'+illustArr[i]);
bmAnim.addEventListener('click', function(){
alert('illus-'+illustArr[i]);
});
Any ideas how to achieve that?
You can do it using a for-loop. Also make sure that you check if element exists so that you wont get an error.
var illustArr = ['map', 'privacy', 'payment', 'rewards', 'passcode'];
for (var i = 0; i < illustArr.length; i++) {
bmAnim = document.getElementById('illus-' + illustArr[i]);
if (bmAnim) { //check if element exists
bmAnim.addEventListener('click', function() {
alert('illus' + this.id);
});
}
}
<div id="illus-map">MAP</div>
<p>
<div id="illus-privacy">PRIVACY</div>
<p>
<div id="illus-payment">PAYMENT</div>
<p>
<div id="illus-rewards">REWARDS</div>
<p>
<div id="illus-passcode">PASSCODE</div>
You need to iterate over the array and assign the click function with the corresponding key in scope.
var illustArr = ['map', 'privacy', 'payment', 'rewards', 'passcode'];
illustArr.forEach(function (key) {
var bmAnim = document.getElementById('illus-' + key);
bmAnim && bmAnim.addEventListener('click', function () {
alert('illus-' + key);
});
});
You should use the Array#forEach function to iterate over the elements in your array before you attach any listeners to the click event. Also, you can use this.id in the event handler to reference the string illus-* with the desired suffix rather than accessing illustArr again.
var illustArr = ['map', 'privacy', 'payment', 'rewards', 'passcode'];
illustArr.forEach(function (e) {
document.getElementById('illus-' + e).addEventListener('click', handler)
})
function handler () {
alert(this.id)
}
<ul>
<li id="illus-map">Map</li>
<li id="illus-privacy">Privacy</li>
<li id="illus-payment">Payment</li>
<li id="illus-rewards">Rewards</li>
<li id="illus-passcode">Passcode</li>
</ul>
I want to retrive all the objects with one datakey and multiple values, for QuickSand:
<ul>
<li data-company="Microsoft">Steve</li>
<li data-company="Google">Jobs</li>
<li data-company ="Facebook">Michael</li>
<li data-company ="Google">Richard</li>
<li data-company ="Facebook">Tim</li>
</ul>
How can i retreve all the li items with data-company Microsoft and Google (these two values are in a array) like this:
var itemes = $('ul').find('li[data-comapany={"Microsoft","Google"}]');
Thank you.
you could create an array of the required companies, and check for each li if the data is contained in that array:
var companies = ["Microsoft", "Google"];
$(function() {
var items = $('ul li').filter(function() {
return $.inArray($(this).data("company"), companies) > -1;
});
items.css({
"position": "relative",
"margin-left": "25px"
});
console.log(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li data-company="Microsoft">Steve</li>
<li data-company="Google">Jobs</li>
<li data-company="Facebook">Michael</li>
<li data-company="Google">Richard</li>
<li data-company="Facebook">Tim</li>
</ul>
You could filter it:
var itemes = $('ul').find('li').filter(function(){
return $(this).data('company').match(/Microsoft|Google/);
});
-DEMO-
To handle case for LI without any data-company set, you should use:
var itemes = $('ul').find('li').filter(function(){
var data = $(this).data('company');
return data ? data.match(/Microsoft|Google/) : null;
});
You can also combine selectors:
var items = $("[data-company*='Microsoft'], [data-company*='Google']");
jsFiddle
You could do it like this:
var companies = ['Google', 'Microsoft', 'Waffle House'];
companies.forEach(function(company, index) {
companies[index] = "li[data-company='" + company + "']";
});
$('ul').find(companies.join(',')).css('background', 'red');
I have a JSON witch looks something like this
{
"English": "en",
"Francais": "fr",
"German": "gm"
}
Now I need to print this data in HTML structure witch looks like this
<ul id="links">
<li class="home">
</li>
<li class="languages">
EN ------ > FIRST LANGUAGE FROM JSON
<ul class="available"> ----> OTHERS
<li>DE</li>
<li>IT</li>
<li>FR</li>
</ul>
</li>
</ul>
In javascript I know how to get data and print all data in the same structure but how to do it in structure shown in example ?
in Javascript I'm getting data with
$.getJSON('js/languages.json', function(data) {
console.log(data);
/* $.each(data, function(key, val) {
console.log(val);
});*/
});
Use jQuery template to bind the Html. Some Sample
Something like that:
var getBlock = function(skipLang) {
var str = '\
<ul id="links">\
<li class="home">\
\
</li>\
<li class="languages">\
' + data[skipLang] + '\
<ul class="available">\
';
for(var lang in data) {
if(lang != skipLang) {
str += '<li>' + lang + '</li>';
}
}
str += '</ul></li></ul>';
return str;
}
var html = '';
for(var lang in data) {
html += getBlock(lang);
}
Although using templating engine is an option for simpler code, for this case you can directly run a for loop and assign HTML within javascript code easily.
HTML part is going to be something like this
<ul id="links">
<li class="home">
home
</li>
<li class="languages">
<ul class="available">
</ul>
</li>
</ul>
And JS part is like this:
var data = {
"English": "en",
"Francais": "fr",
"German": "gm"
};
var $liLanguages = $('li.languages');
var $ulAvailable = $('ul.available');
var selectedLanguage = '';
for(var index in data) {
if(selectedLanguage == '') {
selectedLanguage = data[index];
$liLanguages.prepend("<a href='#'>" + data[index].toUpperCase() + "</a>");
}
else {
$ulAvailable.append("<li><a href='#'>" + data[index].toUpperCase() + "</a></li>");
}
}
Here is the jsfiddle related.
Hope this helps.
Here is a bit that will get you two new objects, one for the first object property/value and another for the remaining. Still not clear what is done with it once you have it, but let me know if it helps:
// This can be replaced with existing data or updated to var langs = data;
var langs = {"English": "en", "Francais": "fr","German": "gm" };
// jQuery map only works on objects after 1.6, heads up
var lang_keys = $.map( langs, function( value, key ) {
return key;
});
// Now that you have an array of the keys, you can use plain-ol shift()
var primary_lang_key = lang_keys.shift();
// create and populate an object just for your first language:
var primary_lang = {};
primary_lang[primary_lang_key] = langs[primary_lang_key];
// Thanks to shift, we know that populating this object with lang_keys will
// only have remaining items:
var other_langs = {};
$.map( lang_keys, function( lang_key ) {
other_langs[lang_key] = langs[lang_key];
});
console.log(other_langs);