简体   繁体   English

Bootstrap-multiselect:默认值和 onChange 不起作用

[英]Bootstrap-multiselect: default value and onChange not working

I've done plenty of searches but couldn't get this to work.我已经进行了大量搜索,但无法使其正常工作。 Seems quite straightforward.看起来很简单。 I am using Bootstrap-multiselect by the way.顺便说一下,我正在使用 Bootstrap-multiselect。

class MyProject extends React.Component {
constructor(props) {
    super(props);
    this.state = { searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};
    }

//blah blah
render() {
return (
<select id="example-multiple-selected" multiple="multiple" defaultValue={this.state.searchForm.status} onChange={(event) => this.state.searchForm.status = event.target.value}>
    <option value="VALUE1">VALUE1</option>
    <option value="VALUE2">VALUE2</option>
    <option value="VALUE3">VALUE3</option>
    <option value="VALUE4">VALUE4</option>
    <option value="VALUE5">VALUE5</option>
    <option value="VALUE6">VALUE6</option>
    <option value="VALUE7">VALUE7</option>
    <option value="VALUE8">VALUE8</option>
</select>
)
}}

PROBLEM问题

  1. Default values (VALUE2 and VALUE4) are not getting selected;未选择默认值(VALUE2 和 VALUE4);

  2. Nothing seems happening when I change selected options当我更改所选选项时似乎没有任何反应

EDIT编辑

Seems everyone is talking about the fact that I am not setting state correctly, which I absolutely agree.似乎每个人都在谈论我没有正确设置状态的事实,我完全同意。 It was a silly mistake I made.这是我犯的一个愚蠢的错误。 However, the fundamental problem I am facing still remains:但是,我面临的根本问题仍然存在:

  1. as I mentioned, default values are not getting populated;正如我所提到的,默认值没有被填充;

  2. onStatusChanged function is not triggered at all. onStatusChanged 函数根本不会被触发。 I put debug point in this function but the debug point was not reached at all when I changed selected options.我将调试点放在此函数中,但是当我更改所选选项时根本没有达到调试点。

    onStatusChanged = (e) => { let search = this.state.searchForm; onStatusChanged = (e) => { let search = this.state.searchForm; search.status = e.target.selectedOptions; search.status = e.target.selectedOptions; this.setState({ searchForm: search }) } this.setState({ searchForm: search }) }

<select id="example-multiple-selected" multiple="multiple" defaultValue={this.state.searchForm.status} onChange={this.onStatusChanged}>

EDIT 2编辑 2

Latest code:最新代码:

class MyProject extends React.Component {
    constructor(props) {
        super(props);
        this.state = { searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};
        this.onStatusChanged = this.onStatusChanged.bind(this);
        }

    //blah blah
    onStatusChanged = (e) => {
        let search = this.state.searchForm;
        search.status = e.target.selectedOptions;
        this.setState({
            searchForm: search
        })
    }

    render() {
    return (
    <select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.onStatusChanged}>
        <option value="VALUE1">VALUE1</option>
        <option value="VALUE2">VALUE2</option>
        <option value="VALUE3">VALUE3</option>
        <option value="VALUE4">VALUE4</option>
        <option value="VALUE5">VALUE5</option>
        <option value="VALUE6">VALUE6</option>
        <option value="VALUE7">VALUE7</option>
        <option value="VALUE8">VALUE8</option>
    </select>
    )
}}

To re-iterate problems I am facing:重申我面临的问题:

  1. as I mentioned, default values are not getting populated;正如我所提到的,默认值没有被填充;

  2. onStatusChanged function is not triggered at all. onStatusChanged 函数根本不会被触发。 I put debug point in this function but the debug point was not reached at all when I changed selected options.我在这个函数中放置了调试点,但是当我更改所选选项时根本没有达到调试点。 Seems like onChange was not detected.似乎未检测到 onChange。

By the way, in case it helps, I am using Bootstrap-multiselect plugin.顺便说一句,如果有帮助,我正在使用Bootstrap-multiselect插件。

In react you can't modify the state directly, You will have to use this.setState That will return a new state to your component and react will re-render if needed.在 React 中,您不能直接修改状态,您必须使用 this.setState 这将向您的组件返回一个新状态,并且如果需要,React 将重新渲染。

For your selected issue, you will have to render each option with the “selected” attribute for it to be selected.对于您选择的问题,您必须使用“selected”属性呈现每个选项才能被选中。

You can't just explicitly set the state (expect in the constructor).您不能只显式设置状态(期望在构造函数中)。 In the event handler (on change), you have to use this.setState(...).在事件处理程序中(更改时),您必须使用 this.setState(...)。 Also you should be using the 'selectedOptions' property.此外,您应该使用 'selectedOptions' 属性。

onStatusChanged(event) {
  let searchForm = this.state.searchForm;
  searchForm.status = event.target.selectedOptions;
  this.setState({
    searchForm:searchForm
  });
}

....

<select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.onStatusChanged.bind(this)}>

