javascript array with keys containing another array of objects using php - javascript

I am working on an e-commerce project. the user can select multiple colors and can enter the quantity for each size of that color differently. I want to store that data into an array and then send it to the server using ajax
the array should look like this
[ {
'color' : [ {
'INDIGO' : [
{ 'S' : 15},
{ 'M' : 15},
] },{
'PURPLE' : [
{ 'S' : 15},
{ 'M' : 15},
]},
]}
]
but I am getting this type of array. it is inserting the last quantity I have inserted replaces the old one like if on purple color if I put 15 for s and 15 for m it only takes m
INDIGO: {L: 15}
PURPLE: {M: 15}
here is my code sample
when the user selects color radio it pushes the value into the color array
var key = 'INDIGO';
color[key] = {};
and when the user increases quantity it inserts the object for the color key
var len = $('.radioCheckbox:checked');
for (var i = 0; i < len.length; i++) {
var key = len[i].value;
color[key] = {
[$size] : val,
};
}

It look like when you are putting the 15 for s and 15 for m you color is not rightly set for each size. So check when you are pushing m or s the color is set correctly. Alternately, Not sure why do you need complex data structure. I think it can be achievable using data structure which is easy handle like
data = {
'color': {
'INDIGO': {
'S': 15,
'M': 15
},
'PURPLE': {
'S': 15,
'M': 15
}
}
}
you can manage color, size and its values like,
data['color'][key][$size] = val

Related

How to restrict HTML column elements based on maximum value of field in array of objects

