I have a widget that contain a back button, when click that back button i want to close the window that having the widget (parent window).
here is my widget.xml :
<Alloy>
<View id="topBar">
<View id="leftItems">
<ImageView id="backIcon" onClick="previousPage" />
<ImageView id="logo" />
</View>
<View id="midItems">
<Label id="pageTitle"></Label>
<ImageView id="searchIcon" onClick="searchIcon" platform="ios" />
<SearchBar id="searchBar" platform="ios" />
<SearchView id="searchView" ns="Ti.UI.Android" platform="android" onBlur="pageTitleVisiability" onFocus="pageTitleVisiability" />
</View>
<View id="rightItems">
<ImageView id="createIcon" onClick="createPost" />
</View>
</View>
</Alloy>
and in widget.js :
function previousPage(argument) {
// closing the window
}
i tried to send the custom property in the widget with the window name like this:
Alloy.createController('windowName').close();
but it says that the window is not opened
You can't create the controller in the widget and try to close it, you are creating a new instance of the window, not referencing the calling controller. I would use messaging to perform the close. Inside you previousPage function, add "$.trigger('closeParent');" to signal to close the window. Then inside the calling window (where the widget is referenced) add something like "$..on('closeParent', );" and then close the window in the function. I hope that makes sense.
Setting callbacks should solve your problem.
your "widget.js" :
var previousPageCallback;
function previousPage() {
if(previousPageCallback) previousPageCallback();
}
module.exports = {
previousPageCallback : previousPageCallback
};
your "previousWindow.xml"
<Window>
<Widget id="myWidget" src="<whateverYourWidgetNameIs>"/>
</Window>
your "previousWindow.js" (the window where you are using the widget)
$.myWidget.previousPageCallback = $.previousWindow.close();
Thanks n cheers
Related
I had a render function with a button that redirects to another page.
When I enter the page, it does immediately trigger to the page (without cliking the button) and display the following warning message : cannot update during an existing state transition
render () {
return (
<View>
<Text > {this.state.text} </Text>
<Button onPress={this.props.navigation.navigate('Home')}
title = "Go Home" />
</View>
);
}
I solved it with the following code, but I don't understand why the previous did'nt work.
render () {
return (
<View>
<Text > {this.state.text} </Text>
<Button onPress={() => this.props.navigation.navigate('Home')}
title = "Go Home" />
</View>
);
}
Could you explain me why the behavior is different ?
When you do:
this.props.navigation.navigate('Home')
You are calling the navigate function and passing it's output to the onPress.
When you do:
() => {
this.props.navigation.navigate('Home')
}
you are passing an arrow function (not a call) and this function contains a call to your navigate, but the arrow function isn't called until the button is pressed.
Your solution with the use of an arrow function is the right thing to do, because you have to pass a parameter, if you didn't have to pass it you could do:
<Button onPress={this.someOfMyFunctions.bind(this)}
title = "Go Home" />
This would result in the someOfMyFunction call when the button is clicked.
That happens because you are actually calling the function in the first case.
In your second code block you are passing the function to the onClick handler which is what you want to do. The value should be a function, not a call to a function.
Hope that helps.
I'm working in react-native. I have a form page in my mobile app and have an edit button and back button. Once the edit button is clicked, I want a save and cancel button to replace the edit and back button, and they should have their own functionality. I have tried componentWillUpdate() and if else statements in my render function, but neither seem to work.
You can put all the buttons in your render function, controlled with state(eg. inEditMode). When user click on edit button you can set inEditMode to true and display the edit & back button.
Something like this:
render() {
this.state.inEditMode ?
<View>
<EditButton />
<BackButton />
</View> :
<View>
<CancelButton />
<SaveButton />
</View>
}
I'm trying to use NavigationBar from the Shoutem UI toolkit.
My code:
<Screen>
<NavigationBar centerComponent={<Title>TITLE</Title>}/>
<ListView
data={groupedData}
renderRow={this.renderRow}
loading ={this.state.loading}
onRefresh={this.getAllNewsfeed.bind(this)}
onLoadMore ={this.loadMoreData.bind(this)}
loadMoreSpinner={<Spinner/>} />
<Button onPress={this.onLogout.bind(this)}>
<Text>
LOGOUT
</Text>
</Button>
</Screen>
But NavigationBar always hidden, listview above NavigationBar. But when I try replace it to Title. It still work. But I don't want use Title because I want add button back or something else same that.
This PR solves it https://github.com/shoutem/ui/pull/104/files but somehow we have removed it from the theme. We are going to fix that in next release but until then you can help yourself by this:
<Screen>
<NavigationBar
style={{
container: {
position: 'relative',
width: Dimensions.get('window').width,
}
}}
centerComponent={<Title>TITLE</Title>}
/>
<ListView
data={groupedData}
renderRow={this.renderRow}
loading ={this.state.loading}
onRefresh={this.getAllNewsfeed.bind(this)}
onLoadMore ={this.loadMoreData.bind(this)}
loadMoreSpinner={<Spinner/>}
/>
<Button onPress={this.onLogout.bind(this)}>
<Text>
LOGOUT
</Text>
</Button>
</Screen>
After release you will just have to change style prop to:
<NavigationBar
styleName="inline"
centerComponent={<Title>TITLE</Title>}
/>
My onClick event seems to not be firing, I have a button inside a <ScrollView>, and it does not give me any response, so I was wondering if there is a way to track which object was clicked so I could do the styling to make my buttons clickable again.
<Alloy>
<Window class="container">
<View class="insideContainer">
<View layout="horizontal">
<ImageView id="minLogo" image="/images/homeLogo.png" ></ImageView>
<ScrollableView id="mainViewInterna">
<View id="MainWelcomeText" class="MainWelcomeText rowLayout">
<Label class="welcomeText">BEM VINDO</Label>
<Label class="welcomeText">[ Usuário ]</Label>
<View class="button-row" width="200dp" height="200dp">
<Label id="logoutButton" class="button" onClick="logout">Log Out</Label>
</View>
</View>
</ScrollableView>
</View>
</View>
</Window>
</Alloy>
The Function:
function logout(){
Ti.API.log('it works');
}
var logout = function() {
$.logoutButton.removeEventListener('click',logout);
console.log('logout');
};
$.logoutButton.addEventListener('click',logout);
The widget that I have is working on other xml files..except for one...
The process goes like this...There's a view that when clicked, a window will open..
<Alloy>
<View class="vertical hsize">
<View class="hsize">
<Require src="actionbar" type="widget" />
</View>
<ScrollView class="container vertical whitebg">
<View class="downloadRowContainer horizontal">
<View class="downloadRow horizontal">
<View id="itemDl" onClick="viewItem" class="downloadItem graybg" />
<View class="divider" />
<View class="downloadItem graybg" />
</View>
</View>
<View class="downloadRowContainer horizontal">
<View class="downloadRow horizontal">
<View class="downloadItem graybg" />
<View class="divider" />
<View class="downloadItem graybg" />
</View>
</View>
</ScrollView>
</View>
</Alloy>
Here's the js:
function viewItem(e){
var showItem = Alloy.createController('viewdl').getView().open();
}
It works it opens viewdl.xml but the widget ain't working anymore on viewdl.xml alone.Any idea why?
Here's viewdl.xml(viewdl.js is blank):
<Alloy><Window class="vertical">
<View class="vertical hsize">
<View class="hsize"><Require src="actionbar" type="widget"/></View>
<ScrollView class="container vertical blackbg">
<View class="imgContainer"></View>
<View class="division"></View>
<Label>DOWNLOAD THIS WALLPAPER</Label>
</ScrollView>
</View></Window></Alloy>
Let me elaborate some points which I think are creating issues:
The root of the UI is Window or TabGroup or NavigationWindow/NavigationGroup : So these elements are responsible for opening and closing of the content/container in screen.
You can add some other View or its sub-element(Label,TableView,etc) to a window using add method.
IMO the widget should be added to the main container.
A simple example, let say we want 2 window application.
1st Window has a button which opens 2nd window.
2nd Window has 2 buttons
1st button close the current window.
2nd button loads some other view ( xml file ) to current window.
index.xml
<Alloy>
<Window id="first" layout="vertical" >
<Require src="actionbar" type="widget" />
<Button onClick="openWin2" title="Open" />
</Window>
</Alloy>
index.js
function openWin2() {
Alloy.createController('window2').getView().open({fullscreen:false});
}
window2.xml
<Alloy>
<Window id="second" layout="vertical" >
<Require src="actionbar" type="widget" />
<Button onClick="closeWin" title="Close" />
<Button onClick="loadData" title="Load Data" />
<View id="dynamicView" height="100px" width="100px"></View>
</Window>
</Alloy>
window2.js
function closeWin() {
$.second.close();
}
function loadData() {
$.dynamicView.add(Alloy.createController('dynamicData').getView());
}
dynamicData.xml
<Alloy>
<Label >Winter is coming !!</Label>
</Alloy>
Hope it is helpful.