Create dynamic number of rows from xml appcelerator ios - ios

I have created xml file like below :
//cityState.xml
<Alloy>
<Window id="cityStateMgWin">
<TableView id="cityAndStatesTableView" >
<TableViewRow id="cityStatesRow" ></TableViewRow>
</TableView>
</Window>
//In cityState.js
I am trying to create state rows dynamically with the following code.
for (var i = 0; i < cityAndStatesListJSONData.length; i++) {
$.cityAndStatesTableView.appendRow(Alloy.createController('cityStatesRow', {title : cityAndStatesListJSONData[cityStates].cityState}).getView());
}
When i run the following error will coming please help me
message = "Object is not a constructor (evaluating 'new (require(\"alloy/controllers/\" + name))(args)')";
[ERROR] : stack = "createController\nonload";
is there any mistake to get the ui element from xml file to controller and create dynamic number of rows.
Thanks in advance.

A couple suggestions.
You have underscore available in Alloy
You cannot create a controller based on ID, it needs to be an actual controller.
So... looping through your data is easier this way:
_.each(cityAndStatesListJSONData, function(cityAndState){
});
Next, make a controller cityStatesRow for your row. Should look like this
JS File of this controller:
if ($.args.data.labelProp){
$.myLabel.text = $.args.title;
}
You can do this with as many items as you like, images, labels etc. Whatever you want in the row.
Within the _.each loop you will want to create the controller and pass the data to it:
var controller = Alloy.createController('cityStatesRow', {title : cityAndState.cityState});
And now append it to your TableView
$.cityAndStatesTableView.appendRow(controller.getView());

Related

AppMaker and picker widget - uploading to a specific folder

I'm trying to have a button to allow users to upload a file, into a specific folder. I tried to follow other advise, and add this hook to
onPickerInit:
var uploadView = new google.picker.DocsUploadView()
uploadView.setParent('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'); // test folder
pickerBuilder.addView(uploadView);
I've set the MULTISELECT_ENABLED feature (without it, the destination folder is not respected), and I can in fact now upload the files where they belong. Yay!
HOWEVER: The picker widget now has two upload tabs. The first one just does the regular upload into the drive main folder, the second tab does the right thing. My guess is that appmaker contstructs the first upload tab behind the curtains and there is no feature to disable this.
This is obviously fairly quirky and hardly usable. My questions are:
1) are there (possibly undocumented) API calls in the pickerbuilder to remove the original upload view?
2) Is it possible to respect the destination folder even is the MULTISELECT feature is off ?
Many thanks in advance for any pragmatic solutions!
EDIT 07/28/2020
Due to the constant changes in drive picker, this code aims for a more permanent solution:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
var prps = [];
for(var prop in pickerBuilder){
var value = pickerBuilder[prop];
if(!!value){
if(typeof(value)==="object"){
var proto = value.__proto__; //jshint ignore: line
if(!!proto["addLabel"] && !!proto["addView"]){
prps.push(prop);
for(var key in value){
var target = value[key];
var type = Object.prototype.toString.call(target);
if(type === "[object Array]"){
prps.push(key);
for(var key in target[0]){
var value = target[0][key];
if(typeof(value)==="object"){
prps.push(key);
}
}
for(var key in target[0]){
var value = target[0][key];
if(typeof(value)==="string") {
prps.push(key);
}
}
}
}
}
}
}
}
var views = pickerBuilder[prps[0]][prps[1]];
for(var i=0; i<views.length; i++){
var view = views[i];
if(view[prps[3]] === "upload"){
view[prps[2]].parent = folderId;
}
}
EDIT 06/29/2020
There has been another change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.rw.kf["0"].Ta.parent = folderId;
EDIT 05/26/2020
There has been another change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.xw.jf["0"].Ta.parent = folderId;
EDIT 02/17/2020
There has been a change in the Drive picker API. To make this work please change what you have to:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.mw.$e["0"].Ra.parent = folderId;
To answer your questions directly:
1.) YES
2.) YES
Now, let's dig a little bit into what's happening under the hood. You are right:
My guess is that appmaker contstructs the first upload tab behind the curtains and there is no feature to disable this.
However, we can manipulate the object. So instead of creating a new picker view, let's simply configure the default one to upload the files to the folder you want. We can achieve that by doing the following:
1.) After you insert a Drive Picker into your UI, make sure the Drive Picker Properties are all empty:
2.) Next, go to the event handlers and click on the onPickerInit event handler. Type in this code:
var folderId = "10fYS3l32R6gk79POOSS8X_Vbsz7vqzRWX"; //the desired folder id
pickerBuilder.SW.Vq["0"].mc.parent = folderId;
In summary, I've come to the conclusion that the property SW contains the array of drive views, which are saved under the property Vq. Vq["0"] is the first view in the array of views and the mc property contains the features; hence parent = folderId.

How to find View with ID

