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)
}
}
}
Related
I'm looping through all the html tags in an html-file, checking if those tags match conditions, and trying to compose a JSON-object of a following schema:
[
{ title: 'abc', date: '10.10.10', body: ' P tags here', href: '' },
{ title: 'abc', date: '10.10.10', body: ' P tags here', href: '' },
{ title: 'abc', date: '10.10.10', body: ' P tags here', href: '' }
]
But I'd like to create the new entry only for elements, classed "header", all the other elements have to be added to earlier created entry. How do I achieve that?
Current code:
$('*').each((index, element) => {
if ( $(element).hasClass( "header" ) ) {
jsonObject.push({
title: $(element).text()
});
};
if( $(element).hasClass( "date" )) {
jsonObject.push({
date: $(element).text()
});
}
//links.push($(element))
});
console.log(jsonObject)
Result is:
{
title: 'TestA'
},
{ date: '10.10.10' },
{
title: 'TestB'
},
{ date: '10.10.11' }
I'd like it to be at this stage something like:
{
title: 'TestA'
,
date: '10.10.10' },
{
title: 'TestB'
,
date: '10.10.11' }
UPD:
Here's the example of HTML file:
<h1 class="header">H1_Header</h1>
<h2 class="date">Date</h2>
<p>A.</p>
<p>B.</p>
<p>С.</p>
<p>D.</p>
<a class="source">http://</a>
<h1 class="header">H1_Header2</h1>
<h2 class="date">Date2</h2>
<p>A2.</p>
<p>B2.</p>
<p>С2.</p>
<p>D2.</p>
<a class="source">http://2</a>
Thank you for your time!
Based on your example Html, it appears everything you are trying to collect is in a linear order, so you get a title, date, body and link then a new header with the associated items you want to collect, since this appears to not have the complication of having things being ordered in a non-linear fasion, you could do something like the following:
let jsonObject = null;
let newObject = false;
let appendParagraph = false;
let jObjects = [];
$('*').each((index, element) => {
if ($(element).hasClass("header")) {
//If newObject is true, push object into array
if(newObject)
jObjects.push(jsonObject);
//Reset the json object variable to an empty object
jsonObject = {};
//Reset the paragraph append boolean
appendParagraph = false;
//Set the header property
jsonObject.header = $(element).text();
//Set the boolean so on the next encounter of header tag the jsobObject is pushed into the array
newObject = true;
};
if( $(element).hasClass( "date" )) {
jsonObject.date = $(element).text();
}
if( $(element).prop("tagName") === "P") {
//If you are storing paragraph as one string value
//Otherwise switch the body var to an array and push instead of append
if(!appendParagraph){ //Use boolean to know if this is the first p element of object
jsonObject.body = $(element).text();
appendParagraph = true; //Set boolean to true to append on next p and subsequent p elements
} else {
jsonObject.body += (", " + $(element).text()); //append to the body
}
}
//Add the href property
if( $(element).hasClass("source")) {
//edit to do what you wanted here, based on your comment:
jsonObject.link = $(element).next().html();
//jsonObject.href= $(element).attr('href');
}
});
//Push final object into array
jObjects.push(jsonObject);
console.log(jObjects);
Here is a jsfiddle for this: https://jsfiddle.net/Lyojx85e/
I can't get the text of the anchor tags on the fiddle (I believe because nested anchor tags are not valid and will be parsed as seperate anchor tags by the browser), but the code provided should work in a real world example. If .text() doesn't work you can switch it to .html() on the link, I was confused on what you are trying to get on this one, so I updated the answer to get the href attribute of the link as it appears that is what you want. The thing is that the anchor with the class doesn't have an href attribute, so I'll leave it to you to fix that part for yourself, but this answer should give you what you need.
$('*').each((index, element) => {
var obj = {};
if ( $(element).hasClass( "header" ) ) {
obj.title = $(element).text();
};
if( $(element).hasClass( "date" )) {
obj.date = $(element).text()
}
jsonObject.push(obj);
});
I don't know about jQuery, but with JavaScript you can do with something like this.
const arr = [];
document.querySelectorAll("li").forEach((elem) => {
const obj = {};
const title = elem.querySelector("h2");
const date = elem.querySelector("date");
if (title) obj["title"] = title.textContent;
if (date) obj["date"] = date.textContent;
arr.push(obj);
});
console.log(arr);
<ul>
<li>
<h2>A</h2>
<date>1</date>
</li>
<li>
<h2>B</h2>
</li>
<li>
<date>3</date>
</li>
</ul>
Always use map for things like this. This should look something like:
let objects = $('.header').get().map(el => {
return {
date: $(el).attr('date'),
title: $(el).attr('title'),
}
})
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);
}
}
}
I'm new to AngularJS, so sometimes when I do some mistake that is obvious, I still can't figure out what is going wrong with my code. So saying, here is my doubt:
HTML code:
<body ng-controller = "Ctrl">
<script id="Page6.html" type="text/ng-template">
<div class="list card" style="background-color: beige">
<div class="item item-icon-left">
<i class="icon ion-home"></i>
<input type="text" placeholder = "Enter display name" ng-model="user.nam">
</div>
<a ng-click = "saveedit(user)"<button class="button button-clear">SAVE DETAILS</button></a>
</div>
</script>
</body>
CONTROLLER.JS
.controller('Ctrl',function($scope,$rootScope,ContactService){
$rootScope.saveedit=function(user) {
ContactService.save({names: user.nam, image:"images.jpg"},ContactService.getid("Donkey"));
}
});
THIS IS THE SERVICE:
.service('ContactService', function () {
var items = [
{ id: 1, names: 'Dolphin', image: 'dolphin.jpg',}, { id: 2, names: 'Donkey', image: 'donkey.jpg'}, { id: 3, empid: 'FG2043', image: 'penguin.jpg'}];
var im = [{image: ''}];
var ctr=0;
var uid=3;
this.save = function (contact,id) {
ctr=0;
for (i=0;i<items.length;i++) {
if(items[i].id == id)
{
im[0].image= items[i].image;
ctr=100;
break;
}
}
uid = (uid+1);
contact.id = uid;
items.push(contact);
if (ctr==100 ) {
alert("in save putting the image");
items[contact.id].image = im[0].image; //doubt
alert("finished putting image");
}
}
//simply search items list for given id
//and returns the object if found
this.getid = function (name) {
for (i=0;i<items.length;i++) {
if (items[i].names == name) {
return (i+1);
}
}
}
//simply returns the items list
this.list = function () {
return items;
}
});
The problem I am facing is this: Everything works, except one thing. In ContactService, push() function, the line I have commented as //doubt is not getting executed.
The alert before it "in save putting the image" runs, but the alert "finished putting image" doesn't. What is the mistake there??
The problem here is that you're using the id's, which start at 1, to navigate in an array whose indexes start at 0.
To access the most recently pushed element, you should rather do :
items[contact.id - 1].image = im[0].image;
But you actually don't need to access the array : items[contact.id - 1] will return the object that you just pushed, and which is already referenced by variable contact, so you could just do :
contact.image = im[0].image;
I have the following html:
<div ng-show=showMarketingNav>
...
</div>
<div ng-show=showProductsNav>
...
</div>
<div ng-show=showSettingsNav>
...
</div>
What I want to do is to easily be able to hide all but one of the divs from another controller. I thought I could be clever and do the following:
var subNavMenuDisplays = {
Marketing: $scope.showMarketingNav,
Products: $scope.showProductsNav,
Settings: $scope.showSettingsNav
}
$rootScope.hideContextMenu = function () {
for (var category in subNavMenuDisplays) {
subNavMenuDisplays[category] = false;
}
}
$rootScope.setContextMenu = function (name) {
$rootScope.hideContextMenu();
subNavMenuDisplays[name] = true;
}
but this obviously does not work as $scope.showMarketingNav etc. will be passed as value, not reference.
The following works, but is not exactly nice to work with:
$rootScope.hideContextMenu = function () {
$scope.showMarketingNav = false;
$scope.showProductsNav = false;
$scope.showSettingsNav = false;
}
$rootScope.setContextMenu = function (name) {
$rootScope.hideContextMenu();
if (name == "Marketing") {
$scope.showMarketingNav = true;
}
if (name == "Products") {
$scope.showProductsNav = true;
}
if (name == "Settings") {
$scope.showSettingsNav = true;
}
}
Is there a way to grab $scope.showMarketingNav by reference, or another clever way around this?
I'd prefer not using eval to concatenate variable names.
You can place an object on the $scope and then toggle it dynamically:
$scope.show = {};
$rootScope.setContextMenu = function (name) {
$scope.show = {};
$scope.show[name] = true;
}
And the Html:
<div ng-show="show.Marketing">
...
</div>
<div ng-show="show.Products">
...
</div>
<div ng-show="show.Settings">
...
</div>
Here's a plunker demonstrating the change.
You can assign simple updater functions in that object:
Marketing: function(val) { $scope.showMarketingNav = val },
Products: function(val) { $scope.showProductsNav = val},
Settings: function(val) { $scope.showSettingsNav = val}
Then call it:
subNavMenuDisplays[name](true);
I have created an object where i need to assign some variables(parameters) and when the object is called, the variables(parameters) change. Here is my code:
var Modal = {
init: function () {
contact1: "";
contact2: "";
aboutus1: "";
aboutus2: "";
privacy1: "";
privacy2: "";
terms1: "";
terms2: "";
$(".modaltrigger").removeAttr("target");
$(".modaltrigger").click(function () {
if ($(this).is("#contact")) {
$('#primary_url').attr('href', contact1);
$('#secondary_url').attr('href', contact2);
} else if ($(this).is("#aboutus")) {
$('#primary_url').attr('href', aboutus1);
$('#secondary_url').attr('href', aboutus2);
} else if ($(this).is("#termsconditions")) {
$('#primary_url').attr('href', terms1);
$('#secondary_url').attr('href', terms2);
} else if ($(this).is("#privacy")) {
$('#primary_url').attr('href', privacy1);
$('#secondary_url').attr('href', privacy2);
}
});
}
};
I am trying to initialize the object above, and it does not work:
Modal.init(
contact1: "http:www.test1.com";
contact2: "http:www.test2.com";
aboutus1: "http:www.test3.com";
aboutus2: "http:www.test4.com";
privacy1: "http:www.test5.com";
privacy2: "http:www.test6.com";
terms1: "http:www.test7.com";
terms2: "http:www.test8.com"
);
it is Done like this way,
i Guess this is what you want to do.
var Modal = {
init: function (args) {
//then access your values like this
contact1= args.contact1;
contact2 = args.contact2;
..........
.........
.........
}
}
And to initiate this method you have write as
Modal.init({
contact1:"contact str",
contact2:"contact str",
.....
.....
lastitem : "last str"
});