I have a pug template that receives an array of objects from Node/mongo/express. Based on the maximum value of one the fields (not length), I need to restrict some columns in an html table.
For example, the objects rendered from node might look like this
{
quantity: 4,
years: 6
},
{
quantity: 78,
years: 2
}
I would then need to restrict the number of 'year' columns in my table to be 6. I'm not sure what the best way is to do this, whether to render an additional 'max' variable in node, whether I can do this in pug, or if I should use some client-side js. In (very) pseudo-code, I want something like this...
forEach(Math.max(project.output.years)){
...create an html table 'year' column
}
I'm not sure if pug is the right tool for doing this kind of data manipulation.
From the nodejs side, you could use a reducer to find the maximum years value and send it down with the rest of your data.
const data = [{
quantity: 4,
years: 6,
},
{
quantity: 78,
years: 2,
},
]
const maxYears = data.reduce((acc, current) => current.years >= acc ? current.years + acc : acc, 0)
console.log(maxYears) // 6
Or make the reducer a bit more flexible in terms of which field it accesses to make a comparison.
const data = [{
quantity: 4,
years: 6,
},
{
quantity: 78,
years: 2,
},
]
const findMaxVal = (property, data) =>
data.reduce(
(accumulator, current) =>
current[property] > accumulator ? current[property] : accumulator,
0
)
console.log(findMaxVal("years", data)) // 6
There are a number of ways to find the max, but the easiest is:
var maxYears = 0;
for(var i = 0 ; i < data.length ; i++){
if( data[i].years > maxYears ){
maxYears = data[i].years;
}
}
(I'm assuming that the array you have all those objects in is called data)
Then you can pass maxYears into the pug template and do this:
table
tr
- var col = 0;
while col < maxYears
td(colIndex= col++)
This will produce a table that looks like this for maxYears = 3:
<table>
<tr>
<td colIndex='0'></td>
<td colIndex='1'></td>
<td colIndex='2'></td>
</tr>
</table>
Just repeat that loop for every row.

how to increase custom count in jquery json

If laptop model and serial id are same, i've to add new field totalModel and increase count. For example in below case: serialid "1" and laptop model "xyz" are coming two time so i want to add "totalModel" count as 2 and so on. How can i achieve this in jquery
This question is not really about jQuery, it is about mapping and filtering arrays and objects. However, we can use some jQuery convenience methods to solve it.
A large part of solving these problems is by properly defining what you want to do. It sounds from your question that you want to get a map of unique serial ids per laptop model type. We can use JavaScript's Array.prototype.reduce to produce just such a map (Note that we will take the 'sold' value for the first of each laptop model we encounter):
var laptop_models = data.reduce(function (memo, obj) {
if (!memo[obj.laptopModel]) {
memo[obj.laptopModel] = {
unique_serial_ids: [],
sold: obj.sold
};
}
if ($.inArray(obj.serialid, memo[obj.laptopModel].unique_serial_ids) === -1) {
memo[obj.laptopModel].unique_serial_ids.push(obj.serialid);
}
return memo;
}, {});
Next, we can map our laptop_models object into the array you specified as your expected result:
var result = $.map(laptop_models, function (laptop_model, model_name) {
return {
laptopModel: model_name,
totalModel: laptop_model.unique_serial_ids.length,
sold: laptop_model.sold
};
});
You got the idea already. Iterate through the array.
if them item is in a hash, increment the count, otherwise, add to the hash and set the count to 1
var hash = {};
for (var i = 0;i<data.length;i++) {
if (hash[data[i].laptopModel) {
hash[data[i].laptopModel]++;
}
else
hash[data[i].laptopModel] = 1;
}
var data = [
{
"serialid": 1,
"laptopModel": "xyz",
"sold": "yes",
"cnt": 5
},
{
"serialid" :1,
"laptopModel": "xyz",
"sold": "yes",
"cnt": 4
},
{
"serialid": 1,
"laptopModel": "abc",
"sold": "yes",
"cnt": 3
},
{
"serialid": 3,
"laptopModel": "xyz",
"sold": "yes",
"cnt": 2
}];
var result = []; //work if result = {};
var tempArray = []; // used to store unique name to prevent complex loop
data.forEach(function(item){
if($.inArray(item.laptopModel, tempArray)< 0){// unique name
result.push(formatData(item));
tempArray.push(item.laptopModel);
}
else{
var indexNew = $.inArray(item.laptopModel, tempArray);
result[indexNew]["totalModel"] += 1;
}
});
function formatData(item){
return{
"laptopModel": item.laptopModel,
"sold": item.sold,
"totalModel": 1
}
}
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

remove and replace item from object in array javascript

I have read and tried all of the posts of SO on this subject, but for some reason none of the answers are providing the desired effect.
I have written a shopping basket program and once the user clicks the'Buy now' button I wish to make POST request containing an object with the users order.
Problem
The user has the option to purchase three different items. Each time the user clicks on an item, which is a html input box, to increase the amount they wish to purchase I want to update the object to only contain the latest amount chosen.
In its simplest format the basket, when initiated, looks like this :
var basket = {items:[
{item:"Trousers", quantity:1, cost:"10"},
{item:"Trainers", quantity:1, cost:"5"},
{item:"Jacket", quantity:1, cost:"30"}
]}
Each time the user clicks the input button I wish for the basket to be updated so if the user clicked to increase the jacket to a quantity of 3, and the trousers to 4 I want the object to look like this:
var basket = {items:[
{item:"Trousers", quantity:4, cost:"40"},
{item:"Trainers", quantity:1, cost:"5"},
{item:"Jacket", quantity:3, cost:"90"}
]}
Then if a user decides to reduce the number of trousers by 1, to 3, I would want the basket.items object to look like this:
var basket = {items:[
{item:"Trousers", quantity:3, cost:"30"},
{item:"Trainers", quantity:1, cost:"5"},
{item:"Jacket", quantity:3, cost:"90"}
]}
I have written the code for all the calculations etc. so this is not the issue but the issue is to update basket.items to only contain the three items listed above at once, with the latest data.
I cannot use the filter method as this needs to work in older versions of IE. I have tried all solutions listed in this and this along with many more but none of these answers are providing the solution I am looking for.
Let me know if any further information is required.
try this:
var basket = {
items: [
{
item: "Trousers",
quantity: 1,
cost: "10"
}, {
item: "Trainers",
quantity: 1,
cost: "5"
}, {
item: "Jacket",
quantity: 1,
cost: "30"
}]
};
function updateBasket(item) {
basket.items = basket.items.map(function (product) {
if (product.item == item.item) return item;
else return product;
});
}
updateBasket({
item: "Jacket",
quantity: 9,
cost: "30"
});
updateBasket({
item: "Trainers",
quantity: 9,
cost: "30"
});
console.log(basket)
Don't know if for you having an array of objects is mandatory if that's not the case you can structure your data differently, for instance
basket = { items : { item_1 : { quantity: 1, cost: 1 } } }
so updating the basket it will be simply
function updateBasket(item, value) {
// item -> item_1
// value - > { quantity: 2, cost: 2}
basket['items'][item] = value;
}
To be honest, I think the problem could be solved if you kept your data in a little different way. For example, something like this
var products = {
trousers:0,
jackets:0,
trainers:0,
};
var prices = {
trainers:5,
jackets: 30,
trousers: 10
}
//to increase the amount of products after user event
products.jackets +=2;
products.trainers +=3;
products.trousers +=1;
//finally generate your desired format
var basket = {items:[]};
for(product in products){
basket.items.push({
item: product,
quantity: products[product],
cost: products[product]*prices[product]
});
}
console.log(basket);
You can see that basket is now in your desired format :)
Cost should be a number and not string.
If you are not keeping a global object for what is the price of 1 item then once you have updated your basket object you will loose the information on price of 1 item and you wouldn't know how much to increase the price.
Considering same, below would be my recommendation of changes:
var basket = {items:[
{item:"Trousers", quantity:4, itemCost:40, totalCost:40},
{item:"Trainers", quantity:1, itemCost:5, totalCost:5},
{item:"Jacket", quantity:3, itemCost:90, totalCost:90},
]}
function updateQuantity(itemName, qIncreaseBy, qDecreaseBy){
console.log(basket);
for(var propt in basket.items){
if(basket.items[propt].item == itemName){
if(qIncreaseBy != 0){
basket.items[propt].quantity = (basket.items[propt].quantity + 1);
basket.items[propt].totalCost = (basket.items[propt].totalCost + basket.items[propt].itemCost);
} else{
basket.items[propt].quantity = (basket.items[propt].quantity - 1);
basket.items[propt].totalCost = (basket.items[propt].totalCost - basket.items[propt].itemCost);
}
break;
}
}
console.log(basket);
}
Usage:
updateQuantity("Trainers", 0, 1); //To add item
updateQuantity("Trainers", 1, 0) //To remove item

Javascript Object: Basic Knowledge Gap

trying to create a set of of html form option/select fields that are driven by a google spreadsheet, to steer users to specific choices. think a hat that is available in red, blue or black, a tshirt that is available in blue, green or red. the source data has the same value in col 1 for many rows, and unique values in col 2. the colors are specific to each product. (the spreadsheet structure can not be changed.)
i'm trying to group the rows by product, so i can populate a product dropdown, then a colors dropdown that is keyed to that product. that's where i'm stuck.
i have the data loading ok and can do the form displays stuff, just need some insight into how to end how to structure an array like this:
var productsAndColors = [];
productsAndColors[0] = new Array("hat", ["pink", "red", "blue"]);
just quoting the iffy bit here:
for (i = 0; i < json.feed.entry.length; i++) {
var entry = json.feed.entry[i];
product = entry.gsx$product.$t;
productsAndColors[i] = ['', []];
if (productCheck != product) {
productsAndColors[i][0] = product;
thisShape = product;
}
color = entry.gsx$color.$t;
productsAndColors[i][1].push(color);
}
this creates an array per row, just can't seem to figure out a way to group the rows. i realize this is cavemanish.
thanks for your thoughts.
http://jsfiddle.net/hartogsmith/SqNNk/
https://docs.google.com/spreadsheet/ccc?key=0AkT3oKFSug31dGhva1lpWkhDOGxKaVJsNnpkZVpNbUE#gid=0
Why not something that's a little less strictly-typed?
If you're comfortable with setting/reading .value as a string, from the first dropdown (ie: "product"), then you could have an object as simple as:
var products = {
hat : {
colours : [ "red", "green", "blue", "black", "grey" ]
},
shirt : {
colours : [ "pink", "salmon", "mauve", "chartreuse" ]
}
};
It could be more simple:
var products = {
hat : [ "grey", "gray", "charcoal", "smoke" ],
shirt : [/*...*/]
};
So why add "colour" as a property to each?
Simply because it's an adjective for an object that you might want to add more adjectives to: .size : [], .shipping_options : [], .cut : [].
shirt : {
size : [],
logo : [],
cut : []
}
And you really don't want to end up in a:
products[0][1][1]
products[1][2][3]
world.
Try this:
var Products = {},
product_type,
current_value,
color_arr;
for (...) {
product_type = entry.gsx$product.$t;
current_value = entry.gsx$color.$t;
Products[product_type] = Products[product_type] || { colors : [] };
/* same as:
if (!Products.hat) { Products.hat = { colors : [] }; }
...basically, Products.hat == itself, else a new object
*/
color_arr = Products[product_type].colors;
color_arr.push(current_value);
}
Now, you can say Products.hat.colors[1]
And if you set your first dropdown up like this:
<select name="product">
<option value="hat" >Cap</option>
<option value="shirt">Tee</option>
</select>
Then:
var type = product_select.value,
avail_colours = Products[type].colors;

JavaScript Trivia: Function to combine two Array sets?

I have two Arrays of object, one has a set of options like this (the left side of the equation):
Id Value
1 Red
2 Blue
3 Green
and another like this (the right side):
Id Value
3 Green
And I need a "left join" (all left products and matching right) like this:
Id Value Selected
1 Red
2 Blue
3 Green X
I would like to create a method with this setup (I put [] to note arrays)
var DisplayArray[] = AllColorsArray[].join(SelectedColors[]);
Is there anything like these already or maybe a JQuery plug-in that does this? It has to be common to provide a selection list with the saved options already checked.
EDIT:
It's really looking for simple SQL like operations on Arrays of objects, but with JavaScript.
use jquery extend, arrays are objects in js:
var object1 = {
apple: 0,
banana: {weight: 52, price: 100},
cherry: 97
};
var object2 = {
banana: {price: 200},
durian: 100
};
$.extend(object1, object2);
In your case will be
var DisplayArray = $.extend(AllColorsArray ,SelectedColors);
You might be interested in LINQ to JavaScript for this sort of thing.
If you set up the arrays in such a way that the indexes are in the same position, you can use a two-dimensional array and then check to see if each dimension is equal. Something like this:
var ary = new Array();
ary[0] = new Array("Red","Blue","Green");
ary[1] = new Array(null, null, "Green");
for (var i in ary[0]) {
alert(ary[0][i] == ary[1][i]); //True if they match, false if not.
}
EDIT
You can manually loop through and check them. You could even throw this in a function where you have to pass the selected and all color arrays. See below for example:
var AllColorsArray = [{"id":1,"value":"Red"},{"id":2,"value":"Blue"},{"id":3,"value":"Green"}];
var SelectedColors = [{"id":3,"value":"Green"}];
for (var ind in AllColorsArray) {
for (var chkind in SelectedColors) {
if (SelectedColors[chkind].id == AllColorsArray[ind].id) {
AllColorsArray[ind] = $.extend(AllColorsArray[ind], SelectedColors[chkind]);
break;
}
}
}
//To test:
for (var i in AllColorsArray) {
alert(AllColorsArray[i].value + ': ' + AllColorsArray[i].selected);
}

Categories

Resources