I have a statu structure array that is called 'devices'. It has ID (item ID), name (item name), renew (string value from DDL), and check (boolean value, whether the checkbox is checked or not)
These information will be displayed as items one by one.
While I don't have problem displaying name and ID, My problem is actually on both renew and check, but I want to solve check first.
I have tried the following on the checkbox:
<CheckBox
checked={item.check}
onPress ={ () =>{
if (item.check === false){
item.check = true
}
else {
item.check = false
}
}}
/>
(I use item instead of this.state.devices, because i mapped the array)
This one is where i created devices:
constructor() {
super();
this.state = {
devices: [
{
check: false,
name: 'PHONE',
id: '01658',
renew: '',
},
{
check: false,
name: 'PHONE',
id: '04523',
renew: ''
},
{
check: false,
name: 'LAPTOP',
id: '04451',
renew: ''
},
{
check: false,
name: 'PHONE',
id: '01165',
renew: ''
},
{
check: false,
name: 'TABLET',
id: '01015',
renew: ''
},
]
};
}
This is where the array map start and where I made the checkbox:
render() {
return (
<ScrollView style={styles.container}>
{this.state.devices.map((item, index) => {
console.log("start");
return (
<React.Fragment key={index}>
<View style={styles.itemRow}>
<View style={styles.itemCell}>
<CheckBox
checked={item.check}
onPress ={ () =>{
if (item.check === false){
item.check = true
}
else {
item.check = false
}
}}
/>
</View>
I expected the checkbox to change its value when pressed, and then the boolean value will be written on item.check of the respective index. What happened are either the checkbox value changed all at once as a group; or the value wont change at all.
You have to do a setState to update the checkbox. For example, you could do something like:
onPress={()=>this.handleCheck(item.id}
where handleCheck is:
handleCheck = (id) => {
let tempArr = this.state.devices
let updatedArr=tempArr.map(item => {
if (item.id === id) {
item.check = !item.check
return item
}
return item
})
this.setState({devices:updatedArr})
}
Related
React-native switch toggle is not working even though i have set value for each feild separately.Also Its setting value correctly but toggle switch is not reflecting that.I want if user selects 2 field's the switch button should be enabled for that particular field's and others will be disabled.
const SystemInformation = props => {
const [isEnabled, setIsEnabled] = useState(false);
const [selectedFeild, setSelectedFeild] = useState([
{ id: 1, text: "Entry", toggle: false },
{ id: 2, text: "Exit", toggle: false },
{ id: 3, text: "Stay", toggle: false }
]);
const toggleSwitch = type => {
setSelectedFeild(type);
setIsEnabled(previousState => !previousState);
};
const renderWordList = () => {
const wordList = selectedFeild.map((word, i, wordArray) => (
<View key={word.id} style={styles.wordsContainer}>
<TextView>{word.text}</TextView>
<Switch
style={styles.pilgrimsWordSwitch}
onValueChange={toggleValue => {
wordArray[i].toggle = toggleValue;
setSelectedFeild(wordArray);
}}
value={word.toggle}
/>
</View>
));
return wordList;
};
return <View style={styles.container}>{renderWordList()}</View>;
};
export default SystemInformation;
Any lead will be appreciated what i am doing wrong ?
I'm working on a react-admin page where I want to display some filters depending on the values of another one. To do so, I'm using the filterValues from the ListContext and simply show/hide the dependant filters:
const PostFilter = (props) => {
const { filterValues } = useListContext();
const { mainType } = filterValues;
return (
<Filter {...props}>
<SelectInput
source="mainType"
alwaysOn
choices={[
{ id: "type_1", name: "Type 1" },
{ id: "type_2", name: "Type 2" },
{ id: "type_3", name: "Type 3" }
]}
/>
{mainType === "type_1" && (
<SelectInput
source="type1"
alwaysOn
choices={[
{ id: "type_1_a", name: "A" },
{ id: "type_1_b", name: "B" },
{ id: "type_1_c", name: "C" }
]}
/>
)}
{mainType === "type_2" && (
<SelectInput
source="type2"
alwaysOn
choices={[
{ id: "type_2_a", name: "A" },
{ id: "type_2_b", name: "B" },
{ id: "type_2_c", name: "C" }
]}
/>
)}
</Filter>
);
};
This visually works fine but if I choose a value in one of the child filter and then change the main filter, the url is still containing the filter value even though it's not on screen anymore. As the url contains a wrong filter, then the list is not filtered properly.
To workaround this, I played with a useEffect and the setFilters function but it feels super hacky:
const { filterValues, displayedFilters, setFilters } = useListContext();
const { mainType } = filterValues;
// we need this workaround because these 3 values are not stable
// and get be used as the effect dependencies. However, we still want to be sure
// to always reference their latest version
const refs = React.useRef({ filterValues, displayedFilters, setFilters });
React.useEffect(() => {
refs.current = { filterValues, displayedFilters, setFilters };
});
React.useEffect(() => {
const filters = { ...refs.current.filterValues };
if (mainType !== "type_1") {
delete filters.type1;
}
if (mainType !== "type_2") {
delete filters.type_2;
}
refs.current.setFilters(filters, refs.current.displayedFilters);
}, [mainType]);
Here's a sandbox showing the result: https://codesandbox.io/s/hidden-mountain-i62p3?file=/src/posts.js
Is there a better way to achieve what I want?
I put the label and value value in the CircleCheckBox to the selectedCheckbox state. When I get the output selectedCheckbox, it looks like this: {"label": "Commercial Vehicle", "value": 1}. How can I get the label value here?
class AdjustAdressScreen extends Component {
constructor(props) {
super(props);
this.state = {
checkboxValue: [
{
label: "1 AraƧ",
value: 1
},
{
label: "2 AraƧ",
value: 2
}
]
};
selectedCheckbox: {}
CheckMe = selectedCheckbox => {
this.setState({ selectedCheckbox }); // update selected item
};
render() {
const { checkboxValue, selectedCheckbox } = this.state;
{checkboxValue.map((option, indexInArray) => {
return (
<CircleCheckBox
key={option.value}
checked={option.value === selectedCheckbox.value} // for current element
onToggle={(value, index) => this.CheckMe(option)} // pass index of toggled element
labelPosition={LABEL_POSITION.RIGHT}
label={option.label}
innerColor= {'red'}
outerColor = {'gray'}
filterSize = {15}
styleLabel={{ fontSize: 14, fontFamily : 'Gilroy-Light' }}
/>
);
})}
);
}
Actual Behaviour :
I'm loading a dynamic form in a FlatList and I'm supposed to add few rows with TextInputs based on a condition. For example, I have a checkbox. When I check the checkbox, I have to add a dropdown and two TextInputs and when I uncheck the checkbox, I have to remove these three. My issue is that when I check the checkbox and enter some value in the TextInputs and uncheck the checkbox, then the value in the last TextInput is getting assigned to another TextInput which is not related to these conditions.
Expected Behaviour :
The last TextInput value should not get assigned to another TextInput which is not related to checkbox conditions on unchecking the checkbox.
Here is my code for the TextInput :
_onChangeText(e, item, index) {
console.log("abc123 ", item);
let count = "false";
let note;
if (this.state.inputsValues.length === 0 && item.blocks.question !== undefined) {
if (item.blocks.question.prompt !== "Notes") {
note = {
note: e.nativeEvent.text.replace(/\n/g, ''),
id: item.blocks.question.prompt
};
} else {
note = {
note: e.nativeEvent.text.replace(/\n/g, ''),
id: item.blocks.block_pos
};
}
this.setState({ inputsValues: [...this.state.inputsValues, note] }, () => {
console.log("length === 0", this.state.inputsValues);
});
} else {
this.state.inputsValues.map((res, idx) => {
if (item.blocks.question !== undefined && res.id === item.blocks.question.prompt) {
res.note = e.nativeEvent.text.replace(/\n/g, '');
count = "true";
}
});
if (count === "false") {
if (item.blocks.question.prompt !== "Notes") {
note = {
note: e.nativeEvent.text.replace(/\n/g, ''),
id: item.blocks.question.prompt
};
} else {
note = {
note: e.nativeEvent.text.replace(/\n/g, ''),
id: item.blocks.block_pos
};
}
this.setState({ inputsValues: [...this.state.inputsValues, note] }, () => {
// console.log("gvrtgrtgt", this.state.inputsValues);
});
}
}
}
<NBTextField
itemStyles={[styles.itemStyles, { height: width / 6 }]}
value={inputsValues[index] !== undefined && inputsValues[index].note}
onEndEditing={e => this._onChangeText(e, item)}
onChangeText={this.getInputValue}
onSubmitEditing={() => Keyboard.dismiss()}
inputStyles={[styles.inputStyles, { height: width / 6 }]}
placeholder="Enter here"
/>
Environment :
react-native : 0.61.1
Screenshot :
Below code works for me in mycase
_onChangeText(e, item, index) {
if (item.blocks.block_type === 'question') {
this.state.mainData[index].answer = e.nativeEvent.text;
this.setState({
mainData: this.state.mainData,
});
}
}
<NBTextField
itemStyles={styles.itemStyles}
value={item.answer}
onEndEditing={e => this._onChangeText(e, item, index)}
onChangeText={e => this.getInputValue(e, item, index)}
onSubmitEditing={() => Keyboard.dismiss()}
inputStyles={styles.inputStyles}
/>
I want to select only one checkbox, not multiple.
If i select two checkboxes one by one the previously selected checkbox should be unselected.
In my below code i can select multiple checkboxes.
import React ,{Component} from "react";
import CircleCheckBox, {LABEL_POSITION} from "react-native-circle-checkbox";
class Select_Delivery_Option extends React.Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
});
this.state = {
check_data:[],
dataSource: ds.cloneWithRows([]),
checked:false,
isLoading:false,
};
}
//I had call The componentDidMount for json Data here and bind it in Data source;
render() {
return ();
}
_renderRow(rowData: string, sectionID: number, rowID: number) {
return (
<View style={{ flex:1,flexDirection:'column',backgroundColor:'#FFF'}}>
<View style={{ flex:1,flexDirection:'row',backgroundColor:'#FFF'}}>
<View style={{flexDirection:'column',margin:10}}>
{rowData.adbHomeAddress}
<CircleCheckBox
checked={rowData.checked}
onToggle={()=>this._onPressRow(rowID, rowData,rowData.checked)}
labelPosition={LABEL_POSITION.LEFT}
label={rowData.Address1 +" ,\n "+ rowData.Address2 +",\n"+rowData.ctiName+", "+rowData.staName+", "+rowData.ctrName+","+rowData.adbZip+"."}
innerColor="#C72128"
outerColor="#C72128"
styleLabel={{color:'#000',marginLeft:10}}
/>
</View>
</View>
</View>
);
}
_onPressRow = (rowID,rowData,checked) => {
const {check_data,filter} = this.state;
console.log('rowdata',rowData);
console.log('rowid',rowID);
console.log('checked',checked);
rowData.checked = !rowData.checked;
var dataClone = this.state.check_data;
dataClone[rowID] = rowData;
this.setState({check_data: dataClone });
}
}
Link to the CircleCheckBox component used: https://github.com/paramoshkinandrew/ReactNativeCircleCheckbox
I had the same requirement and wasted hours looking for solution. Eventually, I was able to resolve the problem on my own.
Posting my answer below, l have used hooks in the example, let me know if someone wants a class-based solution.
const checkboxComponent = () => {
const [checkboxValue, setCheckboxValue] = React.useState([
{ label: 'Customer', value: 'customer', checked: false },
{ label: 'Merchant', value: 'merchant', checked: false },
{ label: 'None', value: 'none', checked: false },
])
const checkboxHandler = (value, index) => {
const newValue = checkboxValue.map((checkbox, i) => {
if (i !== index)
return {
...checkbox,
checked: false,
}
if (i === index) {
const item = {
...checkbox,
checked: !checkbox.checked,
}
return item
}
return checkbox
})
setCheckboxValue(newValue)
}
return (
<View>
{checkboxValue.map((checkbox, i) => (
<View style={styles.checkboxContainer} key={i}>
<CheckBox
value={checkbox.checked}
onValueChange={(value) => checkboxHandler(value, i)}
/>
<Text style={styles.label}>{checkbox.label}</Text>
</View>
))}
</View>
)
}
export default checkboxComponent
I suggest you to use FlatList instead of ListView it's more advance and easy to use component.
For your issue please create a state checkedItem: -1 and directly assign id of your item you check last then just add a check to your CircleCheckBox item. something like below code.
<CircleCheckBox
checked={rowData.id === this.state.checkedItem}
onToggle={(rowID)=> this.setState({ checkedItem: rowID})}
labelPosition={LABEL_POSITION.LEFT}
label={rowData.Address1 +" ,\n "+ rowData.Address2 +",\n"+rowData.ctiName+", "+rowData.staName+", "+rowData.ctrName+","+rowData.adbZip+"."}
innerColor="#C72128"
outerColor="#C72128"
styleLabel={{color:'#000',marginLeft:10}}
/>
Let me know if any query.