If you are going to pass in a function, then you need to bind "this" so that it can set the state (you only need to do bind(this) if you need access to 'this' in the function).如果你要传入一个函数,那么你需要绑定“this”以便它可以设置状态(如果你需要访问函数中的“this”,你只需要执行 bind(this) )。

Here's it working on JS Fiddle https://jsfiddle.net/69z2wepo/184044/这是它在 JS Fiddle https://jsfiddle.net/69z2wepo/184044/上的工作

This answer is using vanilla-js(without Bootstrap-multiselect) but should work all the same.这个答案使用的是 vanilla-js(没有 Bootstrap-multiselect),但应该都一样。

You should not set react state directly, react state is immutable.你不应该直接设置反应状态,反应状态是不可变的。 You should always use setState so this.state.searchForm.status = event.target.value should have had been this.setState({searchForm: {status: event.target.value, otherprops:"blah"}}) .你应该总是使用setState所以this.state.searchForm.status = event.target.value应该是this.setState({searchForm: {status: event.target.value, otherprops:"blah"}}) You can read about setState from React Docs你可以从React Docs 中了解setState

event.target.value does not give you all the selected values. event.target.value不会为您提供所有选定的值。 If you console.log event.target you can see all the values, if you check for event.target[0].selected you can see if your first element has been selected or not.如果你console.log event.target你可以看到所有的值,如果你检查event.target[0].selected你可以看到你的第一个元素是否被选中。 Likewise, you have to iterate through all and see which all has been selected.同样,您必须遍历所有内容并查看已选择的所有内容。

I can see a lot of problems with your code, for a start, you are setting your state wrong.我可以看到您的代码有很多问题,首先,您设置的状态错误。 Try something like below.尝试类似下面的内容。 Y

class MyProject extends React.Component {
    constructor(props) {
        super(props);
        this.state = {  searchForm: { status: ["VALUE2","VALUE4"], otherprops: "blah" }, otherStates: "blah"};

            this.handlesChange = this.handlesChange.bind(this);
        }

        handlesChange(e){
            let statuses  = this.state.searchForm.status;
            let index = statuses.indexOf(e.target.value);

            if(index > 0) {
                this.setState({searchForm: statuses.splice(index, 1) })
            } else {
                statuses.push(e.target.value);
                this.setState({ searchForm: statuses});
            }
        }

    //blah blah
    render() {
        return (
            <select id="example-multiple-selected" multiple="multiple" value={this.state.searchForm.status} onChange={this.handlesChange}>
                <option value="VALUE1">VALUE1</option>
                <option value="VALUE2">VALUE2</option>
                <option value="VALUE3">VALUE3</option>
                <option value="VALUE4">VALUE4</option>
                <option value="VALUE5">VALUE5</option>
                <option value="VALUE6">VALUE6</option>
                <option value="VALUE7">VALUE7</option>
                <option value="VALUE8">VALUE8</option>
            </select>
    )

  }

}

Note: I haven't tested the above code.注意:我还没有测试过上面的代码。 But regardless you can't set the set the way you are doing, react states are immutable.但是不管你不能按照你的方式设置集合,反应状态是不可变的。 Use setState instead .改用setState

I have modified your code to have multi select option. 

#1 - I have added default selected values.
#2 - handleMultiSelect method will loop through the items selected and we set it to state.
#3 html content with values being printed based on our selected. 

 this.state = {
                value: ["VALUE2", "VALUE3", "VALUE4"]
            }


        handleMultiSelect = (e) =>{
            const options = e.target.options;
            var value = [];
            for (var i = 0, l = options.length; i < l; i++) {
              if (options[i].selected) {
                value.push(options[i].value);
              }
            }

            this.setState({
                value: value
            })

        }


   ########################HTML CODE ######################
    Selected Options {this.state.value} <br />
                    <select id="example-multiple-selected" 
                            multiple 
                            onChange={this.handleMultiSelect}
                            value={this.state.value}>
                        <option value="VALUE1">VALUE1</option>
                        <option value="VALUE2">VALUE2</option>
                        <option value="VALUE3">VALUE3</option>
                        <option value="VALUE4">VALUE4</option>
                        <option value="VALUE5">VALUE5</option>
                        <option value="VALUE6">VALUE6</option>
                        <option value="VALUE7">VALUE7</option>
                        <option value="VALUE8">VALUE8</option>
                    </select>

Hope this helps for you :)

The easiest way with Lodash is:使用 Lodash 的最简单方法是:

import React, { useState } from 'react';
import map from 'lodash/map';

const MultipleSelect = () => {
  const [selectedValues, setSelectedValues] = useState([]);

  const onMultipleSelectChange = event => {
    setSelectedValues(map(event.target.selectedOptions, option => option.value));
  };

  return (
    <select multiple value={selectedValues} onChange={onMultipleSelectChange}>
      <option value="value-1">value 1</option>
      <option value="value-2">value 2</option>
      <option value="value-3">value 3</option>
    </select>
  );
};

export default MultipleSelect;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM