Can I specify a separate onClick handler for TextField's icon? - office-ui-fabric

Using component, can I specify a separate onClick handler for a decoration icon?
The code below is not working:
<TextField
{...passwordTextFieldProps}
iconProps={{ iconName: 'RedEye', onClick: () => this.setState({ some new state }) }}
/>

Two years after the author of this post I had the same question and found a better solution.
The onClick event is available on the icon but is disable by default (pointerEvents is set to none).
With some styling it works (also I added a cursor shape so the icon looks "clickable" but it's optional).
<TextField iconProps={{ iconName: 'RedEye', style: { pointerEvents: "auto", cursor: "pointer" }, onClick: () => { ... } }} />

One option to consider would be to render an icon separately:
<div style={{display:'flex', alignItems: 'center'}}>
<TextField />
<Icon iconName="RedEye" style={{left:'-25px',position:'relative'}} onClick={()=> console.log("Clicked")} />
</div>
Demo

Related

menuPortalTarget doesn't not work if react-select dropdown opens inside modal

I have a problem react-select dropdown opens inside modal
Below is my coding:
<Select
styles={{
menu: provided => ({ ...provided, zIndex: 9999 })
}}
options={optionsHour}
value={{ label: durationHour, value: durationHour }}
onChange={(e) => { setDurationHour(e.value) }}
>
</Select>
This one is the current result, it cannot show react_select dropdown over modal.
I tried the below code with using menuPortalTarget, but it also cannot work.
<Select
styles={{
menu: provided => ({ ...provided, zIndex: 9999 })
}}
menuPortalTarget={document.body}
options={optionsHour}
value={{ label: durationHour, value: durationHour }}
onChange={(e) => { setDurationHour(e.value) }}
>
</Select>
Below result is what I've tried:
Actually, I want the result like below the picture:
Hope someone can guide me on how to solve it. Thanks.

How to add an expression and an arrow function to onPress in react native?

I am trying to create a TouchableOpacity that executes another function and an arrow function, but cannot figure out a way to do so. Here is my code:
<SubmitButton
text="NEXT"
style={{ backgroundColor: "#093968" }}
onPress={
(handleSubmit,
() => this.setState({ submitPressed: true }))
}
/>
I understood that the second function is overriding the first, but how do I solve this problem. And I also don't want to add the arrow function to handleSubmit.
You can do:
<SubmitButton
text="NEXT"
style={{ backgroundColor: "#093968" }}
onPress={()=>{
handleSubmit()
this.setState({ submitPressed: true })
}}
/>

Onpress with conditional will not call a function

I have some problem with onPress button function,
if I create button and calling function directly it work well,
but if I'm using conditional it will not call the function.
I already create 2 button below to simulate, button with title "submit normal" can call function and pass the property successfully, button with title "submit conditional" will not calling this.makeRemoteRequest.bind(this); but if you put alert it will react normally, nothing happen if calling a function.
<Input
containerStyle={{ width: '90%' }}
placeholder="Predefined User ID"
label="User ID"
labelStyle={{ marginTop: 16 }}
editable={false}
value={this.state.userid}
onChangeText={input_user_id => this.setState({ input_user_id })}
/>
<Input
containerStyle={{ width: '90%' }}
placeholder="Please fill services request notes here"
label="Reason"
labelStyle={{ marginTop: 16 }}
onChangeText={input_services_detail => this.setState({ input_services_detail })}
/>
<Button
title='Submit Conditional'
onPress={() => {
if (this.state.input_services_detail != null)
{
this.makeRemoteRequest.bind(this);
}
else
{
Alert.alert('Please fill the service detail first');
}
}}><Text style={styles.buttonText}>Submit Aset</Text>
</Button>
<Button
title='Submit Normal'
onPress={this.makeRemoteRequest.bind(this)}><Text style={styles.buttonText}>Submit Aset</Text>
</Button>
</View>
Expecting to call a function using conditional. Appreciate if somebody can brief me on this. Thanks before.
I would say this is kind of a bad practice to achieve this behaviour.
A better way to write it would be like this -
<Button
title='Submit Conditional'
onPress={this.onPressSubmitButton.bind(this)}>
<Text style={styles.buttonText}>Submit Aset</Text>
</Button>
Changed the name of the onPress function to onPressSubmitButton
And the onPressSubmitButton function -
onPressSubmitButton() {
if (this.state.input_services_detail === null) {
return Alert.alert('Please fill the service detail first')
}
this.makeRemoteRequest()
}
I think it more clear to read and understand.
Also you can write the function signature like this -
onPressSubmitButton = () => {
...
}
which make it bound already, this way you can call it like this -
<Button
title='Submit Conditional'
onPress={this.onPressSubmitButton}>
<Text style={styles.buttonText}>Submit Aset</Text>
</Button>
You're not calling this.makeRemoteRequest in your condition, you're just binding it. Change your conditional onPress prop like this :
onPress={this.state.input_services_detail != null ? this.makeRemoteRequest.bind(this) : () => Alert.alert('Please fill the service detail first')}
And you don't need the != null :
onPress={this.state.input_services_detail ? this.makeRemoteRequest.bind(this) : () => Alert.alert('Please fill the service detail first')}

How to programmatically select text in a TextInput component

Is there a way to programmatically highlight/select text that is inside a TextInput component?
You can use selectTextOnFocus to achieve this. This will ensure that all text inside the TextInput is highlighted when the field is tapped into.
Actually you can, by accessing textInput's method by refs.
<TextInput ref={input => this.myInput = input} selectTextOnFocus style={{height: 100, width: 100}} defaultValue='Hey there' />
and where you want to select all text programmatically you can
this.myInput.focus()
works on iOS, not sure about android.
Reference : http://facebook.github.io/react-native/releases/0.45/docs/textinput.html#selectionstate
I don't know if there's a better way, but I found a workaround. The text has to be focused first. Here's an example
import React { Component } from 'react';
import { Button, TextInput, findNodeHandle } from 'react-native';
import TextInputState from 'react-native/lib/TextInputState';
class MyComponent extends Component {
render() {
return (
<View style={{ flex: 1, }}>
<Button
title="select text"
onPress={() => {
TextInputState.focusTextInput(findNodeHandle(this.inputRef))
}}
</
<TextInput
selectTextOnFocus
ref={ref => this.inputRef = ref}
/>
</View>
);
}
}
I'm here to share my findings. In a List, you might encounter that selectTextOnFocus is broken. In this case you can use this method selection. From React-Native I found this:
In my case I had trouble with the selectTextOnFocus prop in a list. So I had to add a debounce function to work with selection prop.
const [shouldSelect, setShouldSelect] = useState(undefined);
const onFocus = () =>{
setShouldSelect({start:0, end:String(text).length});
}
const focus = useCallback(_.debounce(onFocus,500),[shouldSelect]);
<TextInput
selection={shouldSelect}
onBlur={()=>setShouldSelect(undefined)}
onFocus={()=>focus()}// this is important
selectTextOnFocus
ref={r=>onRef(r)}
keyboardType={'number-pad'}
autoCorrect={false}
blurOnSubmit={false}
returnKeyType={'done'}
underlineColorIos={'transparent'}
underlineColorAndroid={'white'}
allowFontScaling={false}
value={String(text)}
/>
this.inputRef.focus() sets focus to the TextInput component, and then the flag you set in the attributes selectTextOnFocus does the rest.
Note: For those who wants to use selectTextOnFocus short answer. Actually, it works fine in IOS, but doesn't work in Android.
Thanks to Arnav Yagnik; Following is a similar approach in a functional component:
const inputRef = React.useRef(null);
React.useEffect(() => {
if (inputRef.current) {
console.log('focusing !');
inputRef.current.focus();
}
}, []);
return <TextInput
multiline
label="Amount"
selectTextOnFocus
placeholder="Write Count"
value={stockCount.toString()}
/>

Implementing Footer Tabs in Native React using Native Base

I am creating a native react application using native base for the UI (http://nativebase.io/docs/v2.0.0/components#footerTab). I am using the footerTabs component and my code is as follows
render() {
return (
<Container>
<Header backgroundColor="#ECEFF1">
<Button transparent>
<Icon name='ios-menu' style={{color: 'black'}}/>
</Button>
<Title style={{color:'black'}}>Header</Title>
</Header>
<Content>
<Profile/>
</Content>
<Footer backgroundColor="#212121">
<FooterTab>
<Button backgroundColor="#000" >
<Icon name="ios-person" size={30} color="#900"/>
<Text>Profile</Text>
</Button>
<Button>
<Icon name="ios-search"/>
<Text>Search</Text>
</Button>
<Button>
<Icon name="ios-camera"/>
<Text>Camera</Text>
</Button>
<Button>
<Icon name="ios-apps"/>
<Text>Apps</Text>
</Button>
<Button>
<Icon active name="ios-navigate"/>
<Text>Navigate</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
I have created different JS files for different functionalities such as Profiles,Search,Apps ect.. and have imported them as follows.
import Profile from './Profile';
How do I implement the onPress functionality on the buttons of the footer to change the component in the content tag depending on what was selected?
<Content>
<Profile/>
</Content>
For eg: If I pressed the search button I want the profile tag to be replaced with and similarly the same for the other buttons.
Here FooterTab from native base is not persist actual tab functionality like UITabBar in iOS, its only persist for design. What you need to do is, keep footer tag in all of your component with all four buttons and keep active accordingly. For changing view by selecting any button you need to replace current view by selected one using navigator like:
<Button onPress={()=> { this.props.navigator.replace({id:'component name'}) }}>
and in your navigator component you should define all required components in renderScene method on the basis of id value in route payload. If you want actual functionality as TabBar work then you can use this third party module react-native-tab-navigator. Thanks!
Instead of replacing the content, why don't you have each Button navigate to a new page?
Let's say you're on the Profile tab. You could do something like this:
import FooterWrapper from './FooterWrapper'
<Footer>
<FooterWrapper tab='profile' navigator={this.props.navigator} />
</Footer>
And then in your FooterWrapper (I just handled a case of two tabs):
constructor(props) {
super(props)
this.state = {
profileTab: this.props.tab === 'profile',
searchTab: this.props.tab === 'search',
}
}
navToProfilePage() {
this.props.navigator.push({
id: 'profile',
tab: 'profile',
})
}
navToSearchPage() {
this.props.navigator.push({
id: 'search',
tab: 'search',
})
}
render() {
return (
<FooterTab>
<Button active={this.state.profileTab} onPress={() => this.navToProfilePage()}>
Profile
<Icon name='ios-person' size={30} color='#900' />
</Button>
<Button active={this.state.searchTab} onPress={() => this.navToSearchPage()}>
Search
<Icon name='ios-search' />
</Button>
</FooterTab>
)
}
Ok so here is I how got it I used the renderContent method within the content tags to generate views depending on the state change when the button was clicked.
<Content>
{this._renderContent(this.state.selectedTab)}
</Content>
The selectedTab is a state variable whose state is set using this.setState in the onPress method. The renderContent has an if function that checks the selected tab and returns the appropriate view. I also tried the navigation approach but this seemed cleaner.
_renderContent = (Tab: string,) => {
if(this.state.selectedTab==="Profile"){
return (
<Profile/>
);
}
else if(this.state.selectedTab==="Search"){
}
}