#flutter #datatable #dropdown
Вопрос:
я пытаюсь отобразить текущий месяц в раскрывающемся списке по умолчанию ( под словом «по умолчанию» я подразумеваю, что при перенаправлении пользователя в раскрывающемся списке экрана будет отображаться текущий месяц, а в таблице будут отображаться записи за текущий месяц.) Итак, я показываю текущий месяц, но в моей таблице данных не отображаются записи.
Я передаю месяц (в количестве) в своем теле api, я определил список, содержащий список месяцев, когда пользователь выбирает месяц, затем я получаю его индекс и увеличиваю его на 1, так как индекс моего списка начинается с 0, а затем передаю это число, которое является моим месяцем, в мой api.
вот код
String _selectedMonth;
int monthIndex;
int month;
var monthsList=<String>[
'January',
'Febuary',
'March',
'April',
'May',
'June',
'July',
'Augest',
'September',
'October',
'November',
'December'
];
String getdate="";
void _getDate() {
final String formattedDateTime =
DateFormat('MM').format(DateTime.now()).toString();
_selectedMonth=DateFormat('MMMM').format(DateTime.now());
setState(() {
getdate = formattedDateTime;
print(currentmonth);
print("date " getdate);
});
}
void initState() {
_userDetails();
_getDate();
_getRecord();
}
Future<List<History>> _getRecord() async{
Dio dio=new Dio();
var data={
'username':getName,
'month':month,
'token':getaccesstoken
};
return dio
.post(localhostUrlAttendanceHistory,data: json.encode(data))
.then((onResponse) async {
Map<String, dynamic> map=onResponse.data;
List<dynamic> data = map['data'];
for (var h in data) {
History history = History(
h["_id"],
h["Date"],
h["TimeIn"],
h["TimeOut"],
);
historyList.add(history);
id=history.id.toString();
print("id is ");
print(id);
}
return historyList;
})
.catchError((onerror){
print(onerror.toString());
});
}
//datatable code
Widget attendanceHistory(List<History>
historyList)=>
Center(
child:Padding(padding: EdgeInsets.fromLTRB(0, 0, 18, 0),
child:SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child:DataTable(
decoration: BoxDecoration(border: Border.all(color: Colors.blue[500], width: 2)),
headingRowColor: MaterialStateColor.resolveWith((states) => Colors.blue[500]),
headingTextStyle: const TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
showBottomBorder: true,
headingRowHeight: 60,
horizontalMargin: 7,
columnSpacing: 15,
dataRowColor: MaterialStateColor.resolveWith((states) => Colors.blue[50]),
dividerThickness: 4,
columns: <DataColumn>[
DataColumn(label: Text("Date")),
DataColumn(label: Text("Time in")),
DataColumn(label: Text("Time out"),numeric: true),
DataColumn(label: Text(" Edit")),
],
rows:
historyList
?.map((element)=>DataRow(
selected: true ,
cells: <DataCell>[
DataCell(Text(element?.date),),
DataCell(Text(element?.timeIn)),
DataCell(Text(element?.timeOut,)),
DataCell(IconButton(icon:Icon(Icons.edit,color: Colors.blue,),onPressed: (){
_getSelectedRowInfo(element?.id,element?.date,element?.timeIn,element?.timeOut);
})
void _getSelectedRowInfo(dynamic id,dynamic date,dynamic timein,dynamic timeout) {
AlertDialog alert = AlertDialog(
scrollable: true,
insetPadding: EdgeInsets.symmetric(vertical: 50),
title: Text("Request to change time",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blue[500])),
content:Container(child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child:Column(children:<Widget> [
TextField(
decoration: InputDecoration(labelText: date,hintText: "Date"),
controller:dateController ,
),
TextField(
decoration: InputDecoration(labelText: timein,hintText: "Time in",icon: Icon(Icons.timer)),
controller:timeinController ,
readOnly:true,
onTap: () async {
TimeOfDay pickedTime = await showTimePicker(
initialTime: TimeOfDay.now(),
context: context,
);
if(pickedTime != null ){
print(pickedTime.format(context)); //output 10:51 PM
DateTime parsedTime = DateFormat.jm().parse(pickedTime.format(context).toString());
//converting to DateTime so that we can further format on different pattern.
print(parsedTime); //output 1970-01-01 22:53:00.000
String formattedTime = DateFormat('HH:mm:ss').format(parsedTime);
print(formattedTime); //output 14:59:00
//DateFormat() is from intl package, you can format the time on any pattern you need.
setState(() {
timeinController.text = formattedTime; //set the value of text field.
});
}else{
print("Time is not selected");
}
},
),
TextField(
decoration: InputDecoration(labelText:timeout,hintText: "Time out",icon: Icon(Icons.timer_off)),
controller:timeoutController ,
readOnly:true,
onTap: () async {
TimeOfDay pickedTime = await showTimePicker(
initialTime: TimeOfDay.now(),
context: context,
);
if(pickedTime != null ){
print(pickedTime.format(context)); //output 10:51 PM
DateTime parsedTime = DateFormat.jm().parse(pickedTime.format(context).toString());
//converting to DateTime so that we can further format on different pattern.
print(parsedTime); //output 1970-01-01 22:53:00.000
String formattedTime = DateFormat('HH:mm:ss').format(parsedTime);
print(formattedTime); //output 14:59:00
//DateFormat() is from intl package, you can format the time on any pattern you need.
setState(() {
timeoutController.text = formattedTime; //set the value of text field.
});
}else{
print("Time is not selected");
}
},
),
]),
)
),
actions: [
FlatButton(
child: Text("Submit",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.blue[500],fontSize: 20),),
onPressed: () {
getupdatedTime();
Dio dio=new Dio();
var data={
'id': id,
'token':getaccesstoken,
'TimeIn': timeinText,
'TimeOut':timeoutText,
};
print("token is " getaccesstoken);
print("submit id is " id);
print(data);
dio
.put(localhostUrlMarkCorrection, data: json.encode(data))
.then((onResponse) async {
Navigator.of(context, rootNavigator: true).pop('dialog');
dialoguebox();
print("mark correction");
print(onResponse.data);
print(onResponse.statusCode);
}).catchError((onerror){
print(onerror.toString());
});
}
)],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: new MyAppBar(title: Text("My Attendance"),onpressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>Profile()));
}),
drawer:Emp_DrawerCode(),
body:Stack(children: <Widget>[
//here is my dropdown code
Container(
padding: EdgeInsets.fromLTRB(45, 80, 10, 0),
child:
DropdownButton<String>(
value: _selectedMonth==null?null:monthsList[monthIndex],
items:
monthsList
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value)
);
}).toList(),
hint:Text(
"Please choose a month",
),
onChanged: (String value) {
setState(() {
_selectedMonth=value; //i am getting month here
monthIndex = monthsList.indexOf(value); //then getting its index, so that i can find month in number
month=monthIndex 1; //and as index start from 0 so i increment it by 1
print(month);
print(_selectedMonth);
});
},
),
),
class History {
final String id;
final String date;
final String timeIn;
final String timeOut;
History(this.id,this.date, this.timeIn, this.timeOut);
}
Выходы:
Когда я вхожу в экран, он выглядит так
и когда я выбираю месяц из выпадающего списка, он отображает записи.
я хочу выводить данные, подобные рис.2, когда я перенаправляю/вхожу на экран, а затем пользователь также может выбрать месяц из выпадающего списка, и строки таблицы будут изменены в соответствии с выбранным месяцем.
Пожалуйста, помогите, если кто-нибудь знает, как это сделать.
Комментарии:
1. Вы имеете в виду, что строки таблиц не отображаются при входе на страницу, а отображаются после ее перестройки по какой-либо другой причине? Я не очень хорошо понимаю этот вопрос
2. да, когда я вхожу на страницу, строки не отображаются, когда я выбираю месяц из выпадающего списка, в моей таблице данных отображаются записи.
3. я обновляю свой вопрос с выводом, пожалуйста, проверьте его.
Ответ №1:
В вашем коде есть некоторые странные вещи. Но главная проблема в том, что месяц равен нулю.
Вы можете использовать геттеры для вычисления, когда это необходимо (удаление старых переменных) .
int get monthIndex => return monthsList.indexOf(_selectedMonth);
int get month => monthIndex 1;
Вы также можете попытаться вычислить его снова в состоянии инициализации перед выполнением операции, оба способа должны исправить вашу ошибку.
Какое-то странное поведение, которое я вижу, _selectedMonth
записывается в _getDate и initState.
Я не вижу, где historyList
это создано, но, возможно, вам нужно создать его экземпляр _getRecord
.
И это если всегда будет ложным if(monthsList.contains("element"))
, так как месяц не называется "element"
.