I have problem with checkbox to add parameter hit to POST data for API.
This is POST data sent when I clicked Save Button :
Map<String, String> params = {
'breed_id': selectedBreedID!,
'gender': _selectedGender!,
'weight': weightTxtCtrl.text,
'date_of_birth': _dateController.text,
pHfirst! : pHlast!
};
final response = await http.post(
Uri.parse(
"http://localhost:8000/api/v1/pet",
),
headers: {'Authorization': 'Bearer $token'},
body: params,
);
}
this is my checkbox code :
String? pHfirst = "";
String? pHlast = "";
List<PetHealthModel> petHealths = [];
List<PetHealthModel>customPets=[];
petHealths.isNotEmpty
? Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: petHealths.map((e) {
var healthsID = customPets.map((e) => e.id).toList();
return CheckboxListTile(
title: Text(e.healthStatus),
value: healthsID.contains(e.id),
onChanged: (bool? value) {
if (value == true) {
setState ((){
customPets.add(e);
for (var element in customPets) {
pHfirst = "pet_healths["+element.id.toString()+"]";
pHlast = ""+element.id.toString()+",";
log(pHfirst!+" : "+pHlast!);
}
});
} else {
setState((){
customPets.remove(e);
for (var element in customPets) {
pHfirst = "pet_healths["+element.id.toString()+"]";
pHlast = ""+element.id.toString()+",";
log(pHfirst!+" : "+pHlast!);
}
});
}
}
);
}).toList(),
),
),
Here's the log that printed :
From the sample below is I know that my code works, but when I called it in Map<String, String> params it only called the last pet_healths that I selected not print all of that :
This is the result that in debut we can see that 5 data printed, but when it called to Map<String, String> Param it only 1 last data
*btw I have secondary problem (already solved) that if I select one of the checkbox, all checkbox will selected too. here's the picture
Please help, get stuck here for many days.
Ok from the code i have added a sample example for you, just copy and run the application to know how things are processing.
Solution Summary:
So you will get list of PetHealthModel and in that we can define a bool variable just for that model so that when that model gets rendered on the screen there will be a default value false and all the checkbox with no tick. and then when you click on the checkbox the specifc model isSelected is made true and only that item will be ticked.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Checkbox Example',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<PetHealthModel> petHealths = [];
@override
void initState() {
super.initState();
getDataHealth();
}
void getDataHealth() async {
// final response = await http.get(
// Uri.parse("http://localhost:8000/api/v1/pet_health"),
// );
// final metadata = PetHealthsMetadata.fromJson(jsonDecode(response.body));
//This above is the same where you get the data
// I have created a sample list
final list = [
PetHealthModel(id: 1, healthStatus: "Dont't no yet"),
PetHealthModel(id: 2, healthStatus: "Wash"),
PetHealthModel(id: 3, healthStatus: "cutting"),
PetHealthModel(id: 4, healthStatus: "styling"),
PetHealthModel(id: 4, healthStatus: "coloring"),
];
// you can use your metadata.data i am using the sample list for demo purpose.
setState(() => petHealths = list);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('heading'),
),
body: Column(
children: [
petHealths.isNotEmpty
? Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: petHealths.map((e) {
return CheckboxListTile(
title: Text(e.healthStatus),
value: e.isSelected,
onChanged: (bool? value) {
setState(() {
e.isSelected = value!;
});
});
}).toList(),
),
)
: Container(),
],
),
);
}
}
class PetHealthModel {
PetHealthModel({
required this.id,
required this.healthStatus,
this.isSelected = false,
// This is where you add the is selected item that means the status of every item can be modified.
});
final int id;
final String healthStatus;
bool isSelected;
// isSelected will not be in the below method because it is not coming from the api and this is just for ui change.
factory PetHealthModel.fromJson(Map<String, dynamic> json) => PetHealthModel(
id: json["id"],
healthStatus: json["health_status"],
);
Map<String, dynamic> toJson() => {
"id": id,
"health_status": healthStatus,
};
}
Let me know if it works for you