How to use the widget fullpath to access widget's properties? - google-app-maker

I know that using widget.getFullPath() method, we can retrieve the full path of a widget as a string in the format "pagename.child1name.child2name....childNname.widgetname".
I am trying to find a way for using this string to access the original widget.
I was successful using this:
app.pages["pagename"].children["child1name"].children["child2name"]....children["childNname"].children["widgetname"].text = "some text";
but I don't know how to change this in a more general function, independent by the depth of the path.
Any idea would be very much appreciated. Thank you.

The parent root descendents should have everything on the page, so try:
widget.parent.root.descendants.ANYTHING.value;
you might alternately need to do this if you want ANYTHING to be a variable
widget.parent.root.descendants[ANYTHING].value;

My intention is to access the widget's property from another page. The root of a widget is its page, and it is the string before the first dot in the full path.
I eventually wrote a function which builds the object after splitting the full path string in an array:
function getWidgetPath(pathString) {
var pathArray = pathString.split('.');
var widgetPath = app.pages[pathArray[0]];
for( i=1; i<pathArray.length; i++ ) {
widgetPath = widgetPath.children[pathArray[i]];
}
return widgetPath;
}
The function can be used to build the target object. I.e., considering that the target widget is a label and I want to change its text property, I use:
var targetPath = 'parentpage.panel1.panel2.panel3.label1';
var targetWidget = getWidgetPath(targetPath);
targetWidget.text = 'some text';
I have the feeling that it's not very Javascriptian, though.

Related

QML Access a Component using a string to reference it´s ID

Here is the thing. I need to do the same processing for 16 Custom Input Boxes. This is a drag. So I thought I could add their ids to some sort of list and then iterate through a list, calling on a fucntion that does the processing.
Problem is I don't know how to access the component (to get the inputted text and set some variables inside it) when the id is in a string variable. Is this possible?
I'm leaving an answer here, in case it is of any help to anyone.
As it turns out you can just pass the input element as a parameter to a function. So lets say that you have
TextInput{
id: input1
...
}
TextInput{
id: input2
...
}
You could do this:
var list = [input1, input2]
for (var i = 0; i < list.length; i++) doStuffFunction(list[i])
And inside the function...
function doStuffFunction (imp){
var thetext = imp.text
//... Do more stuff
}

Umbraco: x.GetPropertyValue("myProp") vs x.myProp

I use Umbraco v4, but think this should be a common problem.
I have a generic property "myNode" of "Content Picker", that should obtain a DynamicNode...
so doying myObj.myNode I obtain the node itself... so can use myObj.myNode.Url
But doying the myObj.GetPropertyValue("myNode") I obtain the ... string ID value of the node... so can't anymore do myObj.GetPropertyValue("myNode").Url (string does not have Url property)
I can't use directly myObj.myNode, because the name is "dynamic" (the same function should use "your"+"Node" or "their"+"Node" upon conditions - the example is very aproximative, but hope the idea is clear)...
I even did myObj.GetPropertyValue<DynamicNode>("myNode"), but the result was the same: "8124" (the node id)
So, how to obtain the real property value, not just string representation of it?
Your content picker does not contain a node, it contains an id of a node.
myObj.GetPropertyValue("myNode") does exactly what is says, gets the value of a property called myNode on the instantiated DynamicNode object. It is not designed to return the node itself.
If you want to return the node whose ID your 'myNode' property contains then you have to use that value in a call to instantiate another DynamicNode
DynamicNode myNewNode = new DynamicNode(myObj.GetPropertyValue("myNode"))
or
Model.NodeById(myObj.GetPropertyValue("myNode"))
Use somethings like: mynode = Umbraco.Content(CurrentPage.myNode).Url (for Umbraco 6 and 7) For Umbraco 4 i use this Model.NodeById(Model.myNode).Url; in a script file. (I think it need at least Umbraco 4.7.x)
See also https://our.umbraco.org/documentation/Using-Umbraco/Backoffice-Overview/Property-Editors/Built-in-Property-Editors/Content-Picker
A not so elegant solution, but at least a solution that work:
var linkNode = image.GetPropertyValue("imgLinkNode" + model._lang.ToUpper());
if (linkNode is string)
{
string id = linkNode;
linkNode = model.NodeById(id);
}
var linkNodeUrl = linkNode.Url;

How do I create the correct KeyboardEvent objects for a given string of text?

I'd like to simulate some keyboard input by dispatching KeyboardEvent objects manually. Creating such events involves passing a key code.
Alas, I only have a given string
const text: String = "Hello";
I can easily get the char code using String::charCodeAt, but how can I get the key code? For any given character (say: "H") there may be just a single key code, a key code plus some modifier (in this case: Shift + keycode_of_h) or even multiple key codes. Is there maybe a way to get the key code for a given char code (possibly by considering the keyboard mapping of the user)?
This isn't too difficult but it will just take a little bit to set up.
First create a dictionary or Object mapping the UTF-8 values to key values like this:
var keyCodes:Dictionary = new Dictionary();
keyCodes[49] = Keyboard.NUMBER_1; //1
// add the rest of the mappings...
Then because you need to specify SHIFT
var shiftedKeyCodes:Dictionary = new Dictionary();
shiftedKeyCodes[33] = Keyboard.NUMBER_1; //!
// add the rest of the shifted mappings
Then create a utility function like this:
public function charCodeToKeyboardEvent(charCode:int):KeyboardEvent{
var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP);
event.charCode = charCode;
if(keyCodes[charCode]){
event.keyCode = keyCodes[charCode];
} else if (shiftedKeyCodes[charCode]){
event.keyCode = shiftedKeyCodes[charCode];
event.shiftKey = true;
} else {
return null;
}
return event;
}
Then loop through your string and do this:
for(var i:int = 0; i < myString.length; i++){
dispatchEvent(charCodeToKeyboardEvent(myString.charCodeAt(i)));
}
EDIT: I updated this to use the constants on the Keyboard class so that it will work independent of device or operating system.
It turns out that I didn't need a 100% correct KeyboardEvent in the first place. Instead, there were two things I was missing:
A flash.events.TextEvent needs to be dispatched for plain text (like "Hello") input.
The events need to be dispatched to the embedded edit control which can be accessed using the textDisplay property.

