Titanium alloy : get current window from required view - titanium

I have following code (index.js) :
<Alloy>
<Window id="home" >
<View id="formulaire">
<Require type="view" id="etape_1_form" src="form/etape_1" />
</View>
</Window>
</Alloy>
On etape_1_form.xml i have to use a picker widget from : danielhanold.pickerwidget
here is a simple method to use this widget inside etape_1_form.js (the controller) :
Alloy.createWidget('danielhanold.pickerWidget', {
id: 'mySingleColumn',
outerView: $.home,
hideNavBar: false,
type: 'single-column',
selectedValues: [20],
pickerValues: [{10: 'Auburn', 20: 'Bald', 30: 'Black', 40: 'Blond', 50: 'Brown'}],
onDone: function(e) {
// Do something
},
});
$.form_win.open();
Now instead of opening a picker, this throw an error because i cannot access the current window from this line :
outerView: $.home
The error : "undefined is not an object (evaluating 'outerView.add')
When i move the picker to the index.js (main controller) the picker works, but i have many required forms and want to organise my code, so i like put each form js code inside it's controller file.
So how i can access $.home window from required view? thank you for your help.

No, you can't directly.
But you can easily avoid this using "globals".
On index.js:
Alloy.Globals.indexController = $;
On etape_1_form.js
outerView: Alloy.Globals.indexController.home

Related

Kendo UI Grid View implementation using vue | pageable functionality issue

I'm trying to implement Kendo grid for my vue project and I was trying to show the pagination with items per page option with a custom message like "Rows per page"
Kendo provides a pageable option to show the custom message for these labels, But for some reason even after adding the custom text, I don't see the change in the UI.
Here is my code :
<Grid
:id="tableId"
:data-items="items"
:sortable="true"
:resizable="resizable"
:columns="displayedColumns"
:sort="sort"
:pageable="pageable"
>
<Grid>
computed: {
pageable() {
return {
buttonCount: 5,
info: true,
type: 'numeric',
pageSizes: [5, 10, 25, 50],
previousNext: true,
pageSizeValue: this.pageSizeValue,
messages:{
itemsPerPage: 'rows per page',
}
};
},
}
Am I missing something? Can someone please help?
Thanks.

How can I remove the radio icon from a ToggleButton in a ToggleButtonGroup?

I am trying to create a button group where a user can choose between multiple options. react-bootstrap 2.0.0-rc.0 provides the combination ToggleButtonGroup + ToggleButton for this purpose. Unfortunately, a radio icon appears next to the button. I want to get rid of it. Below, you can find a minimal example to reproduce the radio icon.
import * as React from "react";
import {
ToggleButton,
ToggleButtonGroup,
} from "react-bootstrap";
interface OwnState {
val: boolean;
}
export default class SomeToggleOptions extends React.Component<OwnProps, OwnState> {
constructor(p: Readonly<OwnProps>) {
super(p);
this.state = { val: true }
}
setVal = (newVal: number) => {
this.setState({
val: newVal == 1
})
}
render() {
return (
<div className="p-1 text-right">
<span className="p-1">Auto Refresh:</span>
<ToggleButtonGroup
name="radio"
size="sm"
onChange={this.setVal}
value={this.state.val ? 1 : 0}
>
{radios.map((radio, idx) => {
return (
<ToggleButton
key={idx}
id={`radio-${idx}`}
variant={
this.state.val === radio.value ? "dark" : "outline-dark"
}
value={idx}
>
{radio.name}
</ToggleButton>
);
})}
</ToggleButtonGroup>
</div>
);
}
}
NOTE: I already found React-Bootstrap Toggle Button is Failing to Hide the Radio Button Circle and this is NOT working for me.
The icon seems to disappear when I use the normal ButtonGroup + Button instead. But this is not primarily an option as you don't have the radio-like "exclusive" behavior there.
I reverted to the earlier react-bootstrap version 1.6.4. This is probably not fixable (without any hacky moves, css-overwriting, or similar) and induced by react-bootstrap 2.0.0 being only a release candidate so far.
In the earlier react-bootstrap version, my code snippet worked flawless.
This appears to be a temporary issue when upgrading react-bootstrap, see my answer here on duplicate question: https://stackoverflow.com/a/72636860/8291415
Also here is the closed issue on github: https://github.com/react-bootstrap/react-bootstrap/issues/5782

Importing dynamic filenames into React-Native

I have a menu.json file with hundreds of items in it:
menu_items = [
{
name: "Category 1",
file: "cat1.json"
},
{
name: "Category 2",
file: "cat2.json"
},
{
name: "Category 3",
file: "cat3.json"
},
{
name: "Category 4",
file: "cat4.json"
},
{
name: "Category 5",
file: "cat15.json"
}
]
I am able to read the menu.json file. I then create a Scrollable List showing each of the entries. When a user clicks on the entry, I want to load another screen that imports the specified json file.
Currently, when someone clicks an item in the list, the following module is loaded:
<DisplayItem file_name={this.state.selected_file} />
Then in my DisplayItem I have the following:
const item_data = require('./' + this.props.file_name);
However, I get the error:
Invalid call at line 52: require(file)
Apparently, I am unable to do imports or requires when the filename is dynamic. The only solutions I have seen is to manually require all of them first of all.
I find this solution a bit challenging because then I end up with redundant data. Any time I update the menu.json file then I have to remember to make the exact same update to the module requiring all the json files.
Is there a more efficient way to do this that eliminates the redundancy issue?
As I know You can't require a file in react native from a dynamic value, because it will make the compiler doesn't know which file to be included when building the app.
As written in React-Native's Image documentation
In order for this to work, the image name in require has to be known
statically.
For example
// GOOD
<Image source={require('./my-icon.png')} />;
// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;
// GOOD
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />;

