1

I am using the Dropdown of PrimeReact.

I have this code, but in the Dropdown I only get to show the label and not the name.

How can I ​​display the name of each element of the optionsSearch variable in the Dropdown menu to select these names?

import React, {Component} from 'react';
import {Dropdown} from 'primereact/components/dropdown/Dropdown';

class OptionsExample extends Component {
  constructor(props) {
    super(props);
    this.state = {
      optionsSearch: 'FORM_FIELDS'
    };
  }

  onOptionChange = e => {
    this.setState({optionsSearch: e.value});
  }

  render() {
    const optionsSearch = [
      {key: 'NAME1', name: 'NAME1', label: 'DESCRIPTION1'},
      {key: 'NAME2', name: 'NAME2', label: 'DESCRIPTION2'},
      {key: 'NAME3', name: 'NAME3', label: 'DESCRIPTION3'}
    ];

    return (
      <div>
        <div className='ui-g-12 ui-md-12 ui-lg-12'>
          <Dropdown value={this.state.optionsSearch} options={optionsSearch} onChange={this.onOptionChange} style={{width: '180px'}} placeholder={`${this.state.optionsSearch}`} />
        </div>
      </div>
    );
  }
}

export default OptionsExample;
NelbeDG
  • 425
  • 1
  • 7
  • 19

1 Answers1

1

This code is copied from PrimeReact source code for dropdowns..

https://github.com/primefaces/primereact/blob/master/src/components/dropdown/DropdownItem.js

render() {
    let className = classNames('ui-dropdown-item ui-corner-all', {
        'ui-state-highlight': this.props.selected,
        'ui-dropdown-item-empty': (!this.props.label || this.props.label.length === 0)
    });
    let content = this.props.template ? this.props.template(this.props.option) : this.props.label;

    return (
        <li className={className} onClick={this.onClick}>
            {content}
        </li>
    );
}

As you can see, {content} is being rendered for each dropdown item, which only contains the "label".

let content = this.props.template ? this.props.template(this.props.option) : this.props.label;

Therefore if you want to show the "name", you have to put it in label.

Their demo also uses the "label" and "value" attribute only.

https://www.primefaces.org/primereact/#/dropdown

EDIT credits to @Chris G

You can also render a custom content, but then you have to pass a template function to the dropdown.

Their demo shows this.

carTemplate(option) {
    if(!option.value) {
        return option.label;
    }
    else {
        var logoPath = 'showcase/resources/demo/images/car/' + option.label + '.png';

        return (
            <div className="ui-helper-clearfix">
                <img alt={option.label} src={logoPath} style={{display:'inline-block',margin:'5px 0 0 5px'}} width="24"/>
                <span style={{float:'right',margin:'.5em .25em 0 0'}}>{option.label}</span>
            </div>
        );
    }
}

Which then they passed it to the Dropdown component.

<Dropdown value={this.state.car} options={cars} onChange={this.onCarChange} itemTemplate={this.carTemplate} style={{width:'150px'}} placeholder="Select a Car"/>
christopher_pk
  • 641
  • 4
  • 17
  • The second demo uses the format `{name: 'New York', code: 'NY'}` and that works perfectly fine if `name` is stated as `optionLabel` as required. –  Jul 03 '18 at 09:36
  • oh right, good catch. Looks like the library requires some Template in order to render a custom content. – christopher_pk Jul 03 '18 at 09:41
  • Thank you very much for your help. I know this demonstration https://www.primefaces.org/primereact/#/dropdown and I could not get it to work. I only needed add optionLabel="name" in the – NelbeDG Jul 03 '18 at 10:09
  • @christopher_pk How to add key attribute to avoid error - encountered two children with the same key. Keys should be unique so that components maintain their identity across update. https://stackoverflow.com/questions/64771089/primereact-warning-encountered-two-children-with-the-same-key/64771811#64771811 – Mahi Nov 13 '20 at 08:22