0

I am learning React and I am trying to achieve the following: I am using Dropdown list which allows a user to select multiple items. Then I am trying to add each selected option in an array. Then I am tying to display the selected items (options) in the render method, but it is not working.

Later on I would like to convert this component into a reusable one so I can perform cascading.

So, my questions are:

1) how can I add each selected option into an array
2) iterate through the array and display items inside the render method
3) how to make this component reusable

enter image description here

The image below shows that the length of the array is 1, but I can't display the items. It is empty. enter image description here

Below I am including the code that I have so far:

import * as React from 'react';
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import { Dropdown, IDropdown, DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';

import './Dropdown.Basic.Example.scss';
import { IBaseProps,BaseComponent, createRef } from 'office-ui-fabric-react';

export interface IDropdownBasicExampleProps extends IBaseProps {
  loadOptions: () => Promise<IDropdownOption[]>;
  onChanged: (option: IDropdownOption, index?: number) => void;
}

export interface IDropdownBasicExampleState {
    selectedItem?: IDropdownOption;
    selectedItems: IDropdownOption[];
    loading: boolean;
    options: IDropdownOption[];
    selectedKey: string | number;
    error: string;
}
export class DropdownBasicExample extends BaseComponent<IDropdownBasicExampleProps,IDropdownBasicExampleState> {
  private _basicDropdown = createRef<IDropdown>();
  private selItem:IDropdownOption;
  constructor(props:IDropdownBasicExampleProps,state:IDropdownBasicExampleState) {
    super(props);
    this.state = {
      selectedItem: undefined,
      selectedItems: new Array<IDropdownOption>(),
      loading: true,
      error: undefined,
      options: undefined,
      selectedKey:""
    };

  }

  public componentDidMount(): void {
    this.loadOptions();
  }


  private loadOptions(): void {
    this.setState({
      loading: true,
      error: undefined,
      options: undefined
    });

    this.props.loadOptions()
      .then((options: IDropdownOption[]): void => {
        this.setState({
          loading: false,
          error: undefined,
          options: options
        });
      }, (error: any): void => {
        this.setState((prevState: IDropdownBasicExampleState, props: IDropdownBasicExampleProps): IDropdownBasicExampleState => {
          prevState.loading = false;
          prevState.error = error;
          return prevState;
        });
      });
  }

  public onChangeMultiSelect = (item: IDropdownOption, index): void => {
    const updatedSelectedItem = this.state.selectedItems ? this.copyArray(this.state.selectedItems) : [];
    if (item.selected) {
      // add the option if it's checked
      updatedSelectedItem.push(item.key);
    } else {
      // remove the option if it's unchecked
      const currIndex = updatedSelectedItem.indexOf(item.key);
      if (currIndex > -1) {
        updatedSelectedItem.splice(currIndex, 1);
      }
    }
    this.setState({
      selectedItems: updatedSelectedItem,
      //selectedItem:item
    });

    if (this.props.onChanged) {
       this.props.onChanged(this.state.selectedItem, index);
    }

    console.log(this.state.selectedItems);
  };

  public copyArray = (array: any[]): any[] => {
    const newArray: any[] = [];
    for (let i = 0; i < array.length; i++) {
      newArray[i] = array[i];
    }
    return newArray;
  };


  public render() {
    const { selectedItem, selectedItems } = this.state;

    return (
      <div className="docs-DropdownExample">

        <Dropdown
          placeHolder="Select options"
          label="Multi-Select controlled example:"
          selectedKey={selectedItem ? selectedItem.key : undefined}
          //selectedKeys={selectedItems}
          onChanged={this.onChangeMultiSelect}

          multiSelect
          options={this.state.options}
        />

    <div>length: {this.state.selectedItems.length}</div>

            {this.state.selectedItems.map((item:IDropdownOption)=>{
              return <div>key: {item.key} {item.selected} {item.text} {item.index}</div>
            })}
       </div>
    );
  }


}
Burre Ifort
  • 653
  • 3
  • 15
  • 30

1 Answers1

0

First time define a state

this.state = {
    checkbox_value: []
}

then define checkboxs such as:

<input onChange = { this.checkboxValue.bind(this) } value = "0" type="checkbox" />
<input onChange = { this.checkboxValue.bind(this) } value = "2" type="checkbox" /> 

then use the function.

checkboxValue(event){

    let checked_list = this.state.checkbox_value;
    let check =  event.target.checked;
    let value =  event.target.value; 
    if(check){
        this.setState({
            checkbox_value: [...this.state.checkbox_value, value]
        });
    }else{
        var index = checked_list.indexOf(event.target.value);
        if (index > -1){
            checked_list.splice(index, 1);
        }
        this.setState({
            checkbox_value: checked_list
        })
    }

}

then you can show checked value in render using map() method for checkbox_value. I hope it is usefull for you

Araz Babayev
  • 1,752
  • 12
  • 16
  • Thanks for your reply. I can't use a checkbox as I am using the dropdown component from office-ui fabric. Most of the things you suggested I have included them. I will give it a try later and let you know. – Burre Ifort Jun 30 '18 at 14:10
  • Thanks but there is chenkbox inside of every dropdown element in image.I think that same logic.You can replace my each checkbox element your similar dropdown element. ) – Araz Babayev Jun 30 '18 at 17:59