Titanium appcelerator model and collections persistance

I am about to retrieve datas from remote and create model and collections, here are each part of the app (the controller, the view and the model).
If i really understand using model in titanium is like storing into database so the data persists even if there is no internet connection after i get all datas.
Below code works well, it seems no data is displayed after connection is lost, so i ask myself what is the advantage of using models in titanium instead of using classic way : retrieve from xhr and display data ?
2- My second question (if i am wrong) after retrieving datas and storing into model, i can retrieve it without xhr again inside another page?
3- And the last one : is it a good practice to retrieve data from alloy.js and save to model because i need datas in all my app pages ?
THE CONTROLLER
// This is an istance of my xhr library
var XHR = require('xhr');
var xhr = new XHR();
$.win.addEventListener('open', function(){
url = 'mydomain.com/api/get_posts';
xhr.get(url, onSuccess, onError);
});
function onSuccess(response){
if(typeof response !== null ){
datas = JSON.stringify(response.data);
postsModel = [];
_.each(datas, function(data){
/* Create model */
postsModel.push(Alloy.createModel('mypostsmodel',{
title : data.title,
id : data.id
}));
});
$.posts.reset(postsModel);
}
}
** THE VIEW **
<Alloy>
<Collection src="myposts" instance="true" id="myposts" />
<Window id="win" title="Inscription" class="container" >
<View id="posts_view" class="myposts" dataCollection="$.myposts">
<View postId="{id}" class="post_item">
<Label class="post_label" text="{title}" />
<Label class="exp" id="exp_{id}" text="" />
</View>
</View>
</View>
</Alloy>
THE MODEL
exports.definition = {
config: {
"columns": {
"title": "Text",
"id": "Integer"
},
"defaults": {
"title": "-",
"id": "-"
},
adapter: {
type: "sql",
collection_name: "myposts"
}
},
extendModel: function(Model) {},
...
Thank you all.
The advantage in my opinion a clearer definition of the View. In my opinion the biggest thing Alloy brings to the table is the ability to more cleanly separate your view from the logic that drives your application. Your logic is also simplified (in most cases!) because all you need to do is add the data to the collection, and Alloy handles the display.
The alternative to how you are doing it:
_.each(datas, function(data){
var container = Ti.UI.createView({class: "post_item"}),
title = Ti.UI.createLabel({
text: data.title,
class: "post_label"
}),
exp = Ti.UI.createLabel({class: "exp"});
container.add(title);
container.add(exp);
$.posts_view.add(container);
});
I've done it both ways, and even with alloy, sometimes it is necessary to do this, because of the limitations of Backbone as implemented in Titanium - but I think clearly if you can include your repeating UI components in the markup, it's easier to read and maintain.

How to handle dynamic creation of view in alloy xml

I have very simple view index.xml
<Alloy>
<Window id="byFav">
<TableView id="tableByFav" />
</Window>
<Alloy>
in this program I want to open webView and use this instead of tableByFav View
when you click tableByFav.
I am not sure how to describe this process in xml.
So I write code in index.js like this.
$.tableByFav.addEventlistener('click',function(e){
entryWindow = Titanium.UI.createWindow({
title: "window"
});
entryView = Titanium.UI.createWebView({
url: "google.com"
});
entryWindow.add( entryView );
$.byFav.open( entryWindow );
}
However I am not sure it is obeying the concept of alloy.
I am trying to understand the concept of alloy.
You are opening the wrong window, try this instead:
$.tableByFav.addEventlistener('click',function(e){
var entryWindow = Titanium.UI.createWindow({
title: "window"
});
var entryView = Titanium.UI.createWebView({
url: "http://www.google.com"
});
entryWindow.add( entryView );
// Call open on the entry window itself
entryWindow.open({
modal : true // Set to true if you want an opening animation
});
}
To do this with Alloy, you can create a controller for the webview named (entryWindow.xml) like this:
<Alloy>
<Window id="entryWindow">
<WebView id="entryView" />
</Window>
<Alloy>
And the in controller (entryWindow.js) you can set the url from the supplied arguments:
$.entryView.url = arguments[0].url;
Now in your index controller, you would open the webview like this:
$.tableByFav.addEventlistener('click',function(e){
// Create a controller, pass url argument
var controller = Alloy.createController('entryWindow', {url: "http://www.google.com"});
// Get the controller's view (a window) and open it
controller.getView().open({
modal : true // Set to true if you want an opening animation
});
}