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;
Related
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
I have a dictionary as as shown below. I am trying to add dict values into them. This is what it stars with
var animals = {
flying : {},
underground : {},
aquatic : {},
desert : {}
};
For example: If I wanted to add d = {dove : [<some list>] } into animal[flying], how would i do it? I cannot enter the values manually as thus i am running a loop, I am able to write it manually, but not with program.
I have tried animals[flying] = d, this would work for the first time, but when i try to add another value it would be replaced and not appended.
In the end I am looking for something like this: This is what it ends with
var animals = {
flying : {
dove : [<list>],
sparrow : [<list>],
},
underground : {
rabbits : [<list>],
squirrel : [Squirrel],
},
aquatic : {
dolphin : [<list>],
whale : [Squirrel],
},
desert : {
camel : [<list>],
antelope : [<list>],
},
};
well because
myDict[subcat] = x
assigns it. You're working with lists. Think about it - when have you ever added an item to a list this way? Of course that overwrites your previous entry. What you want instead is to push the variable into the array (also, this isn't python. Lists are called Arrays and Dictionaries are called Objects. There is a distinction, but that's beyond the scope of an answer here. Google it).
So do this:
myDict = {
subCat: [],
}
And then when you loop:
myDict[subCat].push(x)
I think what you want to do is:
animals["flying"] = Object.assign(animals["flying"], d);
E.g.
animals = {
flying: {}
}
d = { dove: [1, 2, 3] }
Object.assign(animals["flying"], d);
d = { sparrow: [1, 2, 3] }
Object.assign(animals["flying"], d);
console.log(animals); //{"flying":{"dove":[1,2,3],"sparrow":[1,2,3]}}
var newAnimal = {name: 'bird'};
if(animals['flying']['dove'] && animals['flying']['dove'].length > 0) {
//List already exists so add the new animal
//TODO also check if the animal is already in the list?
animals['flying']['dove'].push(newAnimal);
}else {
//Create the new list
animals['flying']['dove'] = [newAnimal];
}
I'm trying to make a Pixel RPG game, and am a bit confused.
What I'm trying to do:
var character = {
gender: male,
age: 18,
action: walking,
direction: left,
skin: 0,
eyes: aqua,
hairStyle: 0,
hairColor: blue,
hat: 'cap'
};
ctx.drawImage(characterIMG.body[character.gender][character.skinColor], 0, 0);
ctx.drawImage(characterIMG.eyes[character.gender][character, 0, 0);
ctx.drawImage(characterIMG.hair[style0], 0, 0);
if(character.hat != "none"){
ctx.drawImage(characterIMG.hat['cap'], 0, 0);
}
How would I go about defining the images?
So far got here, but am mixed up..
var characterIMG = [male, female]; //I want some separate variables to just write in, in case I need to add more images of the same type, then I can just write the "type" in the variable instead of changing a bunch of stuff :)
for(var i in characterIMG){
characterIMG[i] = {
skin: [],
eyes: [],
hair: [],
accessories: []
}
}
Unless there is a more efficient way to do this?
Thanks!
--In short, I want to do this:
ctx.drawImage(characterIMG.body[character.gender][character.skinColor], 0, 0);
ctx.drawImage(characterIMG.eyes[character.gender][character], 0, 0);
ctx.drawImage(characterIMG.hair[style0], 0, 0);
..with characterIMG containing a huge database of all the relevant images (this)
Use an object and then just new up the object whenever you want to create a new instance of a character. With this, each character can inherit their properties from the main Object (via prototype) and become a separate entity within your game.
var Person = function(payload) {
this.name = payload.name;
this.age = payload.age;
this.gender = payload.gender;
};
Person.prototype.talk = function() {
return console.log('hello, I am ' + this.name);
}
var Person1 = new Person({
name : 'Amanda',
age : 18,
gender : 'Female',
});
var Person2 = new Person({
name : 'Sam',
age : 21,
gender : 'Make',
});
Person1.talk();
Person2.talk();
You can load a set of images as follows
// a list of image name comma delimited
const imageURLs = "image1.jpg,image2.jpg,image3.jpg";
// create an array of images
const myImageList = imageURLs.split(",").map(url => {
const image = new Image;
image.src = url;
return image;
});
If you have many images with different categories and subcategories then it will depend on how you organise the images on your file system. If you have one directory and all the images in that then each image's name should have some description of the image
body_dark_female.jpg
body_light_female.jpg
body_dark_male.jpg
body_light_male.jpg
head_dark_female.jpg
head_light_female.jpg
head_dark_male.jpg
head_light_male.jpg
And so on, or a better option is to set the various categories in directories
body/dark/female/jill.jpg
body/dark/male/tom.jpg
body/light/female/jill.jpg
body/light/male/tom.jpg
head/light/female/jill.jpg
head/light/male/tom.jpg
head/dark/female/jill.jpg
head/dark/male/tom.jpg
You can then use the name or directories to create the data structure
// using the directory structure
function loadImage(imageURL,images){
const cats = imageURL.split("/"); // split the cats into an array
// remove the last item as that is the image name
var name = cats.pop();
// remove the extension and add just the image name to the cats
cats.push(name.split(".")[0]);
// reference the base category
var currentCat = images;
cats.forEach(cat => { // for each category create the objects
if(currentCat[cat] === undefined){ // does this cat exist?
currentCat[cat] = {}; // no them create an object for it
}
currentCat = currentCat[cat]; // reference the category
});
// now create the image and add it to the object
currentCat = new Image;
currentCat.src = imageURL;
}
Then use the directory listing to create the list of images to load
const imageURLs = `
body/dark/female/jill.jpg
body/dark/male/tom.jpg
body/light/female/jill.jpg
body/light/male/tom.jpg
head/light/female/jill.jpg
head/light/male/tom.jpg
head/dark/female/jill.jpg
head/dark/male/tom.jpg
`;
Because the directory listing may be a bit unclean (spaces, tabs, linefeeds, etc) you should ensure each image name is valid
// remove tabs, groups of spaces and returns, and use linefeed to seperate them
const imagesURLClean = imageURLs.replace(/\t|\r| +?/g,"").split("\n");
// create the base category
const characterIMG = {};
// add the images
imagesURLClean.forEach(imageURL => loadImage(imageURL,characterIMG));
When that has run you can access the image as follows
ctx.drawImage(characterIMG.body.light.female.jill,0,0);
Or via strings
var part = "body";
var skin = "light";
var gender = "female";
var name = "jill";
ctx.drawImage(characterIMG[part][skin][gender][name],0,0);
The directory listing will create the following data structure
characterIMG = {
body : {
dark : {
female : {
jill : // the image
},
male : {
tom : // the image
},
},
light : {
female : {
jill : // the image
},
male : {
tom : // the image
},
}
},
head : {
dark : {
female : {
jill : // the image
},
male : {
tom : // the image
},
},
light : {
female : {
jill : // the image
},
male : {
tom : // the image
},
}
}
If your list is very long it may have missing items, during development it would pay to add a default category that will return an image appropriate for that category.
Thus you directory listing would look like
body/default.jpg // default
body/light/default.jpg // default
body/light/female/default.jpg // default
body/light/male/default.jpg // default
body/dark/default.jpg // default
body/dark/female/default.jpg // default
body/dark/female/jill.jpg
body/dark/male/default.jpg // default
body/dark/male/tom.jpg
// and so on
Then create a function that gets a image via category and if it has problems it will use the default image as far as it can find to fit the categories
function getImage(images, ...categories){
const count = 0;
var image = images
while(count < categories.length){
if(image[categories[count]] !== undefined){
image = image[categories[count++]];
}else{
return image.default;
}
}
return image;
}
Then you can draw an image as follows
ctx.drawImage(getImage(characterIMG,"body","dark","female","jill"),0,0);
// when you get the wrong referance
ctx.drawImage(getImage(characterIMG,"leg","dark","female","jill"),0,0);
// it will return characterIMG.default
// or
ctx.drawImage(getImage(characterIMG,"body","dark","female","bill"),0,0);
// as there is no female bill, it will return characterIMG.body.dark.female.default
This is how you define an array inside an object.
var characterIMG = {
male: {
skins: [],
hair: ["black", "brown"]
},
female: {
skins: [],
hair: []
}
};
console.log(characterIMG);
console.log(characterIMG["male"]["hair"]);
console.log(characterIMG.male.hair); //does the same
I have an array called category.
var category = ["automobile","Fashion","Music Instruments"]
and I need to link this array with the below array according to product.
var products = ["LandRover","Guitar","vintage,"Drums","Maserati","Piano"]
I think you are talking about some stuff like this?...
//variables predefined
var category = ["Automobile","Fashion","Music Instruments"]
var products = ["LandRover","Guitar","vintage","Drums","Maserati","Piano"]
//create a object categories where later we will add our products!
var categories = { };
//add values(category & products)
categories[ category[0] ] = [ products[0] , products[4] ]; //Automobile
categories[ category[1] ] = [ products[2] ]; //Fashion
categories[ category[2] ] = [ products[1] , products[3] ,products[5] ]; //Music Instrument
So now if you wanna display some value of 'automobile' for example, just:
//METHOD1
categories['automobile']
//METHOD2
categories[ category[0] ] //category[0]->automobile
And what you get is the array with all the products of category,so you just have to choose wich one you want.
Here you can see what you have got in console.
Function for show it in some HTML ( void html i hope)
function showObjectOnHTML( obj ){
for (var key in categories) { //check categories of thethe object
if (categories.hasOwnProperty(key)) {
var CATEGORIES = key;
var SPAN = document.createElement('SPAN');
SPAN.setAttribute('style','font-weight:bold; font-size: 20px; margin-left: 5px; display:block;');
SPAN.appendChild( document.createTextNode( CATEGORIES ) );
document.body.appendChild(SPAN);
var PRODUCTS = categories[key];
for( var i=0; i<PRODUCTS.length; i++){
var SPAN = document.createElement('SPAN');
SPAN.setAttribute('style','margin-left: 15px;font-size: 20px; display:block;');
SPAN.appendChild( document.createTextNode( PRODUCTS[i] ) );
document.body.appendChild(SPAN);
}
}
}
}
For show it,just type,:
showObjectOnHTML(categories);
I think what you need is an object (used like a "hashmap" in java):
//set examples
var category = {
automobile: [],
fashion: [],
musicInstuments: ["Piano"]
};
category["automobile"] = category["automobile"].concat(["LandRover", "Maserati"]);
category.fashion.push("Vintage");
//get examples
for(var key in category){
category[key].forEach(function(item){
console.log(item);
});
}
console.log(category.automobile[0]);
Using an object will also give you constant access time to the category you are looking for (instead of iterating over n items to find it)
Maybe if you use objects instead of only lists?
var categories = [
{
name: "Automobile",
products: ["LandRover", "Maserati"]
},
{
name: "Fashion",
products: ["Vintage"]
},
{
name: "Music Instruments",
products: ["Guitar", "Drums", "Piano"]
}
]
Also, like someone commented, what exactly do you want to accomplish?
EDIT
This JSFiddle shows one way to list products in each category using AngularJS.
Straight to the point, I created a form letting user to insert 2 items (Option Name, Option Value)
The inserting number is dynamic such as:
**Option Name** **Option Value**
Color Red
Blue
Yellow
Size L
M
and I need to populate a table of the possibilities given by user like below:
**Color** **Size**
Red L
Red M
Blue L
Blue M ....etc
how can I write a javascript logic to do that? the worst problem is what if the user input 3 or 4 option name like adding material:cotton, chiffon sex: male, female?
It seems to be impossible or lots and lots of loop? I had been doing this for 2 weeks plus. Can anyone guide me through an easier way? I am almost stunned by this.
If you use a recursive function, you only need one loop and one if-else statement, no matter how many options there are:
var options = [{
name: "Color",
values: ["Red", "Blue"]
}, {
name: "Size",
values: ["M", "L"]
}, {
name: "Sex",
values: ["Male", "Female"]
}];
function list(options, result) {
if (options.length > 0) {
var option = options[0];
var remaining = options.slice(1);
for (var i = 0; i < option.values.length; i++) {
var current = result.slice(0);
current.push(option.values[i]);
list(remaining, current);
}
} else {
document.body.innerHTML += result.join(", ");
document.body.innerHTML += "<br/>";
}
}
list(options, []);
Fiddle available here.