Opening SideMenu on button press - react-native-navigation

I'm currently trying to upgrade to react-native-navigation V2 from V1 and got stuck trying to find a way to toggle side menus on top bar button press.
My app starts with
Navigation.setRoot({
root: {
sideMenu: {
left: {
component: {
name: 'testApp.SideDrawer',
passProps: {
text: 'This is a left side menu screen'
}
}
},
center: {
bottomTabs: {
...
}
},
},
},
});
Is there a way to do it in current version?

Turned out you can't use this.props.navigator.toggleDrawer in V2 and should use Navigator.mergeOptions instead to change drawer visibility.
In my case:
1) First assign an Id to the drawer (id: leftSideDrawer)
Navigation.setRoot({
root: {
sideMenu: {
left: {
component: {
name: 'testApp.SideDrawer',
id: 'leftSideDrawer'
}
},
center: {
bottomTabs: {
...
}
},
},
},
});
2) Use it in to change drawer visibility
Navigation.mergeOptions('leftSideDrawer', {
sideMenu: {
left: {
visible: true
}
}
});

You can set a boolean in your component to identify the current state of the side drawer screen and then you can use that boolean to set the visibility of the drawer with mergeOptions. Basically toggle! Below is the snippet to achieve this.
constructor(props) {
super(props);
this.isSideDrawerVisible = false;
Navigation.events().bindComponent(this);
}
navigationButtonPressed({ buttonId }) {
if (buttonId === "openSideDrawer") {
(!this.isSideDrawerVisible) ? this.isSideDrawerVisible = true : this.isSideDrawerVisible = false
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: this.isSideDrawerVisible,
}
}
});
}
}

Related

static passProps not changing on Navigation.push

I am using react-native-navigation v2 from Wix, trying to push a screen to an existing stack. Here is my push code:
Navigation.push(this.props.componentId, {
component: {
name: 'chapel.search'
}
})
And my options object
static options (passProps) {
console.log('Firing static method')
return {
component: {
name: 'chapel.search',
topBar: {
visible: true,
leftButtons: [
{
id: 'back',
testID: 'back',
icon: require('../../Images/back.png')
}
],
title: {
component: {
name: 'chapel.navtitle',
alignment: 'center',
passProps: { text: 'Search' }
}
},
rightButtons: []
}
}
}
}
I never see the log statement and the topbar options do not change. Should they?
When I use Navigation.mergeOptions with the above options object in the constructor of my target screen, the options appear, so this is what I am using for now.
Using android, have not tested with iOS as yet. Will update when I do.
I'm originating static options like this in my component:
static get options() {
return {
...
}
}
And when i push from another screen and want to override some defaults, i do it like below:
Navigation.push(this.props.componentId, {
component: {
name: 'chapel.search',
passProps: {
myProp: myprop1
},
options: {
topBar: {
title: {
text: newTitleOverridingStaticOne
}
}
}
}
});
I don't know if static options (passProps){...} is valid, but you can try like i show above to check if it is resolved

Wix react native navigation v2 gesture (swipe problem)

While navigating to different screens from side menu, I hid the side menu using following code:
Navigation.mergeOptions('Drawer', {
sideMenu: {
left: {
visible: false,
}
}
});
The problem using this approach was change in behavior of swipe gesture. While using gesture to open the menu, it would appear for a instance and close itself. And swipe gesture would only work properly after your click the menu button.
closeSideMenu = ( ) => {
/*For android devices*/
if (Platform.OS === 'android') {
/*disable swipe gesture*/
Navigation.mergeOptions("navigation.playground.menu", {
sideMenu: {
left: {
enabled: false,
},
},
});
/*enable swipe gesture*/
Navigation.mergeOptions("navigation.playground.menu", {
sideMenu: {
left: {
enabled: true,
},
},
});
} else {
/*for iOs devices*/
Navigation.mergeOptions("navigation.playground.menu", {
sideMenu: {
left: {
visible: false,
},
},
});
}
};

Navigation in react-native

