如何实现单选组验证
onClick
提交按钮,它应该突出显示没有用红色或某种验证回答的单选组或问题。
例如,如果未选中任何单选组按钮,则单击提交按钮将 ListGroupItem bsStyle="danger"更改为特定列表。
原始代码 https://stackblitz.com/edit/react-ujmlcz
//array of cards coming from the backend
const data = [
{
cardName: 'Do you want sugar in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
},
{
cardName: 'Do you want milk in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
},
{
cardName: 'Do you want low-fat-milk in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
}
];
class CardsList extends React.Component {
constructor(props) {
super(props);
this.state = {
cards: [],
};
}
componentDidMount() {
setTimeout(() => {
// mimic an async server call
this.setState({ cards: data });
}, 1000);
}
onInputChange = ({ target }) => {
const { cards } = this.state;
const nexState = cards.map(card => {
if (card.cardName !== target.name) return card;
return {
...card,
options: card.options.map(opt => {
const checked = opt.radioName === target.value;
return {
...opt,
selected: checked
}
})
}
});
this.setState({ cards: nexState })
}
onSubmit = () => {
let unselectedCards = this.state.cards.filter((card) => {
return !card.options[0].selected && !card.options[1].selected
});
console.log("Please answer all the questions"+unselectedCards);
console.log(this.state.cards.map(({ cardName, options }) => {
const option = options.filter(({ selected }) => selected)[0]
return ` ${option.radioValue}`
}))
};
onReset = () => {
this.setState({cards:[]});
}
render() {
const { cards } = this.state;
return (
<div>
{
cards.length < 1 ? "Loading..." :
<div>
{cards.map((card, idx) => (
<ul>
{card.cardName}
{card.options.radioName}
{
card.options.map((lo, idx) => {
return <input
key={idx}
type="radio"
name={card.cardName}
value={lo.radioName}
checked={!!lo.selected}
onChange={this.onInputChange}
/>
})
}
</ul>
))
}
< button onClick={this.onSubmit}>Submit</button>
< button onClick={this.onReset}>Clear</button>
</div>
}
</div>
);
}
}
ReactDOM.render(<CardsList />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
最佳答案
要实现这一点,您首先需要扩展您的状态模型。考虑通过添加以下内容在每张卡片中跟踪您的“bsStyle”:
const data = [
{
cardName: 'Tires are inflated and free of excessive wear or damage. Nuts are tight.',
style : 'info', // <-- this is your bsStyle tracked for each card
options: [
{ radioName: 'Yes', radioValue: '1', selected: false },
{ radioName: 'No', radioValue: '2', selected: false }]
},
...,
...
]
这允许您的组件独立地了解并呈现每张卡片的适当 bsStyle。有了这个,您现在可以通过添加以下“验证”功能来更新您的 onSubmit
函数:
onSubmit = () => {
this.state.cards.forEach((card) => {
// If no option in the card is selected, consider the card invalid
var invalid = card.options.every(option => !option.selected)
if(invalid) {
card.style='danger'
}
else {
card.style='info'
}
});
// Cause form to re-render to display "danger" or "info" bsStyle
this.setState({ cards : this.state.cards })
...
...
}
您还需要确保在用户更改输入时更新验证。您可以通过以下方式实现:
onInputChange = ({ target }) => {
const { cards } = this.state;
const { options } = this.state;
const nexState = cards.map(card => {
if (card.cardName !== target.name) return card;
const options = card.options.map(opt => {
const checked = opt.radioName === target.value;
return {
...opt,
selected: checked
}
})
const style = options.every(option => !option.selected) ? 'danger' : 'info'
return {
...card,
style,
options
}
});
this.setState({ cards: nexState })
}
最后,您需要通过进行以下调整来更新 ListGroupItem
的呈现方式:
{cards.map((card, idx) => (
<ListGroup bsStyle="custom">
<ListGroupItem bsStyle={ card.style }>
...
</ListGroupItem>
</ListGroup>)}
有关更多详细信息,您可以在此处找到完整的工作示例: https://stackblitz.com/edit/react-immp6b?file=index.js
关于javascript - 单选按钮组验证。使用 alert Reactjs 突出显示所有未选中的单选按钮问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51806368/