Url/Link validation - office-ui-fabric

Is there a way for link/url validation in Fabric when a user inputs some value in a TextField without Regex?
public render(): JSX.Element {
// tslint:disable:jsx-no-lambda
return (
<div style={{ padding: '2px' }}>
<TextField
label="Url"
onGetErrorMessage={this._checkIfValid}
/>
</div>
);
}
private _checkIfValid(value: string) {
alert("Test");
}
Link to codepen: https://codepen.io/lipalath/pen/oRaYvJ?editors=1111

Using regular expressions should help you validate for URLs.
public render(): JSX.Element {
// tslint:disable:jsx-no-lambda
return (
<div style={{ padding: '2px' }}>
<TextField
label="Url"
onGetErrorMessage={this._checkIfValid}
/>
</div>
);
}
private _checkIfValid(value: string) {
const regex = new Regexp(/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]#!\$&'\(\)\*\+,;=.]+$/, 'g');
return regex.test(value);
}

Related

how to stop images from rendering on setState

I have images associated with a counter and based on this increment or decrement in counter, a calculation is done and displayed in a text at the bottom.
The problem is that when I render, the images get rendered again and are loaded again and again and again. which I dont want.
If I dont render, the text will not update with the calculated amount.
For the counter I am using react-native-counter.
I have already tried with shouldcomponentupdate, but I want to stop only image rendering, the rest should work.
Please advise.
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Header
backgroundColor="#25D366"
leftComponent={
<Icon
name="menu"
size={40}
color={"#fff000"}
onPress={() => this.props.navigation.openDrawer()}
/>
}
centerComponent={{
text: "Veg & Fruits",
style: {
color: "#ffffff",
fontSize: 25,
fontWeight: "bold",
},
}}
rightComponent={<Icon name="home" color={"#ff0000"} />}
></Header>
/// this is searchbar component,
<SearchBar
fontColor="#ffffff"
fontWeight="bold"
fontSize={20}
iconColor="#c6c6c6"
shadowColor="#ffffff"
cancelIconColor="#c6c6c6"
backgroundColor="#25D366"
placeholder="Search here"
onChangeText={(text) => {
this.setState({ photos: [] });
this.state.search = text;
this.filterList(this.state.search);
console.log("text changed");
}}
onPressCancel={(text) => {
text = "";
//this.filterList(text);
}}
onPress={(text) => {
console.log("rendering");
console.log("now text is: ", this.state.search);
}}
/>
/// in this view images are displayed using functions
<View>
<ScrollView
style={{
height: Dimensions.get("window").height - 200,
}}
>
<View
key={Date.now()}
style={{
flex: 1,
flexDirection: "column",
flexWrap: "wrap",
}}
>
{this.filterList(this.state.search)}
{this._renderImages()}
</View>
</ScrollView>
<CalcText tt={total_num} />
</View>
</div>
);
}
}
class CalcText extends Component {
constructor(props) {
super(props);
this.state = {
ta: 0,
};
}
shouldComponentUpdate(nextProps) {
console.log(nextProps.tt);
if (this.props.tt !== nextProps.tt) {
console.log("changed");
return true;
} else {
console.log("Not changed");
return false;
}
}
render() {
return (
<View style={{ height: 40, backgroundcolor: "ff0000" }}>
<Text style={{ fontSize: 26, fontWeight: "bold" }}>
Total : {this.props.tt}
</Text>
</View>
);
}
}
You can create a TextBox component and split it from ImageComponent. In this way the images will not be bound to the state of the component rendering text, and you can safely change TextBox state and text preventing ImageComponent to re-render.
Edit:
Okei, now i get it. I think you have no possibility to do it like this.
Let's formalize the problem:
<Parent>
<Images calc={functionToCalc} />
<CalcText totalAmount={this.state.totalAmount}/>
</Parent>
functionToCalc is defined in in <Parent> and update parent state, something like:
const funcToCalc = () => {
// when condition occurs
this.setState({
totalAmount : computedAmount
})
}
The state of <Parent> has:
this.state : {
totalAmount: none
}
Whenever condition (buttonClick?) occurs in <Images/> you run functionToCalc update <Parent> state and rerender <CalcText>. Problem here is that also <Images> will be rerender again as all the parent component will be rerender.
this is one of the way to pass info from siblings in React.
You only have a possibility if you want to prevent <Images> rerendering.
Redux or similar libraries for centralize state
You will move the computed calculation in a Store and <CalcText/> will read that from there. <Images/> component will trigger an action modifying that state but won't listen to that so not being rerender.