This's the homepage
What I want is when i click on the clock icon at the BottomTabNavigator, i have a new page with the features below:
The Tab navigator will be hidden
A new header
possibility to go back (go to the homepage)
I have already fixed the two first point... The third one makes me confused!
Is there someone who can help me ?
"dependencies": {
"expo": "^31.0.2",
"react": "16.5.0",
"react-elements": "^1.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-31.0.0.tar.gz",
"react-native-elements": "^0.19.1",
"react-native-snap-carousel": "^3.7.5",
"react-native-vector-icons": "^6.1.0",
"react-navigation": "^3.0.0"
},
**CODE : **
//Differents Stack Navigators
const AppStackNavigator = createAppContainer(createStackNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
header: < Head / >
}
},
Search: {
screen: Search,
navigationOptions: {
title: "Rechercher",
headerStyle: {
backgroundColor: '#00aced'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
}
}
}
}));
const HoraireStackNAvigator = createAppContainer(createStackNavigator({
Horaire: {
screen: Horaires,
navigationOptions: {
title: "Horaires"
}
}
}))
const PaimentStackNAvigator = createAppContainer(createStackNavigator({
Horaire: {
screen: Paiement
}
}))
//The Principle TabNavigator
const TabContainer = createBottomTabNavigator({
Home: {
screen: AppStackNavigator,
},
Paiement: {
screen: PaimentStackNAvigator,
},
Horaires: {
screen: HoraireStackNAvigator,
navigationOptions: {
tabBarVisible: false
}
}
}, {
initialRouteName: 'Home',
order: ['Paiement', 'Horaires', 'Home', 'Proximite', 'Settings'],
//Default Options for the bottom Tab
defaultNavigationOptions: ({
navigation
}) => ({
tabBarIcon: ({
focused,
horizontal,
tintColor
}) => {
const {
routeName
} = navigation.state;
let iconName;
if (routeName === 'Home') {
iconName = `ios-home${focused ? '' : ''}`;
} else if (routeName === 'Settings') {
iconName = `ios-settings${focused ? '' : ''}`;
} else if (routeName === 'Horaires') {
iconName = `ios-clock${focused ? '' : ''}`;
} else if (routeName === 'Proximite') {
iconName = `ios-locate${focused ? '' : ''}`;
} else if (routeName === 'Paiement') {
iconName = `ios-cart${focused ? '' : ''}`;
}
return <Ionicons name = {
iconName
}
size = {
horizontal ? 20 : 35
}
color = {
tintColor
}
/>;
}
}),
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
tabStyle: {
backgroundColor: '#000'
},
showLabel: false,
showIcon: true
}
})
export default AppTabNavigator = createAppContainer(TabContainer);
React navigation stack provide default go back option its usually based on your stack.
close active screen and move back in the stack using
this.props.navigate("goBack")
this.props.navigate.pop("HomeScreen")
We can also push or navigate to HomeScreen by using
this.props.navigate.navigate("HomeScreen")
this.props.navigate.push("HomeScreen")

How to add sidebar drawer with react native navigation v2?

With react-native-navigation v1 you can set up a drawer like this:
drawer: {
left: {
screen: 'ScreenName'
}
}
In docs of react-native-navigation they mention that drawer is still supported,
but there in no example of its usage. I tried with same way as in v1, but it didn't work. Is there anyone who has achieved it somehow?
In RNN V2 and up you can add Drawer with simply using sideMenu instead of old drawer option Ex :
Navigation.events().registerAppLaunchedListener(() => {
Navigation.setRoot({
root: {
sideMenu: {
id: "sideMenu",
left: {
component: {
id: "Drawer",
name: "navigation.Drawer"
}
},
center: {
stack: {
id: "AppRoot",
children: [{
component: {
id: "App",
name: "navigation.AppScreen"
}
}]
}
}
}
}
});
}
Take a look at this and navigate to sideMenu
and in order to close the drawer use Navigation.mergeOptions and pass visible false like this
<Button onPress={this.hideSideMenu}/>
hideSideMenu() {
Navigation.mergeOptions(this.props.componentId, {
sideMenu: {
left: {
visible: false
}
}
});
}

jTable dynamic custom toolbar item in child table

I have a jTable with a child table for each row. On the toolbar header of the child table I have added a custom toolbar item. I want to make that toolbar item dynamic in the sense that if there are already some rows I do not want it to show. I came across a very similar query for the main toolbar "add new" button which added a function to run on recordsLoaded:
Below is my first attempt - it is just the field entry for the main table that specifies the child table. However the ".find(....)" spec will not work in my case as mine is a custom toolbar item. What do I need to put as the .find criteria?
Thanks
Dance: {
title: '',
width: '4%',
sorting: false,
create: false,
listClass: 'centreCol',
display: function(book) {
var $img = $('<img src="Images/layers.png" title="Show associated dance entries" />');
//Open child table when user clicks the image
$img.click(function() {
var thisrow = $img.closest('tr'); //Parent row
if($('#BookTableContainer').jtable('isChildRowOpen',thisrow)) { // Clicking image a second time closes the child row
$('#BookTableContainer').jtable('closeChildRow',thisrow);
} else {
currentTitleID = book.record.DanceTitleID;
$('#BookTableContainer').jtable(
'openChildTable',
thisrow,
{
title: 'Related Dance',
toolbar: {
items: [
{
icon: 'Images/add.png',
text: 'New dance',
tooltip: 'Add dance details',
click: function() { CreateDanceDialog(); }
}
]
},
actions: {
listAction: 'BookPageData.php?action=listChildDances&DanceTitleID=' + currentTitleID,
// createAction: 'dancesData.php?action=createAssignment',
// deleteAction: 'dancesData.php?action=deleteAssignment'
},
recordsLoaded: function(event, data) {
var rowCount = data.records.length;
if (rowCount>0){
$('#BookTableContainer').find('.jtable-toolbar-item.jtable-toolbar-item-add-record').remove();
}
},
fields: {
DanceID: { key: true, create: false, edit: false, list: false, visibility: 'hidden' },
DanceTitleID: { type: 'hidden', defaultValue: currentTitleID },
ChoreographerID: { title: 'Choreographer', width: '40%', options: function() { return ChoreographerOptions; } },
FormationID: { title: 'Formation', width: '30%', options: function() { return FormationOptions; } },
GenreID: { title: 'Genre', width: '30%', options: function() { return GenreOptions; } }
}
},
function(data) { data.childTable.jtable('load'); }
);
}
});
//Return image to show on the person row
return $img;
}
},
Try this
$('#BookTableContainer').find('.jtable-toolbar').remove();

Resources