AS3: Whats determines the order of: for..in

OK I am looping through the properties in an object like so:
private var _propsList:Object = {'Type':'product_type'
,'Kind':'product_type_sub'
,'Stone':'primary_stone'
,'Stone Color':'primary_stone_sub'
,'Metal':'metal_type'
,'Brand':'product_brand'};
for(key in _propsList)
{
val = _propsList[key];
trace(key +" = "+ val);
}
I am expecting the first trace to be Type = property_type since that is the first one defined in the array, however it is coming up random everytime. I guess this is because my keys are strings and not integers, however is there a way to specify the order it loops through them?
Thanks!!
You can't rely on for (v in someObject) ... to return things in a predictable order, no.
Depending on your specific situation, you could just use an array to hold the keys, and just iterate through that:
private var keys:Array = ["Type", "Kind", "Stone", "Stone Color", "Metal", "Brand"];
private function iterate():void
{
for each (var k:String in keys)
{
trace(_propsList[k]);
}
}
Maybe a bit obvious or non-elegant, but it'd get the job done. :)
you could hack it by classing-out your "_propsList" object creating an array inside of the newly created PropsList class that references the properties in order. At that point, you could run a FOR loop on the array and get your properties in order.
OR, you could have a function inside that new class that would return an Array of those properties. like this:
public function getProps():Array {
return [myPropertyOne, myPropertyTwo, myPropertyThree];
}
In general, I think this is a case where you shouldn't depend on a particular behavior from the framework/language you are using. This type of behavior is generally poorly documented and can change from version to version.
If you really need a specific retrieval order, I would create a wrapper class as jevinkones suggested above. Maybe there's even a utility class in the framework somewhere to accomplish this (Dictionary, etc.?)
HTH,
Karthik
I found this link that gives some background:
Subtle Change in for..in Loops for ActionScript 3
This question is actually a dup of this one.
How about using an array representation like this:
var _propsList:Array = [
['Type', 'product_type'],
['Kind', 'product_type_sub'],
['Stone', 'primary_stone'],
['Stone Color', 'primary_stone_sub'],
['Metal', 'metal_type'],
['Brand', 'product_brand']
];
for(var i in _propsList) {
var elem = _propsList[i];
var key = elem[0];
var val = elem[1]
}

Ideas on making a javascript object name unique in ASP.Net?

I've created an ASP.Net user control that will get placed more than once inside of web page. In this control I've defined a javascript object such as:
function MyObject( options )
{
this.x = options.x;
}
MyObject.prototype.someFunction=function someFunctionF()
{
return this.x + 1;
}
In the code behind I've created MyObject in a startup script --
var opts = { x: 99 };
var myObject = new MyObject( opts );
When a certain button in the control is pressed it will call myObject.someFunction(). Now lets say the value of x will be 99 for one control but 98 for another control. The problem here is that the var myObject will be repeated and only the last instance will matter. Surely there's a way to make the var myObject unique using some concept I've haven't run across yet. Ideas?
Thanks,
Craig
Your Javascript like this:-
function MyObject(options) { this.x = options.x; }
MyObject.prototype.someFunction = function() { return this.x + 1; }
MyObject.create(id, options) {
if (!this._instances) this._instances = {};
return this._instances[id] = new MyObject(options);
}
MyObject.getInstance(id) { return this._instances[id]; }
Your startup javascript like this:-
MyObject.create(ClientID, {x: 99});
Other code that needs to use an instance (say in the client-side onclick event)
String.Format("onclick=\"MyObject.getInstance('{0}').someFunction()\", ClientID);
Note the low impact on the clients global namespace, only the MyObject identifier is added to the global namespace, regardless of how many instances of your control are added to the page.
If it is just one value, why not have the function take it as a parameter and build your onclick handler so that it puts the correct value in for each control. If it is more complex than that, then consider making options an array and, for each control, insert the correct options into the spot in the array that corresponds to each particular control. Then pass the proper index into the array into the function.
I do this by using ScriptManager.RegisterClientScriptBlock to register a string as a JavaScript block on the client side. I can then modify my script string using {0}, {1}..,{n} place holders to inject necessary ids. It depends on the structure of your code as to if this is the most elegant fashion, but it works in a pinch. You could then inject variable names using references to Me.ClientID.
You can make the value of "x" static and access it anywhere in the code, such as:
function MyObject( options ) { MyObject.x = options.x; }
MyObject.x = 99; // static
MyObject.prototype.someFunction = function () { return MyObject.x + 1; }
This way you can access MyObject.x anywhere in your code, even without re-instanciating MyObject.
Excellent solution Anthony. The other solutions offered were as good and I did consider them but I was looking for something a little more elegant like this solution.
Thanks!

Resources