I'm trying to add a search function to my SliverList containing multiple list items.
Just before looping through my List of elements I added the TextField to implement the search function itself.
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Animal Name",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0))),
),
),
),
for (var animal in response)
Card( /* Elements to be searched later */)
as for the fluterSearchResults function:
void filterSearchResults(String query) {
List response = widget.res; // <- contains the animal data I'd like to search through
List<String> searchList = List<String>();
if (query.isNotEmpty) {
searchList.forEach((response) {
if (response.contains(query)) {
searchList.add(response);
}
setState(() {
items.clear();
items.addAll(searchList);
});
});
return;
} else {
setState(() {
items.clear();
items.addAll(searchList);
});
}
}
one element of the data within widget.res looks like this:
[{
id: 1,
game: "basegame",
name: "Aardvark",
continent: [
"Africa"
],
biome: [
"Grassland",
"Tropical"
],
can_swim: true,
status: "Least Concern",
exhibit: false,
dominance: "None",
relationship_human: "Shy",
mating_system: "Polygynous"
}]
the my function does not seem to add the elements properly to the searchList I'd like to display as long as the query is not empty but I'm unable to find the issue here.
Part of fluterSearchResults function is the reason causing error.
You use the same list for searching, [searchList].
It always search in an empty list.
Try
List responseList = widget.res;
List<String> searchList = List<String>();
responseList.forEach((response) {
if (response.contains(query)) {
searchList.add(response);
}
setState(() {
items.clear();
items.addAll(searchList);
});
});
return;
I hope the problem will be solved.
Related
if we search for any text in the search bar …we get filtered search results... but the issue is that all other To-dos are gone ..
I cant get back to all other Todos ..
search function code
List<Todos> todList =[];
searchTodo(String enterdText) {
final search = todList.where((txt) {
final inputtext = txt.todoText.toLowerCase();
final input = enterdText.toLowerCase();
return inputtext.contains(input);
}).toList();
setState(() => {todList = search});
}
search bar
TextField(
onChanged: searchTodo,
decoration: InputDecoration(
hintText: 'Search',
prefixIcon: Icon(Icons.search_rounded),
// enabledBorder: InputBorder.none,
iconColor: Colors.grey.shade400,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20))),
),
Save your list to a different variable and once the search ends replace with the saved list.
Something like this... little bit confuse on list size if not replace with length
List<Todos> todList =[];
List<Todos> tmpList =[];
searchTodo(String enterdText){
If(tmpList.size<todList.size){
tmpList=todList;
}
if(enterdText.trim().isEmpty()){
final search=tmpList;
}else{
final search = todList.where((txt) {
final inputtext = txt.todoText.toLowerCase();
final input = enterdText.toLowerCase();
return inputtext.contains(input);
}).toList();}
setState(() => {
If(tmpList.size<todList.size){
tmpList=todList;
}
todList = search});
}
This is my search code. It works by typing id the codes to display the information.
onSearch(String text) async {
if (text.isNotEmpty) {
List<Item> itemList = [];
for (var item in items) {
if (item.custnum == text.toLowerCase().toUpperCase()) {
itemList.add(item);
}
}
setState(() {
searchitems.clear();
searchitems.addAll(itemList);
print('name : ${searchitems[0].name}');
// if (searchitems.isEmpty) {
// searchitems = [];
// print('searchitems : ${searchitems[0].address!.length}');
// print('searchitems : ${searchitems[0].address!}');
});
} else {
setState(() {
searchCus.clear();
searchitems.clear();
// searchitems.addAll(items);
print('searchitems : $searchitems');
});
}
}
This is my textformfield, it can find and display data. But what I will do is Getting a code from another page It's received and shows the code. But it doesn't show me the information. It has to delete and type at least 1 new password to show the information. Please help me i tried a lot.
TextFormField(
initialValue:
'${searchCus.isEmpty ? "" : searchCus[widget.indexCus].custnum}',
onChanged: onSearch,
decoration: InputDecoration(
labelText: 'custnum',
labelStyle: TextStyle(fontFamily: 'supermarket', fontSize: 14),
isDense: true,
),
),
The reason the initial value not do the search is that you search logic is only works when you type in the textfield, if your initial value come from class constructor you can call onSearch in initState like this:
#override
void initState() {
super.initState();
if(searchCus.isNotEmpty){
onSearch(searchCus[widget.indexCus].custnum);
}
}
i'm trying to fetch users through a search bar! the search function works perfectly but everytime I try to remove some letters it doesn't get me back to the intial full list of users.
Textfield for search:
TextField(
controller: searchController,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
hintText: 'Search for users',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: Colors.grey))),
onChanged: (value) => searchUser(value),
),
Search function:
void searchUser(String query) {
final suggstions = users?.where((user) {
final userName = user.name.toLowerCase();
final input = query.toLowerCase();
return userName.contains(input);
}).toList();
setState(() {
users = suggstions;
});
}
initState:
#override
void initState() {
super.initState();
getUsersFromDatabase();
}
I'd be grateful if anyone can help!
since you only fetch the list once in initState, then you have to separate in to different list.
List users = [];
List showUser =[];
in your getUsersFromDatabase()
users = your api response list;
showUser = users;
for the search function you have to filter the users and assign it to showUser
void searchUser(String query) {
if( String query == '') {
setState(() { // setState to update UI
showUser = users); // when empty string, show all users
});
return; // return it, so the code below will not executed
}
// filter the users, and the result assign to show users.
// so your list of user will only change once in initState
final suggstions = users?.where((user) {
final userName = user.name.toLowerCase();
final input = query.toLowerCase();
return userName.contains(input);
}).toList();
setState(() {
showUsers = suggstions;
});
}
last, display the showUser not the users
ListView(
children: showUser.map()
.....
I made a code that displays a String Array using RadioListTile, but I don't know how to exactly get the user input when he/she selects one option from the list. I'm trying to use controller, but I'm not pretty sure how to use it in this ocation. Any advice? or comments? Here is my code:
///Here is the variable I use to get the user's answer.
TextEditingController userAns = TextEditingController();
///Here I'm using RadioListTile to display all the options and let the user to select one of them.
String selectedOption = '';
List<Widget> checkWhatOptionsDisplay(var question){
///Get question options and check what type of options display.
List<Widget> displayOptions = [];
var options = question.options;
if(options==""){
displayOptions.add(
TextField(
controller: userAns,
keyboardType: TextInputType.text,
decoration: InputDecoration(
hintText: 'Answer Fill in Blank',
labelText: 'Answer Fill in Blank',
),
)
);
}else{
for(String option in options){
displayOptions.add(
RadioListTile(
value: option,
groupValue: selectedOption,
title: Text(option),
onChanged:(currentOption){
setSelectedOption(currentOption);
} ,
selected: selectedOption == option,
)
);
}
}
return displayOptions;
}
setSelectedOption(var option) {
setState(() {
selectedOption = option;
});
}
so I am using MultiSelectBottomSheetField in this package. I posted on their github as well as an issue but it seems fairly inactive so i came here looking for help.
And I am having some issues with the initialValue parameter for it. So at the moment, I have data saved in firestore as a string but its in the format of a list. And what i was trying to do was get the string data from firestore -> convert to a list with the respective class -> and then show as initial value in the above package/widget. But whats happening is that the initial value isnt showing, even though the value is not empty.
So for context this is how I change to list from firestore string:
List<Skill?> skillList = [];
void changeSkillToList(String? stringList) {
int indexOfOpenBracket = stringList!.indexOf("[");
int indexOfLastBracket = stringList.lastIndexOf("]");
var noBracketString =
stringList.substring(indexOfOpenBracket + 1, indexOfLastBracket);
var list = noBracketString.split(", ");
for (var i = 0; i < list.length; i++) {
skillList.add(Skill(id: 1, name: list[i].toString()));
}
}
this is how i use the acc widget:
final _skillItems =
skill.map((skill) => MultiSelectItem<Skill>(skill, skill.name)).toList();
MultiSelectBottomSheetField<Skill?>(
selectedColor: Color(0xFF5DB075),
selectedItemsTextStyle:
TextStyle(color: Colors.white),
initialChildSize: 0.4,
decoration: BoxDecoration(),
listType: MultiSelectListType.CHIP,
initialValue: skillList,
searchable: true,
items: _skillItems,
buttonText: Text("Select your skills...",
style: GoogleFonts.inter(
color: Color(0xFFBDBDBD),
fontSize: 16)),
onConfirm: (values) {
context
.read(pharmacistSignUpProvider.notifier)
.changeSkillList(values);
},
chipDisplay: MultiSelectChipDisplay(
items: context
.read(pharmacistSignUpProvider.notifier)
.skillList
?.map((e) =>
MultiSelectItem(e, e.toString()))
.toList(),
chipColor: Color(0xFF5DB075),
onTap: (value) {
context
.read(
pharmacistSignUpProvider.notifier)
.skillList
?.remove(value);
return context
.read(
pharmacistSignUpProvider.notifier)
.skillList;
},
textStyle: TextStyle(color: Colors.white),
),
),
And this is my initState:
List<Skill?> skillList = [];
#override
void initState() {
skillList = changeSkillToList(context
.read(pharmacistMainProvider.notifier)
.userDataMap?["knownSkills"]);
print(skillList);
super.initState();
}
If someone could help me out, it would be very appreciated. Let me know if you guys have any questions
Thanks!!
I get some problem and I fix it by adding the == operator to my entity in your case skill
#override
bool operator ==(Object other) {
return other is Skill && this.id == other.id;
}
inside your Skill class