Topic: Proper use of MDBSelect with search={true}

gllermaly free asked 5 years ago


Hello, there is no documentation about using searchable MDBSelect and Im getting this warning : 

Warning: Failed prop type: Invalid prop `data[0]` of type `object` supplied to `t`, expected `string`.

This is the code im using:

            <div>

<MDBSelect

searchLabel="Write here"

search={true}

color="primary"

options={this.state.options}

selected="Options"

/>

<label>Example label</label>

</div>
 
state={
options: [
{
checked: false,
disabled: false,
icon: null,
text: "Option One",
value: "1"
},
{
checked: false,
disabled: false,
icon: null,
text: "Option two",
value: "2"
},
{
checked: false,
disabled: false,
icon: null,
text: "Option three",
value: "3"
},
{
checked: false,
disabled: false,
icon: null,
text: "Option four",
value: "4"
}
]
};

What I'm missing?

I have some problems/suggestions too to improve this component :

1) Values shows as texts, the search box looks like this:
(showing values instead of texts) 

2) When you click "options" the first time, text should take focus, I have to click again in "write here" to actually write.
 
3) If you write something and press enter the select box should select the first option availible (arrows to navigate between options would be awesome too) but the most common use case is write 3 or 4 chars, find the result and press enter to select it
 
after testing for a while this error appeared too:

Uncaught SyntaxError: Invalid regular expression: /2\/: \ at end of pattern

Thanks!!!



gllermaly free commented 5 years ago

I want to show 

Option 1
Option 2
Option 3

And when I trigger getValue , get 1,2,3 ... thats the supossed behaviour right?


gmayas free answered 5 years ago


Hello

How can I load the values of public optionsSelect: Array <{value: string, label: string}> from the ngOnInit () in Angular?

Example:

 public optionsSelect: Array <{value: string, label: string}>;

  ngOnInit () {
.....

    
     console.log ('olsClients:', this.user.olsClients.length);
     for (var _i = 0; _i <this.user.olsClients.length; _i ++) {
       var olsClients = this.user.olsClients [_i];
       var inc = + _i;
       const data = {
         value: inc.toString (),
         label: olsClients.ClaveClient
       };
       this.optionsSelect.push (data);
       console.log ('this.optionsSelect:', this.optionsSelect);
       console.log ('Data:', data);
     }
    
   }

...

But all inidca you can not perform the this.optionsSelect.push (data) in the ngOnInit ()

Waiting for your comments.


gmayas free commented 5 years ago

But everything indicates that this.optionsSelect.push (data) can not be performed on the ngOnInit ()


Arkadiusz Idzikowski staff commented 5 years ago

The 'push' method won't work, because Angular only run change detection when array reference has changed. We explained that in our documentation:

https://mdbootstrap.com/docs/angular/forms/select/#update-options

For further questions about MDB Angular components, please create new topic in Angular section.


gmayas free commented 5 years ago

Hello:

Try this:

for (var _i = 0; _i < this.user.olsClientes.length; _i++) { var olsClientes = this.user.olsClientes[_i]; var inc = +_i; const data = { value: inc.toString(), label: olsClientes.ClaveCliente }; // this.optionsSelect.push(data); this.optionsSelect = [...this.optionsSelect, {value: inc.toString(),label: olsClientes.ClaveCliente}]; console.log('this.optionsSelect: ', this.optionsSelect); console.log('Data: ', data); }

But I get the following error:

ProductosListComponent.html:7 ERROR TypeError: Cannot read property 'concat' of undefined at ClientBarComponent.ngOnInit (client-bar.component.ts:64) at checkAndUpdateDirectiveInline (core.js:9250) at checkAndUpdateNodeInline (core.js:10514) at checkAndUpdateNode (core.js:10476) at debugCheckAndUpdateNode (core.js:11109) at debugCheckDirectivesFn (core.js:11069) at Object.eval [as updateDirectives] (ProductosListComponent.html:2) at Object.debugUpdateDirectives [as updateDirectives] (core.js:11061) at checkAndUpdateView (core.js:10458) at callViewAction (core.js:10699)

How do I find my question in the Angular section since a few days ago I formulated one?

Best regards.


Arkadiusz Idzikowski staff commented 5 years ago

Please try to initialize your optionsSelect array:

public optionsSelect = [];

You can use search at the top of the support page to find existing question.


Jakub Mandra staff answered 5 years ago


Hi @yujanrichie,

Can you show us your code with binding? I'm not sure what causes the problem.

We could update the Search to search by value too, that sounds like a good suggestion which we could discuss.

But the user searches what he sees. So when we will use for example this object:

 {
    text: "Potato",
    value: 1 
 },
{
    text: "Tomato",
    value: 2
}

the data is no longer transparent to the user.

I think we could provide property to switch between those behaviors :)

Best,

Jakub


yujanrichie free commented 5 years ago