how can I clear Native-base Input text?

I try this
<Input placeholder="search...."
ref={(ref) => { this.SearchInput = ref; }}
/>
<Button transparent onPress={this.clear}>
<Ionicons name="ios-close" />
</Button>
and function:
clear = () => {
this.SearchInput.clear();
}
I get this error:
this.SearchInput.clear() is not a function
This is the running code, change ref to getRef and use this.SearchInput._root.clear(); instead of this.SearchInput.clear();
clear = () => {
this.SearchInput._root.clear();
}
render() {
return (
<Container>
<Header />
<Content>
<Item floatingLabel>
<Input placeholder="search...."
getRef={(ref) => this.SearchInput = ref}
/>
</Item>
<Button onPress={this.clear}>
<Ionicons name="ios-close" />
</Button>
</Content>
</Container>
);
}
I use value and state to achieve this functionality
here is the example:
<Input
value={ this.state.value }
onChangeText={ this.onTextChange }
/>
<Button onPress={this.clear}>
<Ionicons name="ios-close" />
</Button>
declare default value's value on constructor
this.state = {
value: ''
}
listen to onTextChange as follows, this make sure that the value on Input stay the same as we inserting, not blank forever:
onTextChange = (value) => {
this.setState({ value })
}
finally, on clear function
clear = () => {
this.setState({ value: '' })
}
just set back value to empty
i totally agree with Muhammad Hanzala as it worked for me on this but there is a little exception which is really important which i had to do to make it work be sure to add the reference of the text input to your constructor like this:
constructor()
{
...
this.SearchInput = React.createRef();
}
A full example will look like this in your input element...
<InputgetRef={(ref) => this.SearchInput = ref}/>
in your constructor :
constructor()
{
...
this.SearchInput = React.createRef();
}
and finally you can call:
this.SearchInput._root.clear();
and dont forget to clear your state..

How to use checkbox in loop in react naive

