Dynamically generated object not working as parameter to .css() - javascript

I have this function:
function myfunc(obj, properties, value) {
$.each(properties, function(i, key) {
var a = '-webkit-border-' + key + '-radius';
var b = '-moz-border-radius-' + key.replace(/\-/g, '');
var c = 'border-' + key + '-radius';
var z = value+'px';
obj.css({a : z, b: z, c: z});
});
}
Called like this:
myfunc($tab, ['top-left', 'top-right'], defaults.tabRounded);
Note that if I replace the obj.css line with:
obj.css({'border-top-right-radius': value+'px'});
It works as intended. Yet the values of a, b, c are completely correct.
What is going on?

The keys of an object literal in JavaScript are strings, not variables. If you do not quote them yourself, they are auto-quoted. So if you write
var a = {b: 1};
it's the same as if you had written
var a = {'b': 1};
You have to use [] to set keys dynamically.
var a = {};
a[b] = 1;
In this case modify your function to
function myfunc(obj, properties, value) {
$.each(properties, function(i, key) {
var a = '-webkit-border-' + key + '-radius';
var b = '-moz-border-radius-' + key.replace(/\-/g, '');
var c = 'border-' + key + '-radius';
var z = value+'px';
var css = {};
css[a] = css[b] = css[c] = z;
obj.css(css);
});
}

Related

How to flatten an array in Photoshop?

