Adding extra values to JS Object - javascript

Ok I have an HTML list containing the data I need.
It looks like this
ul
li[data-trainer]>trainee
li[data-trainer]>trainee
li[data-trainer]>trainee
I iterate it and want to make an object that looks like this
{
"Trainer":{0:Trainee1},
"Trainer2":{1:Trainee2,2:Trainee3,3:Trainee4}
}
I tried this and a bunch more
var Data = new Object();
var i = 0;
$(".blah-blah-ul li.active").each(function(){
i++;
var trainer = $(this).attr("data-trainer");
var trainee = $(this).text();
Data[trainer] = {};
Data[trainer][i] = trainee;
})
console.log(Data);
Data[trainer][i] = trainee leaves me with only the last trainee in the list.
Data from console.log:
Object
Trainer1: Object
2: Trainee2
Trainer3: Object
4: Trainee6
I tried making an array and using push or making a string but that didn't work.
If someone could please recommend a proper solution, it would be greatly appreciated.
Here's the HTML
<ul class="blah-blah-ul">
<li class="active" data-trainer="Trainer1">Trainee1</li>
<li class="active" data-trainer="Trainer1">Trainee2</li>
<li data-trainer="Trainer2">Trainee3</li>
<li data-trainer="Trainer2">Trainee4</li>
<li class="active" data-trainer="Trainer3">Trainee5</li>
<li class="active" data-trainer="Trainer3">Trainee6</li>
</ul>

