Arranging multiple outputs from forEach function into one array in javascript - javascript

I'm trying to get the hrefs from the li elements with javascript. My function looks like this:
function checkUrl() {
checkUrl = function(){};
function hrefHome() {
var listCont = document.querySelectorAll(".wpcm-listings-item");
listCont.forEach(Children);
function Children(item) {
var Child = item.children;
var Hrefs = Child[0].href;
console.log(Hrefs);
}
}
}
This is returning my hrefs like I want it to, but now I need to put all of them in localStorage. I tried adding localStorage.vehHrefs = Hrefs; after the variable Hrefs, but the second one overwrites the first. What I want to do is create an array of all the hrefs and then put the array in localStorage but I need some help. Below is my HTML.
<div class="wpcm-vehicle-results-wrapper">
<ul class="wpcm-vehicle-results">
<li class="wpcm-listings-item wpcm-listings-item-featured">
<a href="http://localhost/sr19repairables/vehicle/asdfasdf/">
<div class="wpcm-listings-item-image-wrapper">
<img src="Chevy.jpg" class="wp-post-image" onload="checkUrl()"
</div>
</a>
</li>
<li class="wpcm-listings-item wpcm-listings-item-featured">
<a href="http://localhost/sr19repairables/vehicles/repairables/2020-gmc-sierra/">
<div class="wpcm-listings-item-image-wrapper">
<img src="Chevy1.jpg" class="wp-post-image" onload="checkUrl()">
</div>
</a>
</li>
</ul>
</div>

In this case, you should use map rather than forEach:
function checkUrl() {
checkUrl = function () {};
function hrefHome() {
var listCont = document.querySelectorAll('.wpcm-listings-item');
var hrefs = [...listCont].map(function Children(item) {
var Child = item.children;
return Child[0].href;
});
console.log(hrefs);
// To add it to localstorage:
localStorage.setItem('key',JSON.stringify(hrefs));
}
}

Try:
function checkUrl() {
checkUrl = function(){};
function hrefHome() {
var listCont = document.querySelectorAll(".wpcm-listings-item");
var HrefArr = [];
listCont.forEach(Children);
localStorage.vehHrefs = JSON.stringify(HrefArr);
function Children(item) {
var Child = item.children;
var Hrefs = Child[0].href;
HrefArr.push(Href)
console.log(Hrefs);
}
}
}

Related

how to render appendChild Js without duplicate

I am a new learning JS. Who can help me complete this code. I have 2 problem:
render child Node user Chat when click without duplicate
how to remove child Node user when close chat window
full code is here: Jsfiddle
// event handling when click
handleEvents: function () {
let _this = this;
userChatList.onclick = function (e) {
const userNode = e.target.closest(".user-chat__item");
if (userNode) {
userIndex = Number(userNode.getAttribute("user-num"));
_this.renderUserChat(userIndex);
const getChatWithItems = document.querySelectorAll(".chat-with__item");
getChatWithItems.forEach(item => {
item.onclick = function(e){
const itemNode = e.target.closest(".chat-with__top i");
if(itemNode){
chatWithList.removeChild(chatWithItem);
}
}
})
}
}
},
//render user chat with someone
renderUserChat: function (num) {
// console.log(userIndex);
chatWithItem = document.createElement("li");
chatWithItem.classList.add("chat-with__item");
chatWithItem.setAttribute('user-num', num);
chatWithItem.innerHTML = `
<div class="chat-with__top">
<div class="chat-with__img">
<img src="${this.users[num].img}" alt="${this.users[num].name}">
<span class="user__status ${this.users[num].status}"></span>
</div>
<p class="chat-with__name">${this.users[num].name}</p>
<i class="fa-solid fa-xmark"></i>
</div>
<div class="chat-with__body">
<ul class="chat__text">
<li class="chat-text__user">Hey. 👋</li>
<li class="chat-text__user user__chatting">I am here</li>
<li class="chat-text__user user__chatting">What's going on?</li>
<li class="chat-text__user">Have you finished the "project 2" yet?</li>
<li class="chat-text__user user__chatting">I have been fixed bugs</li>
<li class="chat-text__user">OK.</li>
</ul>
</div>
<div class="chat-width__footer">
<i class="fa-solid fa-image"></i>
<i class="fa-solid fa-folder"></i>
<div class="chat-width__input">
<input type="text" id="send-sms" name="send SMS" placeholder="...">
</div>
<i class="fa-solid fa-paper-plane-top"></i>
</div>
`
chatWithList.appendChild(chatWithItem);
},
<ul class="chat-with__list">
</ul>
I have not still known how to solve it, up to now
Just keep track which chat windows are opened in an object.
To give you basic idea of the concept:
// storage for opened chat windows
// this variable must be accessible by event handlers
const openedChats = {};
In chat opened event handler:
if (openedChats[userId]) //check if chat already opened
return;
const chatWithItem = document.createElement("li");
...
openedChats[userId] = chatWithItem; //store window
chatWithList.appendChild(chatWithItem); //show window
In chat close event handler:
const chatWithItem = openedChats[userId]; // get opened chat
if (chatWithItem)
{
chatWithItem.parentNode.removeChild(chatWithItem); // destroy window
delete openedChats[userId]; // remove window
}
If you need to get list of all userIds that have opened chat windows, use:
const openedChatsIds = Object.keys(openedChats);
Finnaly I find the way to code. This is my way
handleEvents: function () {
let _this = this;
let currentChat = [];
userChatList.onclick = function (e) {
const userNode = e.target.closest(".user-chat__item");
if (userNode) {
userIndex = Number(userNode.getAttribute("user-num"));
// get value 'userIndex' for currentChat array
function getCurrentChat(arr, index) {
arr.push(index);
}
// check value userIndex in a currentChat array
function checkCurrentChat(arr, index) {
if (arr.indexOf(index) < 0) {
getCurrentChat(currentChat, userIndex);
return true;
} else {
return false;
}
}
let isExisted = checkCurrentChat(currentChat, userIndex);
// console.log(isExisted);
if (isExisted) {
_this.renderUserChat(userIndex);
}
const getChatWithItems = chatWithList.querySelectorAll(".chat-with__item");
getChatWithItems.forEach( function(item) {
item.onclick = function (e) {
const closeChat = e.target.closest(".chat-with__top i");
if(closeChat){
const getNum = Number(closeChat.parentElement.getAttribute("user-num"));
chatWithList.removeChild(item);
const findNum = currentChat.indexOf(getNum);
currentChat.splice(findNum, 1);
}
}
})
}
}
}
inside, i add an attribute to get number (userIndex):
<div class="chat-with__top" user-num ="${num}">
if you use second .parentElement, it will ok.
closeChat.parentElement.parentElement.getAttribute("user-num")