How to use checkbox in loop with diffrent key when i use in loop and click on any one after than check all loop checkbox give me solution
You can create an array of solutions in state:
...
state.solutions = [
{value:false},
{value:false},
{value:false}
]
Create a changes event handler:
changeEvent = (ev, index) => {
let tmp_solution = [...state.solutions];
tmp_solutions[index].value = !tmp_solutions[index].value;
this.setState({solutions: tmp_solution})
}
Create the checkboxes render function:
const checkBoxes = this.state.solutions.map((index) =>{
return(
<CheckBox
value={this.state.solutions[index].value}
onValueChange={(ev) => this.changeEvent(ev, index)} key={index}
/>
)
});
Render all the checkboxes:
render() {
<View>
{checkBoxes}
</View>
}
...
sorry if there are errors
Well, suppose that you have a data, so you can use map to do that. In order to save the answers also you can use index in setSetate as below. I use the react-native-checkbox-heaven component to have the check Box:
import CheckBox from 'react-native-checkbox-heaven';
renderContentCheckBox=()=>{
console.log("[renderContent] your data", this.state.data);
return Object.keys(this.state.data).map(function (item, index) {
return (<View key={index} style={{ alignItems: 'flex-start', justifyContent: 'flex-start', width: Dimensions.get('window').width / 1.1, }}>
<CheckBox
label={item.title}
labelStyle={styles.labelStyle}
iconSize={28}
iconName='matMix'
checked={this.state.check1}
checkedColor='#44FF00'
uncheckedColor='#FFFFFF'
onChange={(val) => {(value) => { that.setState({ ["CheckBox" + index]: value, }); console.log("radio" + index, value);
}}
/>
</View>
);
}
}
Then you can use it inside the render:
render() {
return (<View>
{this.renderContentCheckBox(this)}
</View>
);
}

React Native Pass Firebase Object To Next Page - React Navigation

I have a list of firebase objects in a React Native ListView. Please see the code below.
Importing the data from Firebase:
getDataForFeed() {
var feedPosts = this;
firebase
.database()
.ref("/feedPosts/")
.limitToLast(10)
.orderByChild('sortingTime')
.on("child_added", function(data) {
var newData = [...feedPosts.state.listViewData];
newData.push(data);
feedPosts.setState({ listViewData: newData });
});
}
Rendering the data:
<ListView
enableEmptySections
dataSource={this.ds.cloneWithRows(this.state.listViewData)}
renderRow={data => (
<Card style={{ flex: 0 }}>
<CardItem
button
onPress={data => {
this.props.navigation.navigate("ViewPost", {
subject: data.val().subject //This doesn't work.
});
}}
>
<Body>
<Text small>
{data.val().subject} //This works.
</Text>
</Body>
</CardItem>
</Card>
)}
/>
When I put a string or integer in the "subject" value, it works fine, but when I want the value I need, data.val().subject - it throws this error.
data.val is not a function.
In the text box below, data.val().subject shows just fine.
Please help me get this into the correct format for me to pass it to the next page.
Ok. This is how I did it:
I brought in the data like this:
getDataForFeed() {
var feedPosts = this;
firebase
.database()
.ref("/feedPosts/")
.limitToLast(10)
.orderByChild('sortingTime')
.on("child_added", function(data) {
var newData = [...feedPosts.state.listViewData];
newData.push(data);
feedPosts.setState({ listViewData: newData });
});
}
I made a separate renderRow function instead of doing it inline:
renderRow(data) {
const { navigate } = this.props.navigation;
return (
<Card style={{ flex: 0 }}>
<CardItem
button
onPress={() => {
navigate("ViewPost", data.val());
}
}
bordered
>
</CardItem>
</Card>
);
}
Then I rendered the list like this:
<ListView
enableEmptySections
dataSource={this.ds.cloneWithRows(this.state.listViewData)}
renderRow={this.renderRow.bind(this)}
/>
Then, on the next page, the data is accessed like this:
console.log(this.props.navigation.state.params, "Navigation");
I hope this helps. Comment if you need any clarification.

Conditional Rendering on Items of Native Base Picker [React Native]

I’m using ‘Native Base’ components for our product and going good with this,
but I’m stuck at one point and it is around putting Items in Nativebase Picker. My code is like this
Render Method code -
render(){
return (
<View style={{marginTop: 20, flexDirection:'row', flexWrap:'wrap', justifyContent:'space-around', alignItems:'center'}}>
<View style={{flex:1, justifyContent:'center', alignItems:'flex-end' }}>
<Button
style={{ backgroundColor: '#6FAF98', }}
onPress={this._showDateTimePicker}
>
<Text>Select Date</Text>
</Button>
</View>
<View style={{flex:1, justifyContent:'center', alignItems:'stretch'}}>
<Picker
style={{borderWidth: 1, borderColor: '#2ac', alignSelf:'stretch'}}
supportedOrientations={['portrait','landscape']}
iosHeader="Select one"
mode="dropdown"
selectedValue={this.state.leaveType}
onValueChange={(value)=>this.setState({leaveType:value,})
//this.onValueChange.bind(this)
}>
<Item label="Full Day" value="leave1" />
{
this.showStartDateFirstHalf() // Here I want to show this picker item on the basis of a condition
}
<Item label="2nd half" value="leave3" />
</Picker>
</View>
<DateTimePicker
isVisible={this.state.isStartDatePickerPickerVisible}
onConfirm={this._handleDatePicked}
onCancel={this._hideDateTimePicker}
mode='date'
/>
</View>
);
}
showStartDateFirstHalf()
{
if(!this.state.isMultipleDays)
{
return(
<Item label="1st Half" value="leave2" />
);
}
}
So, this code is working fine if this.state.isMultipleDays is false, But when this.state.isMultipleDays is true, it means when it is in else part then i'm getting this error -
Cannot read property 'props' of undefined
I think there's an easier answer to this. Instead of creating the separate showStartDateFirstHalf() function try this:
render() {
const pickerItems = [
{
label: 'Full Day',
value: 'leave1',
},
{
label: '1st Half',
value: 'leave2',
},
{
label: '2nd Half',
value: 'leave3',
},
];
const filteredItems = pickerItems.filter(item => {
if (item.value === 'leave2' && this.state.isMultipleDays) {
return false;
}
return true;
});
// The 'return' statement of your render function
return (
...
<Picker ...>
{(() =>
filteredItems.map(item =>
<Item label={item.label} value={item.value} />
)()}
</Picker>
...
);
}
That way, you already have a list of items that is determined before the return statement of the render cycle. Also the use of filter instead of map will not just give you null as the second item if the condition is not met, but will remove the item altogether.