Still learning Javascript by creating mini text RPG games via HTML pages :)
Good practice, trying to learn some new way or add some new better codes into my project.
Right now I'm trying to add language to my project via function;
language.addLang = function(name,id){
if (id != this.log[id]) {
this[name] = new Object;
this.log[id] = name
}
}
Edit;
Was trying to say if you can compare array index number to argument id number.
The name on the argument is just a language name, like English with a string value.
And id is just what array index it will be placed into. And also a conditional branch that will translate all text into that language for later use.
for people that wonder what log is;
language.log = [
undefined, 'English','Swedish','Japanese','German'
]
Summary;
As above, log array length is right now 5.
So let's say I want to add a new language to my project that I will translate, later on, I can then write language.addLang('Chinese',5).
That will add 'Chinese' string into array index number 5.
However! If I would add from a different index number that already exists it will show some error instead of overwriting 'Chinese' to another language.
I hope this explains better than my last post.
I can translate it manually instead of adding a new object for each language.
But would be life-saving if I can compare argument number to index number.
#Charliefl is right but I guess this may give you a clue to apply to your case by modifying according to your other code.
var IncludedLanguages = [ 3 , 4 , 5 ]
var LangObjectsArray = []
language.addLang = function(name,id){
if ( IncludedLanuages.includes( id ) != true ) {
var obj = { "name" : name , "id" : id }
LangObjectsArray.push( obj )
IncludedLanguages.push( id )
}
}
Related
I am using the demo here: http://www.mdelrosso.com/sheepit/index.php?lng=en_GB&sec=demo3
But if you have two of the outer forms (addresses) and two each for the inner forms (numbers) and inspect the elements you'll notice the names of the inputs still have the #index# and/or #index_phone# strings in the index names.
If you try to submit the form then, the field data is lost (since only the latest copy of that name is kept). I've tried debugging the JavaScript so I can patch it, but I'm not seeing where it's wrong. It seems like the normalizeForms function isn't handling nesting correctly.
What can I do to correct the code so the indexes perform as expected? (That is: so that an input of two addresses (A and B), each with two phone numbers (A1, A2 and B1, B2) gives me a POSTed value like:
"people" : [
0 : {
"addresses" : "A",
"phones" [ 0 : "A1", 1: "A2" ]
},
1 : {
"addresses" : "B",
"phones" [ 0 : "B1", 1: "B2" ]
}
]
(Note: I'm not looking for that exact format; I can parse any output, I just need to get all of the data from the client to the server with meaningful indexes and without conflicts.)
There appear to be some fundamental logic issues with the index 'normalization' side of this plugin when it comes to the nested inputs.
Essentially there is is a nametemplate and an idtemplate which are the element names only with %index% or %index_phones% where the index should be, and then the name and id which should be these templates only with the %index% or %index_phones% replaced with the actual element input ids.
What happens during the 'normalization' process is that a function runs over these templates (once per element per form), and depending on the form, replaces either %index% or %index_phones% with the relevant index, depending on which form is being processed.
The problem arises when the inputs are nested, as the function first replaces (for instance) %index% with let's say 0. It then updates the resulting name or id with this value, say person_addresses_0_phones_%index_phones%_phone. When it hits the nested form, it then does the same again, only with %index_phones%. The result is now person_addresses_%index%_phones_0_phone because it is still using the unmodified template attribute, rather than the already half-modified name.
To fix this properly, the logic around this whole section of the plugin really needs rebuilding, but I have slapped together a quick patch which should serve as a temporary fix.
In the main plugin file, update the normalizeFieldsForForm function to be:
function normalizeFieldsForForm(form, index)
{
form.find(formFields).each(function(){
var that = $(this)
,idTemplateAttr = getOrSetTemplate(that,"id")
,nameTemplateAttr = getOrSetTemplate(that, "name")
,idAttr = that.attr("id")
,nameAttr = that.attr("name")
,formParents = that.parents('[idtemplate]')
/* Normalize field name attributes */
var newNameAttr = nameTemplateAttr.replace(options.indexFormat, index);
/* Normalize field id attributes */
var newIdAttr = idTemplateAttr.replace(options.indexFormat, index);
$.each(formParents,function(index,element){
$element = $(element);
if($element.data('indexFormat') != options.indexFormat){
/* Normalize field name attributes */
newNameAttr = newNameAttr.replace($element.data('indexFormat'), $element.data('formIndex'))
/* Normalize field id attributes */
newIdAttr = newIdAttr.replace($element.data('indexFormat'), $element.data('formIndex'))
}
});
form.find("label[for='"+idAttr+"']").each(function(){
$(this).attr("for", newIdAttr);
});
that.attr("id", newIdAttr);
that.attr("name", newNameAttr);
});
}
And then update the addForm function. Around line 385 in an unmodified plugin file, add the line
// Index format
newForm.data('indexFormat', options.indexFormat);
above the line
// Index
newForm.data('formIndex', getIndex());
This should serve as a fix until the plugin author gets around to fixing the logic issues. This is for plugin version 1.1.1
I have a variable called uids
var uids = [];
Then I write some value to it property
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509"
But before it
if (!uids[user.id]) {
uids[user.id] = generateKey(user);
}
This thing behaves ok. If I try to get the value of it property
uids[currentUser.id]
It will give me a value of this property. If I try to call some methods like
Object.keys(uids);
It will give me, what I expected. And here the mystery comes...
uids;
RAM rest in piece. See the node eating ram
I am very confused now. What's wrong?
This is because you are creating a huge array and node will reserve memory for it - who knows what comes. I'd say that's a scenario where you would use a Map (or a plain object, but Map feels better here.
var uids = new Map();
var key = 456464564564654;
if (! uids.has(key)) {
uids.set(key, generateKey(user))
}
You are creating an empty array (length is zero), then you assign some value to an arbitrary index. This will make the array grow as big as the index and assign the value to that index. Look at this example using node.js REPL:
> var a = []
undefined
> a[5] = "something"
'something'
> a
[ , , , , , 'something' ]
> a.length
6
Instead of creating an array, you could create a Map() or an common javascript object (singleton). Javascript objects behave like Maps but only Strings can be used as keys. If you assign a Number to be key, javascript will convert it to String automatically.
Personally, I would go with objects because they perform better. Instantiating an object takes longer than instantiating a Map (and it doesn't seem like you need to create several groups of "uids"), but once done, adding new keys and retrieving values from any key in faster when using common objects. At least that's how things go in my node.js v6.7.0 on ubuntu 14.04 but you could try for yourself. And it would also make the least alteration to your code.
var uids = {} // common/ordinary empty javascript object instead of array.
if (!uids[user.id]) { // getting value from one key works the same.
uids[user.id] = generateKey(user) // assignment works the same.
}
////
uids[16778923] = "3fd6335d-b0e4-4d77-b304-d30c651ed509" // key will be "16778923".
uids[16778923] // getting value for key "16778923" can be done using 16778923 instead of "16778923".
////
uids[currentUser.id] // still returning values like this.
Object.keys(uids) // still returning an array of keys like this. but they are all Strings.
Struggling with some javascript array manipulation/updating. Hope someone could help.
I have an array:
array('saved_designs'=array());
Javascript JSON version:
{"saved_design":{}}
I will be adding a label, and associated array data:
array("saved_designs"=array('label'=array('class'='somecssclass',styles=array(ill add more assoc elements here),'hover'=array(ill add more assoc elements here))))
Javascript version:
{"saved_designs":{"label":{"class":"someclass","style":[],"hover":[]}}}
I want to be able to append/modify this array. If 'label' already defined...then cycle through the sub data for that element...and update. If 'label' doesnt exist..then append a new data set to the 'saved_designs' array element.
So, if label is not defined, add the following to the 'saved_designs' element:
array('label2' = array('class'=>'someclass2',styles=array(),'hover=>array()')
Things arent quite working out as i expect. Im unsure of the javascript notation of [], and {} and the differences.
Probably going to need to discuss this as answers are provided....but heres some code i have at the moment to achive this:
//saveLabel = label the user chose for this "design"
if(isUnique == 0){//update
//ask user if want to overwrite design styles for the specified html element
if (confirm("Their is already a design with that label ("+saveLabel+"). Overwrite this designs data for the given element/styles?")) {
currentDesigns["saved_designs"][saveLabel]["class"] = saveClass;
//edit other subdata here...
}
}else{//create new
var newDesign = [];
newDesign[saveLabel] = [];
newDesign[saveLabel]["class"] = saveClass;
newDesign[saveLabel]["style"] = [];
newDesign[saveLabel]["hover"] = [];
currentDesigns["saved_designs"].push(newDesign);//gives error..push is not defined
}
jQuery("#'.$elementId.'").val(JSON.stringify(currentDesigns));
thanks in advance. Hope this is clear. Ill update accordingly based on questions and comments.
Shaun
It can be a bit confusing. JavaScript objects look a lot like a map or a dictionary from other languages. You can iterate over them and access their properties with object['property_name'].
Thus the difference between a property and a string index doesn't really exist. That looks like php you are creating. It's called an array there, but the fact that you are identifying values by a string means it is going to be serialized into an object in javascript.
var thing = {"saved_designs":{"label":{"class":"someclass","style":[],"hover":[]}}}
thing.saved_designs.label is the same thing as thing["saved_designs"]["label"].
In javascript an array is a list that can only be accessed by integer indices. Arrays don't have explicit keys and can be defined:
var stuff = ['label', 24, anObject]
So you see the error you are getting about 'push not defined' is because you aren't working on an array as far as javascript is concerned.
currentDesigns["saved_designs"] == currentDesigns.saved_designs
When you have an object, and you want a new key/value pair (i.e. property) you don't need a special function to add. Just define the key and the value:
**currentDesigns.saved_designs['key'] = newDesign;**
If you have a different label for every design (which is what it looks like) key is that label (a string).
Also when you were defining the new design this is what javascript interprets:
var newDesign = [];
newDesign is an array. It has n number of elements accessed by integers indices.
newDesign[saveLabel] = [];
Since newDesign is a an array saveLabel should be an numerical index. The value for that index is another array.
newDesign[saveLabel]["class"] = saveClass;
newDesign[saveLabel]["style"] = [];
newDesign[saveLabel]["hover"] = [];
Here explicitly you show that you are trying to use an array as objects. Arrays do not support ['string_key']
This might very well 'work' but only because in javascript arrays are objects and there is no rule that says you can't add properties to objects at will. However all these [] are not helping you at all.
var newDesign = {label: "the label", class: saveClass};
is probably what you are looking for.
I'd like a class that stores a structure such as this:
{
name: "blabla",
metaData: [ {a: "mya"}, { a:"mya2"} ]
}
`
Now, I would like to have an index over the metaData[?].a fields.
What is the best way to represent this metaData in a schema? As an embeddedList?
Is it possible to have that index i want?
If so, who should the query for retrieving an entity by it's "a" value should look like?
Alternatively, if we have, instead of that metaData, a field called "myAs" that is a
simple array of string - would it be easier?
Note that i'm using the Node.JS oriento library.
I don't know if the index you want is possible, but if you do what you say in point 4, it's possible to define an index (I defined it as unique, but others will work).
You could:
create class Test
create property Test.name string
create property Test.metaData embeddedlist string
insert into Test set name = 'blabla', metaData = ['mya', 'mya2']
CREATE INDEX Test.metaData UNIQUE
insert into Test set metaData = ['mya', 'mya2'] # this will throw an exception
The query you asked in point 3 might be something like:
select from Test where 'mya' in metaData
UPDATE
You can also index an embeddedmap. (See here)
create property Test.metaDataTwo embeddedmap string
create index myIndex on Test (metaDataTwo by value) unique
insert into Test set name = 'blabla', metaDataTwo = {'prop1':'value1', 'prop2':'value2'}
insert into Test set metaDataTwo = {'prop3':'value1'} # this will throw an exception
The query to use such index should be:
select from Test where ( metaDataTwo containskey 'prop1' ) and ( metaDataTwo['prop1'] = 'value1' )
I'm trying to create an object which references a number of forms which I can JSON.stringify() to send through to a validation script with a single AJAX request, but I can't seem to properly name the array inside the object, which should be an incrementing count as the number of arrays (forms) increases.
i.e.
var images = new Object();
var i = 0;
// loop through every form
$('form').each(function() {
var form = $(this);
images[i].name = form.find('input[name="name"]').val();
images[i].description = form.find('textarea[name="description"]').val();
// etc.
i++;
});
So, when complete after say two to three iterations (that is, it's gone through two-three forms), I have a Javascript object similar to this (written in pseudocode, I'm not exactly too sure how it's actually outputted):
images {
0 {
name : 0thImageNameValueHere,
description : 0thImageDescripValueHere,
etc : etc
}
1 {
name : 1stImageNameValueHere,
description : 1stImageDescripValueHere,
etc : etc
}
}
But, right now, Firebug is giving me a SyntaxError: missing ; before statement error, centered around this line:
images[i].name = form.find('input[name="name"]').val();
Now, I can change the 'value' of images[i].name to anything I like (images[i].name = 'yes') and I still get the same error. Syntactically I'm not missing any semi-colons, so it can't be that. Is it possible I'm not declaring my object correctly?
Images is an array ([]). Your syntax does not comply with this situation (you expect an object). Create an object for each item in the array, then you can assign values to the attributes of this object.
Also, you can just make use of the index parameter provided by jQuery, you don't have to create your own iterator.
This does what you want:
var images = []; // create an array
$('form').each(function( index ) {
var form = $(this);
// create object with {} object notation
var image = {
name: form.find('input[name="name"]').val(),
description: form.find('textarea[name="description"]').val()
};
images[index] = image; // append object in array position index;
}
See for more info on objects the JSON WIKI.
See for more info on arrays W3Schools.
I don't know about any missing semi colon, but you need to create an object at images[i] before you assign any properties on it. Ie try this:
images[i] = {
name: get('input[name="name"]').val(),
description: get('textarea[name="description"]').val()
};
You can also use the index parameter supplied by each():
$('form').each(function(i) { ... }