Get id's retrieved by data attribute using javascript from li items

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

Convert list of HTML element into Javascript list of object

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>

Add entries from the top in to-do list angular

I have made this to-do list in angular but would like the posts entered to entered fro m the top instead the bottom.
my code:
HTML
<a href="{{url.title}}" class="link">
<p class="title">{{url.name}}</p>
<p class="url">{{url.title}}</p>
</a>
</div>
<div class="col-md-4 delete m-b-2">
<!--a href="javascript:" ng-click="edit($index)" type="button" class="btn btn-primary btn-sm">Edit</a-->
Delete
</div>
</div>
</li>
JS
var urlFire = angular.module("UrlFire", ["firebase"]);
function MainController($scope, $firebase) {
$scope.favUrls = $firebase(new Firebase('https://lllapp.firebaseio.com/'));
$scope.urls = [];
$scope.favUrls.$on('value', function() {
$scope.urls = [];
var mvs = $scope.favUrls.$getIndex();
for (var i = 0; i < mvs.length; i++) {
$scope.urls.push({
name: $scope.favUrls[mvs[i]].name,
title: $scope.favUrls[mvs[i]].title,
key: mvs[i]
});
};
});
You can use unshift() instead of push() when you add elements to your array. It adds the element at the beginning of your array instead of at the end, and since your angular view is based on the model it will add it on top.
Use $scope.urls.splice(index_to_insert,0, object); so in your case you could do
var obj = {
name: $scope.favUrls[mvs[i]].name,
title: $scope.favUrls[mvs[i]].title,
key: mvs[i]
};
$scope.urls.splice(0,0, obj);

Javascript push Array items in Object

I have the following issue for creating a object in Javascript
When a user clicks a button I want to push the sn_slab to the array slabs. But each serial_number is grouped by the batch_number.
The object should look something like this
var Object = {
'COFBP21018': {
slabs: {
0: 18765,
1: 38947,
...
}
},
'DEPOUS394O': {
slabs: {
0: 11006276,
1: 11020446,
...
}
},
..
}
my html looks like this
<a href=".." class="add_slab_to_array" data-batch_nr="COFBP21018" data-sn_slab="18765" />
<a href=".." class="add_slab_to_array" data-batch_nr="COFBP21018" data-sn_slab="38947" />
<a href=".." class="add_slab_to_array" data-batch_nr="DEPOUS394O" data-sn_slab="11006276" />
<a href=".." class="add_slab_to_array" data-batch_nr="DEPOUS394O" data-sn_slab="11020446" />
var block = {};
$('.add_slab_to_array').click(function(event) {
event.preventDefault();
var batch_nr = $( this ).attr('data-batch_nr');
var sn_slab = $( this ).attr('data-sn_slab');
// Create new object if batch_nr does not exists
// ADD sn_slab to Array inside the Object with related batch_nr
block[batch_nr] = {
slabs: [],
add: function(sn_slab) {
this.slabs.push(sn_slab)
}
}
block[batch_nr].add(sn_slab);
});
The code above works, but my array slabs is always overridden.
It seems to me you're redefining the block object each time you click. You should instead check if it's set before proceeding.
block[batch_nr] = block[batch_nr] || {};
block[batch_nr].slabs = block[batch_nr].slabs || [];
block[batch_nr].add = block[batch_nr].add || function(sn_slab) {
this.slabs.push(sn_slab);
};
Consider this
block[batch_nr] = {
slabs: [],
add: function(sn_slab) {
if (block[batch_nr]) {
block[batch_nr].slabs.push(sn_slab)
}
}
}

Categories