Hi, I am trying to create a dropdown list search in AppDesigner, that look for a string within the word, not just at the start.

My list is hundred of chemicals long and I want to search a dropdown list which will show me all these options containing the word formaldehyde, not just those starting with the word.
I tried this (an answer for a similar question) and it restricts the list as required, but I still only get the options starting with 'formald' come up in my dropdown.
app.NameLookupDropDown.Value = 'formald'
if isempty(app.NameLookupDropDown.Value) % If empty
app.NameLookupDropDown.Items = app.ChemList; % whole dataset
else
idx = contains(app.NameLookupDropDown.Items, app.NameLookupDropDown.Value);
Filtered_Values = app.NameLookupDropDown.Items(idx);
app.NameLookupDropDown.Items = Filtered_Values;
end
----
Formaldehyde
Formaldehyde polymer with 4-(1,1-dimethylethyl)phenol
Formaldehyde mixt. with methylphenol
Sodium formaldehydesulfoxylate
Naphthalenesulfonic acid, polymer with formaldehyde, sodium salt
4-tert-Butylphenol formaldehyde resin
Paraformaldehyde
N-[4-[[4-(dimethylamino)phenyl]phenylmethylene]-2,5-cyclohexadien-1-ylidene]-N-methylMethanaminium chloride, mixt. with formaldehyde
Pentanedial, mixt. with alkylbenzyldimethylammonium chlorides, ethanedial and formaldehyde

3 commentaires

That's odd. I would think, from this code, that you get everything that matches formaldehyde but doesn't begin with "Formald," because contains is case-sensitive by default.
Are you sure the dropdown items contain the whole name in one cell, or is it possible each item is broken up into multiple words?
Each name is a single cell. Here is a screenshot of what I'm getting.
It's difficult to diagnose without the full code, but a simple fix might be adding 'IgnoreCase',true to the contains call.
idx = contains(app.NameLookupDropDown.Items, app.NameLookupDropDown.Value, 'IgnoreCase',true);
On the other hand, since your code isn't working as it seems like it should, you might try Marcel's example, or troubleshoot.
You can put a breakpoint at the start of the if block, and when the program pauses, switch to the Matlab IDE window to inspect the app/variable properties. Determine whether they match what you expect to see, and you can inject code via the command window, to make sure the command you want to use is working properly.

Connectez-vous pour commenter.

 Réponse acceptée

EDIT
I changed the code as it didnt work 100%. Now it should.
Okay so i might have managed to make a solution. Im pretty sure you can adopt this to your application as well.
So in the startup function im declaring the data:
% Code that executes after component creation
function startupFcn(app)
global data;
data = [
"Formaldehyde",
"Formaldehyde polymer with 4-(1,1-dimethylethyl)phenol",
"Formaldehyde mixt. with methylphenol",
"Sodium formaldehydesulfoxylate",
"Naphthalenesulfonic acid, polymer with formaldehyde, sodium salt",
"4-tert-Butylphenol formaldehyde resin",
"Paraformaldehyde",
];
end
I added a few basic elements for testing using the App Designer and wrote the following code.
% Value changed function: ClearButton
function ClearButtonValueChanged(app, event)
value = app.ClearButton.Value;
global data;
clearitems(app);
for i=1:length(data)
app.ListBox.Items = [data(i), app.ListBox.Items];
end
end
% Value changed function: SearchButton
function SearchButtonValueChanged(app, event)
value = app.EditField.Value;
clearitems(app);
global data;
searchLength = strlength(value);
for i=1:length(data)
data(i);
for a=1:strlength(data(i))
if contains(lower(data(i)), lower(value)) == 1
% Get the items form the listbox
str = get(app.ListBox, 'Items');
str = cellstr(str);
if find(ismember(str, (data(i))))
% A Item with the value already exist
else
% There was no item with the value in the listbox,
% therefore we can add it
app.ListBox.Items = [data(i), app.ListBox.Items];
end
end
end
end
end
function clearitems(app)
app.ListBox.ItemsData = [];
app.ListBox.Items=cellstr(num2str([]));
end
Results:

4 commentaires

After some testing this also seems to work with a DropDown Control and after entering a text and pressing enter to trigger the ValueChanged Event, it works :)
I have a couple suggestions. Foremost, if you can avoid globals, I think it's pretty widely encouraged.
Data can be kept in the app instead:
properties (Access = public)
data
end
Include some data that doesn't pass the "formald" test, and populate the ListBox on startup
function startupFcn(app)
app.data = [
"Formaldehyde",
"Formaldehyde polymer with 4-(1,1-dimethylethyl)phenol",
"Dihydrogen Monoxide"
"Formaldehyde mixt. with methylphenol",
"Sodium formaldehydesulfoxylate",
"Vinyl Record"
"Naphthalenesulfonic acid, polymer with formaldehyde, sodium salt",
"Sofia Ester"
"4-tert-Butylphenol formaldehyde resin",
"Paraformaldehyde",
];
app.ListBox.Items = app.data;
end
We can also avoid nested for loops (Matlab's achilles heel) and use contains as the OP desired:
function SearchButtonValueChanged(app, event)
dataidx = contains(app.data, app.EditField.Value, ...
'IgnoreCase', true);
app.ListBox.Items = app.data(dataidx);
end
yeah i see what you mean. im more of a "proof of concept" guy and when something works then im trying to make it better, but in this case in my opinion its not that bad and well should only show a way (of many) on how you could achieve this.
But thats the cool thing about communities and colaboration as we can help each other and improve :P

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur App Building dans Centre d'aide et File Exchange

Produits

Version

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by