Here is my code :
var doc = app.activeDocument;
var allLayers = new Array;
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
collectAllLayers(theLayer, allLayers);
}
}
return allLayers;
}
alert("array_layers : " + allLayers);
I am getting in alert array like this
[Layer1],[Layer2],[Layer3];
and I want make it looks like this :
[Layer1,Layer2,Layer3];
Thanks for answers and help in advance!
The code in question already works correctly. Referring to the documentation on ArtLayer, you can prove this by printing some of the properties for each of the objects in the array:
function collectAllLayers (layerSet, layers){
for (var i = 0; i < layerSet.layers.length; i++){
var layer = layerSet.layers[i];
if (layer.typename === "ArtLayer"){
layers.push(layer);
} else {
collectAllLayers(layer, layers);
}
}
return layers;
}
function printable (artLayers) {
var layerDescriptions = [];
for (var i = 0; i < artLayers.length; i++) {
var layer = artLayers[i];
layerDescriptions.push(
'{ name: ' + layer.name +
', kind: ' + layer.kind +
', opacity: ' + layer.opacity +
', visible: ' + layer.visible +
' }'
);
}
return layerDescriptions;
}
var artLayers = collectAllLayers(app.activeDocument, []);
var layerDescriptions = printable(artLayers);
alert(layerDescriptions);
Code in the question do display single level array of ArtLayer objects. One can be confused, because toString method of ArtLayer object returns name of the layer in square brackets (in version of PS that I have installed (v19.1.5), "ArtLayer" string is displayed before layer name, but still inside square brackets). For example:
var doc = app.activeDocument;
alert(doc.layers[0]); // Alerts "[ArtLayer Layer 1]"
To flatten array ary you can use [].concat.apply([], ary), like in:
var ary = [1, ["A", "B", "C"], 3];
alert(ary[2]); // Alerts "3"
alert([].concat.apply([],ary)[2]); // Alerts "B"
How about using the allLayers.push(theLayer[0]); instead of allLayers.push(theLayer);.
Have you tried to flat the list in the recursive result?
var doc = app.activeDocument;
var allLayers = new Array;
var allLayers = collectAllLayers(doc, allLayers);
function collectAllLayers (doc, allLayers){
for (var m = 0; m < doc.layers.length; m++){
var theLayer = doc.layers[m];
if (theLayer.typename === "ArtLayer"){
allLayers.push(theLayer);
}else{
flatten(collectAllLayers(theLayer, allLayers));
}
}
return flatten(allLayers);
}
function flatten(arr) {return arr.reduce(
(a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
)};
alert("array_layers : " + allLayers);
you can use
const flatten = (layers, allLayers) => layers.reduce((acc,layer) => (Array.isArray(layer)) ? collectAllLayers(layer, acc) : acc.push(layer), allLayers);
const collectAllLayers = (doc, allLayers) => flatten(doc.layers, allLayers);

Convert string to object in NodeJS

I have a string in this format:
var x = "a=1; b=2; c=3; d=4"
and I would like to convert it to an object like this:
var y = {
a: "1",
b: "2",
c: "3",
d: "4"
}
Any ideas how to achieve that?
This works in iE9+
var x = "a=1; b=2; c=3; d=4",
y = {};
x.split(';').map(function (i) {
return i.split('=')
}).forEach(function (j) {
y[j[0].trim()] = j[1]
});
If you are using Node.js v4+
let x = "a=1; b=2; c=3; d=4",
y = {}
x.split(';').map(i => i.split('=')).forEach(j => y[j[0].trim()] = j[1])
You could try this (not bullet proof, refer to comments):
var json, str;
str = 'a=1; b=2; c=3; d=4';
str = str.replace(/\s*;\s*/g, ',');
str = str.replace(/([^,]+)=([^,]+)/g, '"$1":"$2"');
str = '{' + str + '}';
json = JSON.parse(str);
document.write(
'<pre>' + JSON.stringify(json) + '</pre>'
);
here is what i did and it seems to work fine:
var y = x.split(";");
var obj = {};
for(var i = 0; i < y.length ; i++){
var k = y[i].split("=");
var r = k[0].replace(" ", "");
obj[r] = k[1];
}
console.log(obj);

How to merge these complex JavaScript array objects?

Can someone help me to do these example?
var a = ["17","18"];
var b = ["1","1","1"];
I need an output below:
var c = [17:111,18:111]
var a = ["17","18"];
var b = ["1","1","1"];
var i=0;
var ConcateC="";
for(i=0;i< b.length;i++)
{
ConcateC +=b[i];
}
var c=[];
for(i=0;i< a.length;i++)
{
c[i]=a[i] + ":" + ConcateC;
alert(c[i]);
}
You can join the values of b together, then use map to create a new array from the indices of a:
var a = ["17","18"];
var b = ["1","1","1"];
var bValue = b.join("");
var c = a.map(function(currentValue) {
return currentValue + ":" + bValue;
});
console.log(c); // ["17:111","18:111"]

Get element on any level of an object in Javasscript

Given the following:
var a = JSON.parse('{"fst":"data1","snd":{"ind2":"data2"}}');
var index = "fst";
var res = a[index]; //res = data1
var index2 = "????";
var res2 = a[index2]; //res = data2
what should I put on index2 so res2 equals data2?
I'm looking for a generic syntax that would let me grab an element at ANY level of the parsed json, just by modifying the index string.
(I'm looping through a list of elements from different places/levels of a json derived object to build a table)
Any help would be much appreciated
You need a function for that
function deepAccess( obj, str ) {
var parts = str.split("."),
cur = obj;
for( var i = 0; i < parts.length; ++i ) {
cur = cur[parts[i]];
}
return cur;
}
var index = "fst";
deepAccess( a, index ); //"data1"
index = "snd.ind2";
deepAccess( a, index ); //"data2"
You're accessing a property of a property, and the syntax reflects this:
var res = a['snd']['ind2'];
There is no way to directly grab the "nested" property directly. If you're allowed to change the original object, you could add shortcut accessors for each object:
//Credit goes to Esailja for the original
function deepAccess(obj) {
function nestedAccess(o, level) {
if (typeof o == "object") {
var level = level || "";
for (p in o) {
if (o.hasOwnProperty(p)) {
if (level && typeof(o[p]) != "object") {
obj[level + "." + p] = o[p];
}
nestedAccess(o[p], (level ? level + "." : "") + p);
}
}
}
}
nestedAccess(obj);
}
deepAccess(a);
a["snd.ind2"];
var someObject1 = {};
var someObject2 = {e01: '*', e02: {e03: '*', e04: '*'}, e05: '*'};
var someObject3 = {e01: {e02: {e03: '*'}}};
function setValueByPath(obj, path, value) {
var pathArray = path.split('.');
function goDownstears(o, chunk, val) {
var prop = chunk.shift();
if(!o.hasOwnProperty(prop)) o[prop] = {};
o[prop] = (chunk.length > 0) ? goDownstears(o[prop], chunk, val) : val;
return o;
}
obj = goDownstears(obj, pathArray, value);
}
setValueByPath(someObject1, 'e01.e02.e03', 'changed');
setValueByPath(someObject2, 'e02.e04', 'changed');
setValueByPath(someObject3, 'e01.e02.e03', 'changed');
setValueByPath(someObject3, 'e01.e02.e04', 'changed');
setValueByPath(someObject3, 'e02.e01.e01', 'changed');
console.log(someObject1);
console.log(someObject2);
console.log(someObject3);
My question was closed here set an object property with sugar like obj['level1.level2.leve3'] = value
See here http://jsfiddle.net/zafod/RDGwY
This issue is for setting a value, but you can just return an asked property througth iterations

How to make a variable addressable by name as string in JavaScript?

Is there a way to convert variable names to strings in javascript? To be more specific:
var a = 1, b = 2, c = 'hello';
var array = [a, b, c];
Now at some point as I go through the array, I need to get variable names (instead of their values) as strings - that would be 'a' or 'b' or 'c'. And I really need it to be a string so it is writeable. How can I do that?
Use a Javascript object literal:
var obj = {
a: 1,
b: 2,
c: 'hello'
};
You can then traverse it like this:
for (var key in obj){
console.log(key, obj[key]);
}
And access properties on the object like this:
console.log(obj.a, obj.c);
What you could do is something like:
var hash = {};
hash.a = 1;
hash.b = 2;
hash.c = 'hello';
for(key in hash) {
// key would be 'a' and hash[key] would be 1, and so on.
}
Goint off of Triptych's stuff (Which Thanks)...
(function(){
(createSingleton = function(name){ // global
this[name] = (function(params){
for(var i in params){
this[i] = params[i];
console.log('params[i]: ' + i + ' = ' + params[i]);
}
return this;
})({key: 'val', name: 'param'});
})('singleton');
console.log(singleton.key);
})();
Just thought this was a nice little autonomous pattern...hope it helps! Thanks Triptych!

Categories