Trying to build some simple app with rikulo framework and have a question:
Is it possible to find View inside hierarchical layout ? and how ? (in Dart)
There's some documentation on Rikulo site about IdSpace but I didn't quite understand how to use it. Should I extend View with IdSpace ? Or View will auto-generate the Id ?
Update (add code example)
/*
* Function will actualy build View
*/
void _buildUi(Element tagElement)
{
View mainView = new View();
mainView.profile.width = '100%';
mainView.profile.height = '100%';
mainView.layout.type = 'linear';
mainView.layout.orient = 'vertical';
mainView.style.cssText = "background: yellow;";
View vWorkSpace = new View();
vWorkSpace.profile.width = 'flex';
vWorkSpace.profile.height = 'flex';
vWorkSpace.layout.type = 'linear';
vWorkSpace.layout.orient = 'horizontal';
vWorkSpace.style.cssText = "background: red;";
//
// Left menu
View vLeftBar = new View();
vLeftBar.profile.width = "10%";
vLeftBar.profile.height = "10%";
vLeftBar.layout.type = 'linear';
vLeftBar.layout.orient = 'vertical';
vLeftBar.layout.spacing = '10';
View vLogo = new View();
vLogo.addChild(new Image('images/google_chrome.png'));
vLeftBar.addChild(vLogo);
Button vButton = new Button();
vButton.text = 'Sign in with Google';
vLeftBar.addChild(vButton);
vButton.on.click.add((e){ // Somehow I get an error here: Method 'add' not defined for class 'Stream'
broadcaster.send(new ViewEvent('foo'));
});
vWorkSpace.addChild(vLeftBar);
mainView.addChild(vWorkSpace);
mainView.addToDocument(ref: tagElement, layout: true);
}
In another place in dart.app when handling the vButton click event. How I could find (in code) the vLogo View ?
The easiest way to retrieve a View in the code is to give it an id:
View vLogo = new View();
vLogo.id = "vLogo";
Then, in your event listener, use query to access it:
button.query("#vLogo"); // returns vLogo
However, in your case, you will be able to directly access the vLogo instance within the event listener closure.
Sure, like Element, View provides CSS selector based retrieval called query and queryAll. You can use them to retrieve the view as you retrieve the DOM elements.
In general, you don't have to worry about IDSpace, unless you want to use the same ID in different views. A hierarchy tree itself is an ID space. If a view implements IDSpace, it forms another ID space.

How to bind generic list of objects to a MonoDroid GridView

I want to bind List with 5 properties (columns) and 10 rows of data to a GridView. The examples I found all have an ImageAdapter.
How do you bind object properties from a list to the GridView? What kind of Adapter do I need?
I dont know if this help you, but when i need a custom control I set all the information inflating a custom axml, if you are used to a WindowsPhone or a Windows 8 application, it's like a User Control
LinearLayout linearImages = FindViewById<LinearLayout>(Resource.Id.LinearLayoutImages);
LayoutInflater layoutInflater = (LayoutInflater)LayoutInflater.Context.GetSystemService(Context.LayoutInflaterService);
foreach (Image image in images)
{
var view = layoutInflater.Inflate(Resource.Layout.ImageControl, null);
TextView txtView = view.FindViewById<TextView>(Resource.Id.textView);
txtView.Text = image.Title;
...
linearImages.AddView(view);
}

How to use dynamic e.parameter with Google Apps?

I have created a grid in a doGet() function. This grid contains a dynamic number of rows choose by the user. In each rows i have some TextBox. I would like to be able to get all the data inserted by the user on the textboxes once the user clicked on the submit button.
So i give a dynamic ID to each textBox :
app.createTextBox().setName('gridText'+countRow);
countRow ++;
.........
My problem is that I dont know how to dynamicaly access to my TextBox on my submit function.
I tried something like this :
for( i = 0 ; i < countRow ; i++){
var buffer = e.parameter[e.parameter.gridText]+i;
.........
}
based on this : http://productforums.google.com/forum/#!category-topic/apps-script/services/nWN14AQ-9gQ
But it does'nt work... whereas this works :
var buffer = e.parameter.gridText3;
Any idea of what i'm doing wrong ?
Thanks for your help
Try
var buffer = e.parameter['gridText' + i.toString()];

Add an event to HTML elements with a specific class

I'm working on a modal window, and I want to make the function as reusable as possible. Said that, I want to set a few anchor tags with a class equals to "modal", and when a particular anchor tag is clicked, get its Id and pass it to a function that will execute another function based on the Id that was passed.
This is what I have so far:
// this gets an array with all the elements that have a class equals to "modal"
var anchorTrigger = document.getElementsByClassName('modal');
Then I tried to set the addEventListener for each item in the array by doing this:
var anchorTotal = anchorTrigger.length;
for(var i = 0; i < anchorTotal ; i++){
anchorTrigger.addEventListener('click', fireModal, false);
}
and then run the last function "fireModal" that will open the modal, like so:
function fireModal(){
//some more code here ...
}
My problem is that in the "for" loop, I get an error saying that anchorTrigger.addEvent ... is not a function.
I can tell that the error might be related to the fact that I'm trying to set up the "addEventListener" to an array as oppose to individual elements, but I don't know what I'm supposed to do.
Any help would be greatly appreciated.
anchorTrigger[i].addEventListener...

Resources