I'm working on a online survey app in flutter and the API in PHP with MySQL for the database.
I'm using TextFormField for the Name field and wanted to use Slider for Age field.
I can retrieve the value from TextFormField using onSaved: (e) => name = e,, But I don't know how to retrieve the value of the Slider.
I tried to change the value to string using age.toString() but It says:
The argument type 'String' can't be assigned to the parameter type.
Here is my Form() code:
Form(
key: _key,
child: ListView(
children: [
TextFormField(
onSaved: (e) => name = e,
decoration: InputDecoration(labelText: "Name"),
),
Slider(
min: 10,
max: 100,
value: age,
onChanged: (value) {
setState(() {
age = value;
});
},
label: "$age",
),
MaterialButton(
onPressed: () {
check();
},
child: Text("submit"),
)
]
)
),
Related
By using TextEditingController in Flutter, I'm trying to force the user to enter a number that starts with zero and then the number 4 or 8, then enter whatever he wants. Like this:
04****** or 08******
What should I do?
My code:
TextFormField(
maxLength: 10,
controller: _inputdat,
inputFormatters: [ FilteringTextInputFormatter.digitsOnly,],
keyboardType: TextInputType.number),
ElevatedButton(
......
onPressed: () async {
if (_inputdat.text.length < 10
|| !RegExp(r'^[0][8/4/2]{1}[0-9]{8}$').hasMatch(value))
{
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
backgroundColor: Color(0xff446d74),
content: Text(
"Error",
)));
What's wrong with my code? I got the error: Undefined name 'value'.
You can use https://pub.dev/packages/mask_text_input_formatter and do something like this:
var maskFormatter = new MaskTextInputFormatter(
mask: '0*########',
filter: { "*": RegExp(r'[48]'), "#": RegExp(r'[0-9]') },
type: MaskAutoCompletionType.lazy
);
and then pass maskFormatter to your text filed
TextField(inputFormatters: [maskFormatter])
Use this regex in the TextFormFiled validator r'^0[48][0-9]{7}$'
If you want to specify a specific number in total you can specify it in this part [0-9]{7} instead of seven you can choose different number.
This regex has in total of 9 numbers:
start with Zero 0
Second choose one 4 or 8 [48]
Third choose any 7 number [0-9]{7}
The validator should look something like this:
validator: (value) {
if (value!.isEmpty || !RegExp(r'^0[48][0-9]{7}$').hasMatch(value)) {
return "error message";
} else {
return null;
}
},
initialize a form key like below:
final formKey = GlobalKey<FormState>();
Full code:
Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
key: formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value!.isEmpty || !RegExp(r'^0[48][0-9]{7}$').hasMatch(value)) {
return "error message";
} else {
return null;
}
},
decoration: const InputDecoration(
errorMaxLines: 2, // specify how many error lines you want
border: OutlineInputBorder(),
labelText: 'number',
),
maxLength: 10,
controller: _inputdat,
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
keyboardType: TextInputType.number),
ElevatedButton(
onPressed: () {
if (formKey.currentState!.validate()) {
// do something like a function or toast message etc...
}
},
child: const Text('Confirm'),
),
],
),
),
How do I reset or select the first value from DropdownButtonFormField?
The answer from here How to reset value in Flutter DropdownButtonFormField is outdated and not suitable for the newer flutter version.
DropdownButtonFormField:
final etSkillScore1Key = GlobalKey<FormState>();
...
DropdownButtonFormField(
key: etSkillScore1Key,
decoration: const InputDecoration(labelText: 'Select value'),
onChanged: (val) async {
setState(() {
etSkillScore1 = val as int;
});
FocusScope.of(context).requestFocus(FocusNode());
},
value: etSkillScore1,
items: priorities2.map((db.Priority priorities) {
return DropdownMenuItem(
child: Text(priorities.name),
value: priorities.value,
);
}).toList(),
),
Button for resetting the value:
IconButton(
onPressed: () {
//ERORR: Null check operator used on a null value
etSkillScore1Key.currentState!.reset();
},
icon: Icon(
Icons.close,
))
Error:
======== Exception caught by gesture
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value
If I use
etSkillScore1Key.currentState?.reset();
then nothing happens
First of all you are not using the correct key it should be a GlobalKey<FormFieldState>(), but even then the reset() would not work.
The reason for this is because of the implementation of DropdownButtonFormField:
DropdownButtonFormField({
// ...
T? value,
// ...
}) : super(
// ...
initialValue: value,
// ...
);
(source: Flutter Documentation)
As you can see the value property of DropdownButtonFormField is what defines the initialValue of the FormField so when you are rebuilding your form field and changing the value of etSkillScore1 it is also changing the value of your DropdownButtonFormField.initialValue.
Solution 1
If you want your reset() to work then you can remove the property value of DropdownButtonFormField so the initialValue won't change with etSkillScore1.
DropdownButtonFormField<int>(
key: etSkillScore1Key,
decoration: const InputDecoration(labelText: 'Select value'),
onChanged: (val) {
etSkillScore1 = val;
FocusScope.of(context).requestFocus(FocusNode());
},
// value: etSkillScore1,
items: priorities2.map((db.Priority priorities) {
return DropdownMenuItem<int>(
child: Text(priorities.name),
value: priorities.value,
);
}).toList(),
)
Try the full example on DartPad
Solution 2
Do not set the value property with etSkillScore1, if you want to initialize your widget with an initial value then do it like this:
DropdownButtonFormField<int>(
key: etSkillScore1Key,
decoration: const InputDecoration(labelText: 'Select value'),
onChanged: (val) {
etSkillScore1 = val;
FocusScope.of(context).requestFocus(FocusNode());
},
value: 1, // Use a fixed value that won't change
items: priorities2.map((db.Priority priorities) {
return DropdownMenuItem<int>(
child: Text(priorities.name),
value: priorities.value,
);
}).toList(),
)
As your value will be fixed then when DropdownButtonFormField is rebuild it will keep 1 as its initial value.
I tried to make json to dropdownbutton today.
But I want to get 2 values(ID and Name both) from it.
this is my json
[{"StudentID":"3","StudentName":"Amy"},{"StudentID":"4","StudentName":"Derek"}]
and this is my code of dropdown button.
Row(
children: <Widget>[Container(
padding: EdgeInsets.only(left:5),
child: new DropdownButton(
value: _StudentSelection,
items: StudentData.map((product) {
return new DropdownMenuItem(
value: product["StudentID"].toString(),
child: new Text(product["StudentName"]!)
)
}).toList(),
onChanged: (String? newValue) {
setState(() {
_StudentSelection = newValue!;
});
},
hint: Text('StudentID'),
)
),
],
),
in this case variety _StudentSelection is already initialized by Amy and StudentData is result of decoding json.
Thank you for seeing this question :)
Make your _StudentSelection variable's type the same type as your product variable and then use product as a value:, not just the ID.
Row(
children: <Widget>[Container(
padding: EdgeInsets.only(left:5),
child: new DropdownButton(
value: _StudentSelection, // change this variables type to the type of your product variable
items: StudentData.map((product) {
return new DropdownMenuItem(
value: product, // use the whole product as value
child: new Text(product["StudentName"]!)
)
}).toList(),
onChanged: (TYPE_OF_PRODUCT_HERE? newValue) {
setState(() {
_StudentSelection = newValue!;
});
},
hint: Text('StudentID'),
)
),
],
),
I am trying to assign an input value into my model in order to use it in the API POST request. However, I keep getting the error:
setter was called on null when saving
Model:
#JsonSerializable()
class Discount {
String value;
Discount();
set setValue(String value) {
this.value = value;
}
Dart Code:
children: <Widget>[
Expanded(
child: Container(
margin: EdgeInsets.only(right: 5),
child: TextFormField(
initialValue: _invoiceFormData.discount?.value ?? '0.00',
inputFormatters: [_amountValidator],
keyboardType: TextInputType.numberWithOptions(
decimal: true,
signed: false,
),
decoration: TextFormField.decoration(
labelText: Localizations.of(context)
.text('label_invoice_discount'),
),
onChanged: (String value) {
setState(() {
discountTotal = value;
});
},
onSaved: (value) => _invoiceFormData
.discount.setValue = value,
),
),
),
FlatButton(
onPressed: () {
setState(() {
discountType = !discountType;
});
},
),
],
Log:
The setter 'setValue=' was called on null.
Receiver: null
Tried calling: setValue="10.00"
I tried to set _invoiceFormData.discount.value = value but it is still showing the same error.
use StatefulWidget class and
change this
onSaved: (value) => _invoiceFormData
.discount.setValue = value,
to
onSaved: (value) => setState(() {
onSaved: (value) => _invoiceFormData
.discount.setValue = value,
});
Your log is saying that _invoiceFormData.discount is null when you are using the setter setValue=.
To resolve this, you first need to instantiate the field discount in your object named _invoiceFormData. For example, when you initialize this form data (maybe in your initState()), you should do _invoiceFormData.discount = Discount(); then it will not be null anymore
I'm new to flutter and I have issues with Radio.
I got it to work perfectly when using the "regular" method:
int _groupValue=-1;
...
...
child: Align(
alignment: Alignment.center,
child: Column(
children: <Widget>[
RadioListTile(activeColor: Colors.black,
groupValue: _groupValue,
value: 1,
onChanged: (value) { setState(() {
_groupValue=value;
}); },
title: Text("a"),
),
RadioListTile(activeColor: Colors.black,
groupValue: _groupValue,
value: 2,
onChanged: (value) { setState(() {
_groupValue=value;
}); },
title: Text("b"),
),
],
),
),
Since I'm using data from API to create the radio buttons I've changed this code to this:
child: Align(
alignment: Alignment.center,
child: children: radioListView
),
),
and on click of a button i call async method to download the data from the API and like this :
void getApiData() async {
...
...
...
setState() {
var radioListView = List<RadioListTile>();
for (Map<String, dynamic> c in apidata)) {
radioListView.add(new RadioListTile(
groupValue: _groupValue,
value: c['option_value'],
title: c['title'],
onChanged: (value) { setState(() {
_groupValue=value;
});
),
));
}
}
}
using the first code it works but using the second code I just get to see the items but nothing happens when I click on the radio buttons (although the onchanged does trigger because I tried to print the value and it's fine)
what am I doing wrong?
I found the solution here:
https://www.didierboelens.com/2018/05/hint-5-how-to-refresh-the-content-of-a-dialog-via-setstate/
The problem was that I had to seperate the widgets and create another stateful widget for the radio