Your problem was in order to have more than one value assigned to the element in the array, the sub element must be an array. This allows for adding multiple Trainee to the Trainer item in the Data object.
var Data = new Object();
var i = 0;
$(".blah-blah-ul li.active").each(function(){
i++;
var trainer = $(this).attr("data-trainer");
var trainee = $(this).text();
if(typeof Data[trainer] === 'undefined') {
Data[trainer] = {};
}
Data[trainer][i] = {trainee};
})
console.log(Data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="blah-blah-ul">
<li class="active" data-trainer="Trainer1">Trainee1</li>
<li class="active" data-trainer="Trainer1">Trainee2</li>
<li data-trainer="Trainer2">Trainee3</li>
<li data-trainer="Trainer2">Trainee4</li>
<li class="active" data-trainer="Trainer3">Trainee5</li>
<li class="active" data-trainer="Trainer3">Trainee6</li>
</ul>
Documentation on Javascript Arrays using Push, can be found here w3schools

var Data = {};
var i = 0;
$(".blah-blah-ul li.active").each(function(){
i++;
var trainer = $(this).attr("data-trainer");
var trainee = $(this).text();
Data[trainer] = {};
Data[trainer][i] = trainee;
})
console.log(Data);

Try the following approach:
Data[trainer][i] = trainee;
and you can find more info here:
How can I add a key/value pair to a JavaScript object?

Related

How to createElement of list/images in separate rows?

So below I have the HTML code that is part of my draggable/droppable:
Drag from here:
<ul id="sortable1" class="dropBox connectedSortable">
<li class="ui-state-default">Word 1</li>
<li class="ui-state-default">Word 2</li>
<li class="ui-state-default">Word 3</li>
<li class="ui-state-default">Word 4</li>
</ul>
Drop a word onto each iamge: <br>
<ul class = "row">
<li id="drop1" class="dropZones images"><img src="image1.jpg"></li>
<li id="drop2" class="dropZones images"><img src="image2.jpg"></li>
</ul>
<ul class = "row">
<li id="drop_zone3" class="dropZones images"><img src="image3.jpg"></li>
<li id="drop_zone4" class="dropZones images"><img src="image4.jpg"></li>
</ul>
</div>
I am trying to create this using document.createElement() etc. But am having difficulty doing this efficiently.
The purpose of the rows (in above code) are for formatting (using bootstrap4), since there are 6 pictures total in my array, and I want 2 rows of 3.
Below, I have an array that holds all the images' src's. This array is passed into the function. I'm able to create one row/ul, with all of the li's/images inside. But I want to be able to create what I have above, with as little hard coding as possible and as efficiently as possible.
I have:
function createType3(arr)
{
var count = 0;
var length = arr.length;
var list = document.createElement("ul");
list.classList.add("row");
for (var i = 0; i < length; i++)
{
//create list and associated ids and classes
var listPiece=document.createElement("li");
listPiece.classList.add("dropZones","images","list-inline");
listPiece.setAttribute("id","dropZone");
//create image tags and append
var imageSRC = document.createElement("IMG");
imageSRC.setAttribute("src",arr[i]);
listPiece.appendChild(imageSRC);
list.appendChild(listPiece);
}
return list;
}
I'm having trouble doing this, thank you.
You could create a document fragment and add list elements to it. Create a new list whenever i % 3 is zero. Make that 3 an argument so that you can use the function also for lists of any other number of entries:
function createType(arr, groupSize = 3) {
var lists = document.createDocumentFragment(),
list;
for (var i = 0; i < arr.length; i++) {
if (i % groupSize === 0) {
list = document.createElement("ul");
list.classList.add("row");
lists.appendChild(list);
}
//create list and associated ids and classes
var listPiece = document.createElement("li");
listPiece.classList.add("dropZones","images","list-inline");
listPiece.setAttribute("id","dropZone");
//create image tags and append
var imageSRC = document.createElement("IMG");
imageSRC.setAttribute("src", arr[i]);
listPiece.appendChild(imageSRC);
list.appendChild(listPiece);
}
return lists;
}
You could call it like this:
var frag = createType(["img1.png","img2.png","img3.png","img4.png"], 3);
document.body.appendChild(frag); // add it somewhere in your HTML page

Implement an array using foreach in Javascript

I've a several li elements which have as class : multiselect_selected_profil.
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="60">
<span class="multiselect_profil">C1</span>
</li>
I would like that for each li that has this specific class, I get its data-id and then put it into an array. At then end of the process I would like to have an array which contains all the ids.
Here is what I've tried :
$(".multiselect_selected_profil").each(function(){
var iObjetId = $(this).attr('data-id');
// ???
}
var ids = []
$(".multiselect_selected_profil").each(function(){
var iObjetId = $(this).attr('data-id');
ids.push(iObjetId);
}
Create an empty array and push ids
You can use map() to create an array from a set of matched elements:
var arr = $(".multiselect_selected_profil").map(function() {
return $(this).data('id');
}).get()
Have a look attached snippet.
var dataid = []; //Initialize the array variable
$(".multiselect_selected_profil").each(function(){
var iObjetId = $(this).attr('data-id');
dataid.push(iObjetId);
});
alert(dataid);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="60"><span class="multiselect_profil">C1</span></li>
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="61"><span class="multiselect_profil">C2</span></li>
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="62"><span class="multiselect_profil">C3</span></li>
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="63"><span class="multiselect_profil">C4</span></li>
<li id="li60" class="multiselect_my_profil multiselect_selected_profil" data-id="64"><span class="multiselect_profil">C5</span></li>
var ids = [];
$(".multiselect_selected_profil").each(function(){
if($(this)..hasClass( "specific_class_name" )){
ids.push($(this).attr('data-id'));
}
});
now you will get all ids those contains specific class
The fastest way would be specifying the data-id right in the selector description and use toArray() function to retrieve all the elements contained in the jQuery set, as an array:
var arr = $(".multiselect_selected_profil[data-id]").toArray();

Get attribute of all list items and add them to input

I have a list like this:
<ul class="draggable">
<li data-bullet="1"> item 1</li>
<li data-bullet="2"> item 2</li>
<li data-bullet="3"> item 3</li>
</ul>
Using javascript, how do I grab all the list item attributes data-bullet and insert them into the value of an input (separated by a comma):
<input id="insertme" type="hidden" name="bullet" value="">
So the end result will be:
<input id="insertme" type="hidden" name="bullet" value="1,2,3">
I know how to get individual list items but can't get my head around how to get them all and insert them there.
Here you go, A pure javascript solution
Try to use dataset at this context,
var res = "";
[].forEach.bind(document.querySelectorAll(
'.draggable > li[data-bullet]'),function(itm, i){
res += ((i) ? ":" : "") + itm.dataset.bullet;
})();
document.getElementById("insertme").value = res;
DEMO
Or the less complex and a readable version would be,
var elemArray = Array.from(document.querySelectorAll('.draggable > li[data-bullet]')),
res ="";
elemArray.forEach(function(){
res += ((i) ? ":" : "") + itm.dataset.bullet;
});
document.getElementById("insertme").value = res;
As per your new requirement, you can accomplish your task by,
$("button").click(function() {
var parent = $(this).parent();
parent.closest(".draggable").next(":text").val(parent.siblings("li").addBack().map(function(){
return $(this).data("bullet")
}).get().join(":"));
});
DEMO
try
var allBullets = [];
$(".draggable li").each(function(){
allBullets.push($(this).attr("data-bullet"));
});
$("#insertme").val(allBullets.join(","));
If you can use querySelectorAll to find elements and then map it using getAttribute method. For example (ES6 syntax):
const items = document.querySelectorAll('.draggable li');
const result = [...items].map(el => el.getAttribute('data-bullet')).join();
document.getElementById('insertme').value = result;
ES5 analogy:
var items = document.querySelectorAll('.draggable li');
var result = [].slice.call(items).map(function(el) {
return el.getAttribute('data-bullet');
}).join();
document.getElementById('insertme').value = result;

jQuery find data attributes with one datakey and multiple values

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');

Select sub element based on classes it has

Below is the HTML that I have
<ul id="QBS">
<li>
<a class="qb_mode starting Rodgers" href="#">See Stats</a>
</li>
<li>
<a class="qb_mode Manning" href="#">See Stats</a>
</li>
<li>
<a class="qb_mode Brady" href="#">See Stats</a>
</li>
</ul>
I want to find this unordered list, then tell which item has the starting qb class and then return the class that has their name (brady rodger manning) etc.
What's throwing me in a loop is the fact that the link is wrapped in the list element.
Here is what I am trying:
element = $("#qbs"); // pretty sure I want this vs getElementbyDocumentID
children = element.children();` // gets me all the list elements
for (i=0;i<children.length;i++) {
grandchild = children[i].children();
???? How would I get the 3rd class on this element?
}
Sorry about the formatting.
How about this?
var allClasses = $("#QBS").find('li a[class^="qb_"]')
.map(function () {
return this.className.split(" ").pop();
}).get();
console.log(allClasses);
Fiddle
Provided the class started with qb_* is at the beginning and you want to take only the last class of the match.
if all your class names are qb_mode then:
var allClasses = $("#QBS").find('.qb_mode').map(function () {
return this.className.split(" ").pop();
}).get();
if you want all of them then:
var allClasses = $("#QBS").find('.qb_mode').map(function () {
var cls = this.className.replace(/qb_mode/,'');
return cls.trim().split(/\W+/);
}).get();
console.log(allClasses);
Fiddle
If I understood you correctly, how about:
var name = $('#QBS a.qb_mode.starting').prop('class').replace(/\s*(qb_mode|starting)\s*/g,'');
console.log(name); // Rogers
See demo here.
a=document.getElementById('QBS');
var b=a.getElementsByClassName("qb_mode");
var i, j=b.length, result=[];
for(i=0;i<j;i++) {
c=b[i].className.split(" ");
result.push(c.pop());
}
return result;
fiddle http://jsfiddle.net/3Amt3/
var names=[];
$("#QBS > li a").each(function(i){
var a=$(this).attr("class").split(" ");
names[i]=a[(a.length-1)];
console.log("Name is " + names[i]);
});
or a more precise selector
$("#QBS > li a.qb_mode").each( ....

Categories

Resources