I created a wrapper component that uses MDB Select and provide values that are needed based on PropTypes. Search works when the Options passed are fixed and hard coded but not when derived from component state. Note that the "option" variable is from a state value. Here are 2 option samples: (I'm searching for "VX-520" thinking search checks by text)

checked: false, disabled: false, icon: "SX425.jpg">SX425.jpg">SX425.jpg">SX425.jpg">https://api.360payments.com/p/4988-410nhGscVFL.SX425.jpg", id: "option-1-8570311a-a0c2-474b-b6f0-7b693eaac89b", text: "VX 520", value: "Hardware-1",

checked: false, disabled: false, icon: "https://api.360payments.com/p/25668-swiftB250CardReader.png", id: "option-2-1fc0a824-957c-4e58-a50d-5c6b16c69c1e", text: "SwipeSimple Card Reader", value: "Hardware-2"


yujanrichie free commented 5 years ago

        <MDBSelect
          id={this.selectID}
          className={className || 'select-nomargin'}
          getValue={this.handleChangeValue}
          getTextContent={this.handleChangeText}
          multiple={multiple}
          style={this.props.style}
        >
            <label className={selectedText ? 'active' : ''}>
              {label}
            </label>
            <MDBSelectInput selected={selectedText} ></MDBSelectInput>

            <MDBSelectOptions search={search}>
              {
                options.map((option) => {
                  const {
                    id, checked, disabled, value, text, icon,
                  } = option;
                  return (
                    <MDBSelectOption
                      checked={checked}
                      selected={checked}
                      disabled={disabled}
                      key={id}
                      value={value}
                      icon={icon}
                    >
                      { text }
                    </MDBSelectOption>
                  );
                })
              }
              {addButtonElement}
            </MDBSelectOptions>
        </MDBSelect>

Jakub Mandra staff commented 5 years ago

Hi,

Thanks for the snippet. I've tested on my local project and works ok (merely label should be outside of the tag), data is derived from the state. Do you use the newest mdbreact version (there were some problems with the search in previous releases)?

Alternatively, you could use this markup for select, I think it will fit your config better: https://mdbootstrap.com/docs/react/forms/select/#alternative

<MDBSelect
  options={this.state.options}
  id={this.selectID}
  className={className || 'select-nomargin'}
  getValue={this.handleChangeValue}
  getTextContent={this.handleChangeText}
  multiple={multiple}
  style={this.props.style}
/> 
<label className={selectedText ? 'active' : ''}>
  {label}
</label>

It's much easier, cleaner, and more controllable by React.


yujanrichie free commented 5 years ago

If I use this structure, options.value has a prop-type of number and expected is string.


Jakub Mandra staff commented 5 years ago

Can you paste here the error message?

Options shape is:

options: PropTypes.arrayOf(
    PropTypes.shape({
      checked: PropTypes.bool,
      disabled: PropTypes.bool,
      icon: PropTypes.string,
      text: PropTypes.string,
      value: PropTypes.string
    })
  ),

yujanrichie free commented 5 years ago

I can't do the simpler call to MDBSelect because I need to add children, specifically a Button inside the dropdown. I don't understand what is the difference between passing options.map where options is a constant array of objects versus options created from a state. It doesn't seem to see the innerText or can't identify the children.

Edit: found one issue, when including an image/icon, it inserts an element before the span element so search condition in MDBSelectOption is no longer correct. However removing the icon so span becomes the first element still didn't solve the problem.


Jakub Mandra staff commented 5 years ago

Thank you for the issue report (it does not appear in the select with options from the state).

The main difference when you pass options created from the state is that the state object is fully controllable by React. It allows you to remove/add or sort your options with no worries (which is not possible with the options.map, because the Select's inner state won't be updated).


yujanrichie free commented 5 years ago

I'm using state because I needed to modify the options before sending to MDBSelect. I can probably let the parent component handle this logic and pass options to the child component as props which would then use MDBSelect. Will that work?


Jakub Mandra staff commented 5 years ago

Yes, that should work, with no problem :) But you have to remember to update the state of the child, or make it as a stateless component.


yujanrichie free answered 5 years ago


Can you update MDB Select to search from either value or text? I'm not sure why but it seems that the search have issues when state values are passed to it. If I bind prop values it works but the search does not work when I bind to state values


gllermaly free answered 5 years ago


Thanks for answering, I really hope you can improve this component to use it in my project.

Regards!


Anna Morawska staff commented 5 years ago

Thank You, please check it out on Monday, 7th January.

Happy coding :)


Jakub Mandra staff answered 5 years ago


Hello,

That's a bug - text property is missing for options, so the value is displayed. And search is searching by value, not bye text content. 

We have to fix those bugs immediately, but it can be release with the whole package in 7th o January.

Thank you so much for posting bugs and your thoughts about component.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Free
  • Premium support: No
  • Technology: MDB React
  • MDB Version: 4.8.4
  • Device: Macbook pro 2013
  • Browser: chrome
  • OS: macos sierra
  • Provided sample code: Yes
  • Provided link: No