Topic: Proper use of MDBSelect with search={true}
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>
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:
2) When you click "options" the first time, text should take focus, I have to click again in "write here" to actually write.
Uncaught SyntaxError: Invalid regular expression: /2\/: \ at end of pattern
Jakub Mandra staff premium answered 6 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.
gllermaly answered 6 years ago
Thanks for answering, I really hope you can improve this component to use it in my project.
Regards!
Anna Morawska staff commented 6 years ago
Thank You, please check it out on Monday, 7th January.
Happy coding :)
yujanrichie answered 6 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
Jakub Mandra staff premium answered 6 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 commented 6 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 commented 6 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 premium commented 6 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 commented 6 years ago
If I use this structure, options.value has a prop-type of number and expected is string.
Jakub Mandra staff premium commented 6 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 commented 6 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 premium commented 6 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 commented 6 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 premium commented 6 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.
gmayas answered 6 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 commented 6 years ago
But everything indicates that this.optionsSelect.push (data) can not be performed on the ngOnInit ()
Arkadiusz Idzikowski staff commented 6 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 commented 6 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 6 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.
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: 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
gllermaly commented 6 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?