I am trying to create an array in Jade and then loop through another and create a new array from it. I am doing something like:
.metadata4
- var prepopulate = []
- if (entry.artist_ids)
- for (var artist in entry.artist_ids)
- var name = entry.artist_ids[artist]
- prepopulate.push({id: name, name: name})
input(type='text', class='token-input', data-url="/query", data-pre=prepopulate)
All this works awesome. However, it seems to add an extra element onto the end of the list (like its pushing the function push to the array or something). Anyone know why this may be?
I am not sure why this is happening and also didn't test it. as a workaround, what you can do is, declare a new var i = 0;
and then increment it inside the for. and put prepopulate.push({id: name, name: name}) inside an if statement, like if(i < entry.artist_ids.length - 1){...push...}
I cannot reproduce this behavior, using the following data
entry = { "artist_ids": {1: "hello", 2:"robert"} }
I get the following data-pre:
[{"id":"hello","name":"hello"},{"id":"robert","name":"robert"}]
which is exactly what you wrote (although I suspect you wanted to replace id's name value with artist)
Maybe you could post your entry object?
Related
I have many string variables that start with "Question" and then end with a number. ("Question1")
Each variable has a question in it ("How many times does it say E?")
There is an editable textbox on the stage that the user types in which question number he want to be displayed in a different textbox. ("1")
When the user clicks a button, I want that the text of Question1 should be displayed in the textbox.
My code looks like this:
var Question1:String = "How many times does it say E?" ;
var Question2:String = "How many times does it say B?" ;
var Question3:String = "How many times does it say A?" ;
myButton.addEventListener(MouseEvent.CLICK, displayQuestion);
function displayQuestion(event:MouseEvent):void
{
var QuestionNumber:Number = Number(userInputQuestionNumber.text);
textBoxDisplayQuestion.text= Question(QuestionNumber);
}
How can I get the textBoxDisplayQuestion to display the actual text of the Question??
(the code i have now obviously is not working!!)
But this example doesnt seem to work: I created a class called Question and here is the code:
import Question;
var QuNoLoad:Number;
var Qu1:Question = new Question(1,"how","yes","no","maybe","so","AnsB","AnsA");
trace(Qu1.QuNo, Qu1.Qu, Qu1.AnsA,Qu1.AnsB, Qu1.AnsC, Qu1.AnsD, Qu1.CorAns, Qu1.FaCorAns);
//the following is the code for the button
loadQu.addEventListener(MouseEvent.CLICK, loadQuClick);
function loadQuClick(event:MouseEvent):void
{
//this sets the variable "QuNoLoad" with the contents of the "textBoxQuLoad"
//imagine the user inputed "1"
QuNoLoad=Number(textBoxQuLoad.text);
//this SHOULD!! display the contents of "Qu1.Qu"
textQu.text= this["Qu"+QuNoLoad.toString()+".Qu"]
//and when i traced this statment the value was "undefined"
}
Why???
You can reference a variable by name using square brackets [] operator, such as:
this["Question" + QuestionNumber.toString()]
You may use this operator to dynamically set and retrieve values for a property of an object.
Keeping the question number as an integer, your function would be:
var Question1:String = "How many times does it say E?" ;
var Question2:String = "How many times does it say B?" ;
var Question3:String = "How many times does it say A?" ;
function displayQuestion(event:MouseEvent):void
{
var QuestionNumber:uint = uint(userInputQuestionNumber.text);
textBoxDisplayQuestion.text = this["Question" + QuestionNumber.toString()];
}
This is a pretty fundamental concept in programming that will make a lot of things harder to do until you understand it well, and it's pretty hard to explain without starting with some groundwork:
What's happening here is easiest to talk about with plain old Object rather than classes, so lets start with a very simple example:
var question1:Object = new Object();
question1.number = 1;
Note that with Object you didn't have to say that number existed ahead of time, it gets created when you set it. Now, when you say either question1.number you get 1, obviously. What is happening, however is that first question1 gets the value you stored in the variable question1 (which is { number: 1 }), then the .number gets the value stored in the property number stored in that value: 1.
To save some typing, you can use a shorthand called "object literals":
var question1 = {
number: 1
};
Now lets try a more complex object:
var question1 = {
number: 1,
text: "How many times does it say A?",
answers: {
a: 1,
b: 2,
c: 3,
d: 4,
correct: "b"
}
};
Now question1 is an object that has 3 properties, one of which, answers, is an object with 5 properties: a, b, c, d, and correct. This could also be written as:
var question1 = new Object();
question1.number = 1;
question1.text = "How many times does it say A?";
question1.answers = new Object();
question1.answers.a = 1;
question1.answers.b = 2;
question1.answers.c = 3;
question1.answers.d = 4;
question1.answers.correct = "b";
It should be pretty clear why the literal syntax exists now!
This time, if you say question1.answers.correct you get "b": first question1 gets you the { number: 1,...} value, then the .answers gets the { a: 1, b: 2,...} value, then finally the .correct gets the "b" value.
You should also know that this is a special variable that has a particular meaning in ActionScript (and JavaScript, on which it is based): it broadly refers to the object in when the code you are writing is inside: for "global" code (not inside a function), var adds properties to this object: var number = 2; and this.number = 2 are this same here. (This is not true when you're in function, this behaves differently there, sometimes in very strange ways, so be careful!)
Now you might start seeing what's happening: when you use [], for example, question1["number"], rather than question1.number, you are passing the property name you want to get as a String value, which means you can change what property you get while you are running, rather than when you compile ("runtime" vs. "compiletime"), but it also lets you get properties with names you can't refer to with the . syntax!
var strange = {
"a strange name? That's OK!": 1
};
trace(strange["a strange name? That's OK!"]);
So when you write this["Qu" + QuNoLoad.toString() + ".QuNo"], you create a name like "Qu2.QuNo", for example, you are trying to get a property with that exact name, . included, which doesn't exist! What you were trying to do the equivalent of: Qu2.QuNo could be written as this["Qu" + QuNoLoad].QuNo.
I shouldn't leave this without saying, though, that for something like this, I would use arrays, which exist so that you can use a single name to store a list of values:
var questions:Array = [ // set questions to an array with multiple questions
new Question(...),
new Question(...),
...
];
for each (var question:Question in questions) { // Look at each question in the array
if (question.QuNo == textBoxQuLoad.text) { // If this is the right question
loadQuestion(question);
break; // Found it, stop looking at each question by "breaking out" of the for each
}
}
There's lots more you can do with arrays, so read up on them when you get time.
I'm reading XML and attaching values to objects in two seperate movieclips. Like this
Map01:
Marker01.name = hello there
Marker01.short = hel
Marker01.value = 12
Map02:
Marker02.name = hello there
Marker02.short = hel
Marker02.value = 99
Now I'm clicking on Marker01 in Map01 and get its name and value. I want to compare its value to that of Marker01 in Map02, using the name, or better yet .short because the names are long and use special characters/spaces. How do I do this? I've pretty much tried everything that seemed logical!
EDIT: sample code for clarification
var marker01:mc_marker = new mc_marker();
marker01.name="hello there";
marker01.short="abc";
marker01.val="99";
marker01.x=10;
marker01.y=10;
this.mc_map01.addChild(marker01);
var marker02:mc_marker = new mc_marker();
marker02.name="hello there";
marker02.short="abc";
marker02.val="20";
marker02.x=10;
marker02.y=10;
this.mc_map02.addChild(marker02);
marker01.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
marker02.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
function showMarkerInfo(event:MouseEvent):void {
txt_ms.text=event.target.short;
txt_mv.text=event.target.val;
if (event.target.short==mc_map02.marker02.short){
txt_mvi.text="here should be the marker02 value";
}
}
You have a typo there. Map02 use Marker1 things.
If its a typo in Stackoverflow,
this.getChildByName( "Marker01" ) will return you the movieclip, buy its name. take care though, as "name" is what it searches for. You used "hello there" when you should put Marker01 as the name. I would suggest you put a property called "data" and put the xml info in it so it doesn't conflict.
In the end you have:
if( this.getChildByName( "Marker01" ).data.value == this.getChildByName( "Marker02" ).data.value ).
I assume this is because you generate Marker0X at runtime and you can't declare some variables and use them directly.
Browny points if you make "data" a instance of a custom class where you can compare two "data". If you need more help, add a comment ^_^
I'm trying to create a flash application that will keep track of user generated values. The app should basically allow the user to input the name of the item and it's cost. The total costs should then be added up to show a total value to the user. I can probably figure out how to add the values together, but I'm not really sure how to allow the user to create a list and then allow the user to save it. Can anyone point me towards a tutorial or point me in the right direction?
I am using variables to add user inputed numbers to come up with a total. The first problem is that actionscript 3.0 does not allow variables for texts. I just converted it to 2.0 to fix this. The second problem, is when I test the app and put in my values and click submit, I get NaN in the total values field. Is there a reason why it wouldn't add the values?
Here is the code I used for the submit button:
on (release) {
total = Number(rent) + Number(food) + Number(travel) + Number(entertainment) + Number(bills);
}
Am I missing anything?
Can I give the input text instance names and then give them variables? How are some ways to go about this?
Thanks for the help!
Have an object array, say for example
var stack:Array = new Array();
Then push the item name and it's cost to that array when user inputs, like
stack.push({item:AAA, cost:xx});
So that you can generate the list whenever you want with that array.
You have to see how this works in code. A list in actionscript could be stored inside an array, vector, dictionary or even an Object.
Var myList:Array = [];
myList.push({name: "item 1", cost: 5 });
myList.push({name: "item 2", cost: 7.5 });
If you want to grab the 'product' of "item 1" from the list, you have to create a function for that, lets call it getProductByName
function getProductByName(name:String):Object
{
for each(var product:Object in myList)
{
if (product.name === name) return product;
}
return null; // no match found
}
You can call that function like this:
var product = getProductByName("item 1");
trace(product.cost); // 5
And you can alter the product, so lets make it more expensive
product.cost += 1;
trace(product.cost); // 6
Have fun! If you are using classes, you would create one for the product, with public name and cost, and in that case you'de better use a vector, to ensure working with the right type.
This is what fixed the issue for me in action script 3.0:
myButton.addEventListener(MouseEvent.CLICK, addThem);
function addThem(e:MouseEvent)
{
totalField.text = String ( Number(field1.text) + Number(field2.text) + ....);
}
I also had to name the instances appropriately.
Hmmm, maybe someone can help me out here or point me in the right direction , as i have been banging my head against the wall for a number of days now and dont seem to be gettin anywhere useful.
(and admittedly i'm pretty new with regards to json,objects, google visulization etc)
essentially, i am running 3 different queries on the same page against 3 different fusion tables, which in return are supposed to return an array of 3 different xets of markers.
all is fine, when i run the queries individually and make an array of the markers .
however, running the 3 queries on the same page, i can't seem to find a way to identify the query in the response function.
any hints much appreciated. and i'll be happy to provide more info if needed (tried to get rid of some unneccessary stuff)
this is what i have. thanks
a) calling the function "setFusionData()" with all relevant vars. something like setFusionData("'LatLng','name'", 2729461);
(this is calles 3 times with different variables)
function setFusionData(selColumns,tableId) {
/****
an actual query example is this:
http://www.google.com/fusiontables/gvizdata?tqx=reqId:1234&tq="select+'LatLng','name'+from+2729461"
****/
var query = new google.visualization.Query(
'http://www.google.com/fusiontables/gvizdata?tqx=reqId:1234&tq='+ encodeURIComponent("SELECT "+selColumns+" FROM "+tableId+"")
);
query.send(getFusionData); //do something with the response
}
function getFusionData(response) {
/**
here, is the problem as i need to get the table id or reqId or anything that is uniquely passed on from "setFusionData" above
also something like
alert(JSON.stringify(response)) does not return any reqId or table id either
***/
/*return rows/columns and add values to an array of markers***/
var numRows = response.getDataTable().getNumberOfRows();
var numCols = response.getDataTable().getNumberOfColumns();
for (i = 0; i < numRows; i++) {
/* add markers to array etc this works fine***/
}
}
i also tried something like this:
function setFusionData(selColumns,tableId) {
......
query.send(getFusionData({reqId:tableId}));
}
function getFusionData(response) {
alert(response['reqId']);//returns tableId. but how do i get the tableData ?
}
with wich i can get the reqId, but not the table*Data*. So I am only able to get either id or data :(
----edit----------------
after messing around a bit more (see below) it appears that the key/value pairs that get returned when typing the query into the browser directly are different than what gets returned by the call from the script...i.e the following
http ://www.google.com/fusiontables/gvizdata?tqx=reqId:1234&tq="select+'LatLng','name'+from+2729461"
typed directly into the browser bar will return
version:'0.5',reqId:'1234',status:'ok',table etc
however, calling the same from within the script returns something like
{
"rj":"0.5","ef":"ok","pb":[],"qb":[],"h":"{"cols":
[{"id":"col2","label":"LatLng","type":"string"},{"id":"col1","label":"name","type":"string"}],
"rows":
[{"c":[{"v":"47.20572,12.70414"},
{"v":"Hohe Tauern"}]},{"c":[{"v":"47.5530395,12.925611"},{"v":"Berchtesgaden"}]},{"c":[{"v":"47.5585405,14.61887"},{"v":"Gesu00e4use"}]}],
"p":{"totalrows":3}
}"
}
, so no 'reqId' but only some cryptic keys (without one that looks like the reqId either)...... anyone any idea why that would/could be ?
Sometimes you can figure it out by just looking at the JSON response, your sample request returns:
google.visualization.Query.setResponse({
version:'0.5',
reqId:'1234',
status:'ok',
table: {
...
}
})
You already got response.reqId to identify which request is this the response for, now you can use response.table to create a new DataTable instance:
var dt = new google.visualization.DataTable(response.table);
Or, since you have multiple tables, put then in an array indexed with the reqId
tables[response.reqId] = new google.visualization.DataTable(response.table);
You'd do var tables = new Array() before calling setFusionData() for the first time.
I was trying to make a similar thing with the game SameGame (ie. the block above the removed blocks fall downward). Before trying this with an Array that contains MovieClips, this code worked (tried it with int values). With MovieClips on the array, it seems not working the same way.
With int values, example:
popUp(0, 4): Before: 1,2,3,4,5,6,7,8,9,10; After: 1,2,3,4,6,7,8,9,10
But with MovieClips:
popUp(0, 4): Before: 1,2,3,4,5,6,7,8,9,10; After; 1,2,3,4
// Assume the numbers are movieclips XD
Basically, it strips everything else, rather than just the said block >_<
Here's the whole method. Basically, two extra arrays juggle the values above the soon-to-be removed value, remove the value, then re-stack it to the original array.
What could be wrong with this? And am I doing the right thing for what I really wanted to emulate?
function popUp(col:uint, row:uint)
{
var tempStack:Array = new Array();
var extraStack:Array = new Array();
tempStack = IndexArray[col];
removeChild(tempStack[0]);
for(var ctr:uint = tempStack.length-(row+1); ctr > 0; ctr--)
{
removeChild(tempStack[ctr]);
extraStack.push(tempStack.pop());
trace(extraStack);
}
tempStack.pop();
for(ctr = extraStack.length; ctr > 0; ctr--)
{
tempStack.push(extraStack.pop());
//addChild(tempStack[ctr]);
}
IndexArray[col] = tempStack;
}
PS: If it's not too much to ask, are there free step-by-step guides on making a SameGame in AS3 (I fear I might not be doing things right)? Thanks in advance =)
I think you just want to remove an element and have everything after that index shift down a place to fill what you removed. There's an inbuilt function for this called splice(start:uint, length:uint);
Parameters:
start - the index to start removing elements from
length - the amount of elements to remove
var ar:Array = ["hello","there","sir"];
ar.splice(1, 1);
ar is now -> ["hello", "sir"];
As per question:
Here's an example with different types of elements:
var ar:Array = [new MovieClip(), "some string", new Sprite(), 8];
ar.splice(2, 1);
trace(ar); // [object MovieClip], some string, 8
And further example to display the indexes being changed:
trace(ar[2]); // was [object Sprite], is now 8