I am trying to select buttons and then display how many I selected. Something like this:
I selected 4 buttons and I want the text to show "selected:4". Also if I unselect 2, I want the text to show "selected:2.
This is my code:
class RegionBT extends Component {
static defaultProps = {
onToggle: () => {},
}
state = {
status: [{ toggle: false }],
count: ''
}
handleIncrement = () => {
this.setState({
count: this.state.count + 1
});
}
handleDecrement = () => {
this.setState({
count: this.state.count - 1
});
}
_onPress() {
const newState = !this.state.toggle
this.setState({ toggle: newState })
this.props.onToggle(newState)
{this.handleDecrement}
}
render() {
const { count } = this.state
const { toggle } = this.state
const buttonBG = toggle ? '#6AAAC6' : 'white'
const textColor = toggle ? 'gray' : 'gray'
return (
<TouchableOpacity
onPress={()=>this._onPress()}
style={{width:'70%', height:'70%',backgroundColor:buttonBG, justifyContent:'center',
borderColor:'#E0E0E0', borderWidth:1}}>
<Text style={{color:textColor, textAlign:'center', fontSize:13}}>{this.props.text}</Text>
<Text>{count}</Text>
</TouchableOpacity>
)
}
}
I think I did the code correctly but its not working. Any ideas?
Related
I used Ant table to show some information.
https://codesandbox.io/s/proud-architecture-lsb85?file=/src/index.js
I want to customize the position of the checkbox for row selection.
In this application, you can see the header in the following order of checkbox, Name, Age, Address but I want to swap checkbox and Name.
You can add checkbox columns and customize render and titleRender of it to checkbox and then handle the events. if you incounter performance issue you have to add some memoization on columns or evenet handlers.
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import { Table, Button, Checkbox } from "antd";
const data = [];
for (let i = 0; i < 46; i++) {
data.push({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`
});
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedRowKeys: [], // Check here to configure the default column
loading: false,
allChecked: false
};
this.columns = [
{
title: "Name",
dataIndex: "name"
},
{
dataIndex: "checked",
title: () => {
return (
<Checkbox
checked={this.state.allChecked}
onChange={(e) => this.selectAll(e)}
></Checkbox>
);
},
render: (text, rec, index) => {
return (
<Checkbox
checked={
this.state.selectedRowKeys.includes(rec.key) ||
this.state.allChecked
}
onChange={(e) => this.onChange(e, rec)}
></Checkbox>
);
}
},
{
title: "Age",
dataIndex: "age"
},
{
title: "Address",
dataIndex: "address"
}
];
}
start = () => {
this.setState({ loading: true });
// ajax request after empty completing
setTimeout(() => {
this.setState({
selectedRowKeys: [],
loading: false
});
}, 1000);
};
onChange = (e, rec) => {
const checked = e.target.checked;
if (checked) {
this.setState((state) => ({
...state,
selectedRowKeys: [...state.selectedRowKeys, rec.key]
}));
} else {
this.setState((state) => ({
...state,
selectedRowKeys: [
...state.selectedRowKeys.filter((item) => item !== rec.key)
]
}));
}
};
selectAll = (e) => {
const checked = e.target.checked;
if (checked) {
this.setState((state) => ({
...state,
allChecked: true
}));
} else {
this.setState((state) => ({
...state,
allChecked: false
}));
}
};
onSelectChange = (selectedRowKeys) => {
console.log("selectedRowKeys changed: ", selectedRowKeys);
this.setState({ selectedRowKeys });
};
render() {
const { loading, selectedRowKeys } = this.state;
const hasSelected = selectedRowKeys.length > 0;
return (
<div>
<div style={{ marginBottom: 16 }}>
<Button
type="primary"
onClick={this.start}
disabled={!hasSelected}
loading={loading}
>
Reload
</Button>
<span style={{ marginLeft: 8 }}>
{hasSelected ? `Selected ${selectedRowKeys.length} items` : ""}
</span>
</div>
<Table columns={this.columns} dataSource={data} />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
I have a switch in my tab header and
I want to get the value of switch value in my header every time when I toggle the switch. how can I get that value?
const navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
title: "Home",
headerTitleStyle: {
flex: 1,
textAlign: "center",
color: "white",
fontSize: 20,
},
headerTintColor: "white",
headerStyle: {
backgroundColor: "#4169E1",
},
headerRight: (
<Switch
onValueChange={() => params.handleSave()}
value={this.navigation.state.switchValue}
/>
),
};
};
class HomeScreen extends React.Component {
state = { switchValue: false };
componentDidMount() {
this.props.navigation.setParams({ handleSave: this.toggleSwitch });
}
toggleSwitch = (value) => {
//onValueChange of the switch this function will be called
this.setState({ switchValue: value });
//state changes according to switch
//which will result in re-render the text
};
}
I just called this.props.navigation.setParams every time I update the params value in navigation options
toggleSwitch = (value) => {
this.setState({ switchValue: value });
this.props.navigation.setParams({
switchValue: holder,
});
};
I have a button and when I toggle the button It changes the color.
This is the code:
state={
status:[
{toggle:false}
]
}
_onPress(){
const newState = !this.state.toggle
this.setState({toggle:newState})
}
render(){
const {toggle} = this.state
const textValue = toggle?"ON":"OFF"
const buttonBG = toggle?"#6AAAC6":"white"
const textColor = toggle?"white":"gray"
return(
<TouchableOpacity
onPress={()=>this._onPress()}
<Text>button</Text>
</TouchableOpacity>
)
}
}
But what if I have multiple buttons and they basically do the same function. Is there a way I could reuse this code without copy and pasting multiple times?
you can create a component call CustomButton
class CustomButton extends React.Component {
static defaultProps = {
onToggle: () => {},
}
state = {
status: [{ toggle: false }]
}
_onPress() {
const newState = !this.state.toggle
this.setState({ toggle: newState })
this.props.onToggle(newState)
}
render() {
const { toggle } = this.state
const textValue = toggle ? 'ON' : 'OFF'
const buttonBG = toggle ? '#6AAAC6' : 'white'
const textColor = toggle ? 'white' : 'gray'
return (
<TouchableOpacity onPress={() => this._onPress()}>
<Text>button</Text>
</TouchableOpacity>
)
}
}
and use anywhere you want
class App extends React.Component {
onButtonToggle = (isToggle) => {
console.log(isToggle)
}
render() {
return (
<View>
<CustomButton onToggle={this.onButtonToggle} />
</View>
)
}
}
I'm trying to display/store a list of items in my flatlist, but the problem is when I save an item and load that item in a different screen it is in a kind of repetition(look for the screen shot). And when I try to add different item, this new item will replace the previous item with the same kind of repetition. What I'm targeting is to have a list.
List_ScreenShot
Here is my code
AddModal.js
export default class AddModal extends React.Component {
constructor(props) {
super(props);
this.state = {
modalVisible: props.modalVisible,
id: null,
count: 0,
price: null
};
}
state = {
text: '',
}
save = () => {
const { text } = this.state;
let myArray = {
text, text
}
AsyncStorage.setItem('myArray', JSON.stringify(myArray));
alert(text + 'saved');
}
onChange = (text) => {
this.setState({ text });
}
componentWillReceiveProps(nextProps) {
this.setState({
modalVisible: nextProps.modalVisible,
id: nextProps.id,
price: nextProps.price
})
}
render() {
console.log('inside AppModal', this.state.modalVisible);
return (
<View>
<TextInput style = { styles.input }
keyboardType = "numeric"
onChangeText = { this.onChange }
value = { this.state.text } //Item **
>
</TextInput>
</View>
<View}>
<TouchableOpacity
onPress = {() => { this.props.setModalVisible(false) }}
>
<Text style = { styles.buttonText }>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
onPress = { this.save }>
<Text style = { styles.buttonText }>Send</Text>
</TouchableOpacity>
</View>
)
}
}
Settlment.js
import Details from '../Menus/Details';
const key = '#MyApp:key';
export default class Settlement extends React.Component {
state = {
text: '',
storedValue: '',
myArray: ''
}
componentWillMount() {
//this.onLoad();
AsyncStorage.getItem('myArray')
.then(text => this.setState({ text }));
}
showData = async() => {
let myArray = await AsyncStorage.getItem('myArray');
let d = JSON.parse(myArray);
this.setState({ myArray : myArray });
}
render() {
const { myArray, text } = this.state;
return (
<View>
<TouchableOpacity onPress = {this.showData}>
<Text>Load Data</Text>
</TouchableOpacity>
<FlatList data = { this.state.myArray }
renderItem = {({ item }) =>
<Text>{myArray}</Text>
}
keyExtractor={(item, index) => index.toString()}
>
</FlatList>
</View>
);
}
}
What I see here:
const { text } = this.state;
let myArray = {
text, text
}
AsyncStorage.setItem('myArray', JSON.stringify(myArray));
alert(text + 'saved');
is an object called myArray, and nothing is being added to it. It's being defined and then assigned a value.
Maybe you could declare your array elsewhere like in the constructor (as an array, not an object, using myArray = []) and then use myArray.push(text) or if you want an array containing objects you can push object using myArray.push({ yourKeyName: text }). Also, it seems like the object you're storing in AsyncStorage is being replaced and not added to. But I'm not sure why you're getting multiple list items instead of just one.
PS - Where you're declaring state looks a bit off. I usually see it like this:
constructor() {
super();
this.state = {
text: '',
storedValue: '',
myArray: '',
};
}
I have a component will use map to render multi checkbox, and each checkbox has a callback function "onPress" get by props, the "onPress" function will setState checked, but now when I click on one checkbox, all checkboxs will be chosed, it cause they all use the same state, the goal I wanna choose each checkbox what I just ckick on, I know I can write many state different "onPress" function for each checkbox, but it looks stupid, I will add more checkbox in the future, What's the best and flexiable way to solve the task?
import React, { Component } from 'react'
import { View } from 'react-native'
import { CheckBox } from 'react-native-elements'
const styles = {
CheckBox: {
borderBottomWidth: 0.3,
borderBottomColor: 'gray'
},
checkBox : {
backgroundColor: "#ffffff",
borderWidth: 0
},
text: {
flex: 0.95,
backgroundColor: "#ffffff"
}
}
const languages = ["中文","英文","日文","韓文"]
class Language extends Component {
constructor(props) {
super(props);
this.state = { checked: false };
}
onPress = () => {
this.setState({ checked: !this.state.checked })
}
renderlanguages = () => {
return languages.map((langauge) => {
return(
<View key = { langauge } style = { styles.CheckBox }>
<CheckBox
title = { langauge }
iconRight
containerStyle = { styles.checkBox }
textStyle = { styles.text }
checkedColor = 'red'
checked = { this.state.checked }
onPress = { this.onPress }
/>
</View>
)
})
}
render(){
return(
<View>
{ this.renderlanguages() }
</View>
)
}
}
export default Language;
The behavior is choose all checkbox even though I only choose one now.
You can just pass the langauge (note this is probably a typo for language) variable to the function and us it to identify which one is being checked
onPress = (langauge) => {
this.setState({ [langauge]: { checked: !this.state[langauge].checked } })
}
renderlanguages = () => {
return languages.map((langauge) => {
return(
<View key = { langauge } style = { styles.CheckBox }>
<CheckBox
title = { langauge }
iconRight
//component = { () => {return <TouchableOpacity></TouchableOpacity>}}
containerStyle = { styles.checkBox }
textStyle = { styles.text }
checkedColor = 'red'
checked = { this.state[langauge].checked }
onPress = { () => this.onPress(langauge) }
/>
</View>
)
})
}