Can anyone help me how to use onChange props in react native scrollable tab view?
Any sample code?
Basically I want to fetch data, when tab is changed.
<View style={styles.container}>
<ScrollView>
<ScrollableTabView>
<OverViewPage tabLabel = "Overview" contentProps = { this.state = {data : this.state.data , addressDetails : this.state.addressDetails }} />
<OverViewPage1 tabLabel = "OverView1"/>
<OverViewPage2 tabLabel = "OverView2" />
</ScrollableTabView>
</ScrollView>
</View>
When I go to OverView1 scene I want to fetch data from api and rendered the information returned. Basically I want to catch an event, when tab is changed.
I found there is an onChange props but couldnt figure it out how to use.
Appreciate the help!!
Thank you!!
ScrollableTabView don't pass state of tab state to children tab screens. Instead, in onChangeTab prop of ScrollTabView you can set state in your parent React class and pass new state to children tab screens about active tab as properties. Something like following:
<ScrollableTabView onChangeTab={(event)=>{this.setStateForTabChange(event.i)}}>
<Scene1 isActive={this.state.isSceneOneVisible} />
<Scene2 isActive={this.state.isSceneTwoVisible} />
</ScrollableTabView>
You can define setStateForTabChange which will eventually will set state values for scene active states based on index value sent by onChangeTab.
Related
I have a simple TabView like this using NativeScript w/angular:
<TabView [(ngModel)]="tabSelectedIndex" height="300px" (selectedIndexChanged)="onSelectedIndexChanged($event)">
<StackLayout *tabItem="{title: 'Tab 1'}">
<Label text="Content in Tab 1"></Label>
</StackLayout>
<StackLayout *tabItem="{title: 'Button 1'}">
<!-- these won't be content here because clicking this should not change to a another tab, but instead should do something else. -->
</StackLayout>
<StackLayout *tabItem="{title: 'Tab 2'}">
<Label text="Content in Tab 2"></Label>
</StackLayout>
</TabView>
I want a button in the tab bar that doesn't change the view, but instead does something else (such as open a modal dialog).
I tried a new <StackLayout> both inside and outside of <TabView>.
I also tried using an <AbsoluteLayout>. All methods caused the app to crash.
Is it possible to capture the tab view change using selectedIndexChanged and prevent the change?
I tried stopPropagation() on the event but got error:
Property 'stopPropagation' does not exist on type 'SelectedIndexChangedEventData'.
I tried changing the view back to the view that existed when the middle button was clicked, but there is a noticeable flicker because the view has to change before this event is even fired. What would have been acceptable is something like onSelectedIndexWill Change but that method does not exist.
onSelectedIndexChanged(args: SelectedIndexChangedEventData) {
if (args.newIndex === 1) { //the middle button
setTimeout(() => {
tabView.selectedIndex = args.oldIndex; //go back to the previous view (causes flicker)
//do stuff for the button click.
});
}
}
Or is there another way to incorporate a button in the tab bar that doesn't link to a new view?
Or should I not implement a native tab bar and instead just create a navigation bar from scratch?
Here's how it can be done for ios.
Here is a sample app in NativeScript playground showing the issue. Click center link to see the flicker.
Do to the fact that the NativeScript team has refused to export the delegates this is not something you can monkey patch in at this point. The only way to do this is to fork the TabView code and create your own plugin using it.
However, making this change should be fairly simple once you have your forked copy. You just need to on around line 64 public tabBarControllerShouldSelectViewController(tabBarController: UITabBarController, viewController: UIViewController): boolean {
You just need to detect which viewController it is trying to load; and then return false in the case where you don't want to actually change the view. ;-)
Two possible ways;
check the owner.selectedIndex; I believe it should be pointing to the proper new index at this point;
however if it is not then the second possible method would be to check the viewController against the owners viewcontroller list (i.e. const selectedIndex = owner._ios.viewControllers.indexOfObject(viewController); )
How do I show Keyboard for TextInput programmatically using react native? Using a ScrollView, tapping between TextInput causes the keyboard to be dismissed. I want to show the Keyboard again using onFocus method of TextInput. Anyway to accomplish this?
consider have a reference of your textInput :
<TextInput ref={(ref)=>{this.myTextInput = ref}} />
And when you have to focus it again use : this.myTextInput.focus()
edit React16
For react16 use React.createRef to create a reference.
Your ScrollView needs to include the keyboardShouldPersistTaps prop:
<ScrollView keyboardShouldPersistTaps></ScrollView>
Without ScrollView works only on ios.
Place this component around the code you need the keyboard to appear on:
<ScrollView keyboardShouldPersistTaps='always'>
</ScrollView>
link: https://reactnative.dev/docs/scrollview#keyboardshouldpersisttaps
This is my code for the nav page which picks up all the props from the index page fine. But the nav page has a navigator component and it seems unable to pass through the props from a simple state to the initial route page in the navigator.
var MainPage = React.createClass({
render () {
return (
<NavigatorIOS ref="nav" style={styles.container} titleTextColor='#FFFFFF' barTintColor='#061009' tintColor='#ECCB2B' navigationBarHidden={true}
initialRoute={{
component:HomePage,
title: 'Home Page',
passProps: {
language:this.props.language
}
}} />
);
}
});
I click a button to call a function located on the index page to update the state there and the result will pass through to the home page but not to the initial route navigator page. this.props.language updates on the home page but not on the second page where it is being activated. The value itself is there, its not null, it just never changes.
Functions are passed through ok, its just not updating on the fly. So when I click whilst on the initial route navigator page to change the language, the language changes for the tab bar index page ok but does not update in the initial route navigator page.
I am new to React Native. I have an app with a ScrollView component and several custom components inside it. I would like to trigger an onPressOut event from the ScrollView, so that when the user scrolls, and releases, the child components inside the ScrollView update their states. But, the ScrollView documentation does not include any press events: https://facebook.github.io/react-native/docs/scrollview.html
Other things I tried:
I tried wrapping the scrollview inside a TouchableWithoutFeedback component, when I do this, I get an error as soon as I try to scroll:
2015-10-26 11:59:13.849
[error][tid:com.facebook.React.ShadowQueue][RCTModuleMethod.m:60]
Argument 0 (NSNumber) of RCTUIManager.measure must not be null
2015-10-26 11:59:13.850 [error][tid:com.facebook.React.ShadowQueue][RCTModuleMethod.m:60]
Argument 0 () of RCTUIManager.measure could not be processed.
Aborting method call.
No idea what that means...
Any ideas? Thanks!
Here is my code:
<View ref="theWrapperView" style={styles.theWrapperView}>
<ScrollView
onScroll={this.onScroll.bind(this)}
onMomentumScrollEnd={this.onScrollAnimationEnd.bind(this)}
style={styles.scrollView}
contentContainerStyle={styles.scrollViewContentContainer}
showsHorizontalScrollIndicator={true}
scrollEventThrottle={10}
pagingEnabled={true}
horizontal={true}
automaticallyAdjustContentInsets={false}
snapToAlignment={'center'}
snapToInterval={20}
zoomScale={1.5}
centerContent = {true}
>
{cards}
</ScrollView>
</View>
When I change the View element to a TouchableWithoutFeedback element is when I get the error.
I have figured this out after investigating the React Native source code: https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollResponder.js
As it turns out there are actually a number of other events available via the ScrollResponder mixin, that are not mentioned in the online documentation. It is not necessary to include the mixin to access these events, since they are already part of the ScrollView component. The one that was useful for me was onResponderRelease, which fires when you release the ScrollView, like so:
<View ref="theWrapperView" style={styles.theWrapperView}>
<ScrollView
onScroll={this.onScroll.bind(this)}
onMomentumScrollEnd={this.onScrollAnimationEnd.bind(this)}
onResponderRelease = {this.onResponderReleaseHandler.bind(this)}
>
{cards}
</ScrollView>
</View>
and in the class define a handler:
onResponderRelease(){
//do stuff
}
onTouchEnd will help you to get this
<ScrollView contentContainerStyle={{ paddingHorizontal: 22, top: -16 }}
onTouchEnd={(e) => {
//Here define your ScrollView Press Event
}}
>
{this.props.children}
</ScrollView>
I am using Primefaces 5 and use which has severl tabs.
In each tab I have a dataTable which either can be in editable or not depending to user action.
I want to stay in the same tab and prevent tab change if user is editing a row, otherwise go to the clicked tab. How should i do it ??
This is my xhtml :
<p:tabView id="customerTab"
orientation="left"
dynamic="false"
cache="false"
widgetVar="detailsTab"
activeIndex="#{myBean.activTab}"
>
<p:ajax event="tabChange" listener="#{myBean.onTabChange}" update="customerTabv" />
<p:tab tab1> </p:tab>
<p:tab tab2> </p:tab>
This is my backing bean:
public void onTabChange(
TabChangeEvent event) {
if (Tab.isInEditMode()) {
FacesMessage msg = new FacesMessage("Tab Changed", "Active Tab: " + event.getTab().getId()
+ "You can not change the tab when you are in Edit mode!");
FacesContext.getCurrentInstance().addMessage(null, msg);
this.messagesTab.setActiveIndex(0);
// // RequestContext.getCurrentInstance().execute("tabWidget.select(0)");
activTab = 0;
FacesContext.getCurrentInstance().setProcessingEvents(false);
} else {
TabView tabView = (TabView) event.getComponent();
int activeIndex = tabView.getChildren().indexOf(event.getTab());
this.messagesTab.setActiveIndex(activeIndex);
activTab = activeIndex;
}
}
The solution in short boils down to this:
In the onstart of the rowEditInit ajax event, set a client-side variable that you are in edit mode
In the oncomplete of the rowEditCancel event, set the client-side variable that your are in a non-edit mode
In the oncomplete of the rowEdit event, set the client-side variable that your are in a non-edit mode
In the onstart of the tab change event, write some javascript that checks for the value of this edit variable and if in edit mode, return false. The tabChange should not happen then. If in non-edit mode, return true and the tabChange happens
Sorry, I do not write an answer for you with a fully working example. This is mainly because I do not want to/have the time to write it (never used inline editing myself for complexity reasons like this) AND think that people 'learn' more from hints then fully worked out code.
I had a lot of problems with tabView and nested dynamic elements like dataTable in it. So I use the tabView now only as trigger. This means the tabView has tabs but inside the tabs are not elements. I react with ajax listener to tab changes and update a specific area in my UI which shows the content that should be inside the tab.
For your problem this could be a solution. You can ignore the tab change event when the dataTable is edited.
Or disable the other tabs with tab disabled attribute.
My solution was some javascript. In order to stop tabchange:
<p:tabView id="tabView" activeIndex="#{controller.tabSelected}" onTabChange="handleTabChange(index);return false;"
Check primefaces_user_guide_6_2 for the handleTabChange function.
I also needed p:remoteCommand to send the new selected tab to the bean.