feat: enhance NewPage UI with dynamic bottom sheet for form input and restructure SDUI JSON schema for improved data handling

This commit is contained in:
2025-12-28 16:05:37 +03:30
parent 71952bef5a
commit fc0161e261
4 changed files with 1343 additions and 113 deletions

View File

@@ -25,7 +25,19 @@ class NewPage extends GetView<NewPageLogic> {
child: Column(
children: [
SizedBox(height: 24.h),
ObxValue((data) {
Row(children: []),
SizedBox(height: 24.h),
RElevated(
text: 'دکمه نمونه',
onPressed: () {
Get.bottomSheet(
isScrollControlled: true,
enableDrag: true,
BaseBottomSheet(
height: Get.height * 0.8,
child: ObxValue((data) {
if (data.value == null) {
return Center(child: CircularProgressIndicator());
}
@@ -44,11 +56,8 @@ class NewPage extends GetView<NewPageLogic> {
),
);
}, controller.sduiModel),
SizedBox(height: 24.h),
RElevated(
text: 'دکمه نمونه',
onPressed: () {
controller.onButtonPressed();
),
);
},
),
SizedBox(height: 24.h),

View File

@@ -1,13 +1,149 @@
{
"info": {
"type": "column",
"visible": true,
"data": {
"spacing": 10.0,
"crossAxisAlignment": "start"
},
"children": [
{
"type": "card_label_item",
"visible": true,
"data": {
"title": "اطلاعات مزرعه",
"title": "اطلاعات پایه واحد",
"padding_horizontal": 12.0,
"padding_vertical": 11.0
},
"child": {
"type": "column",
"visible": true,
"data": {
"spacing": 10.0
},
"children": [
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "unit_name",
"label": "نام واحد مرغداری",
"keyboard_type": "text"
}
},
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "breeding_unique_id",
"label": "(عدد معمولی)کد یکتا / شناسه واحد",
"keyboard_type": "number"
}
},
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "health",
"label": "پروانه بهداشتی",
"keyboard_type": "number"
}
},
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "health_license",
"label": "عدد اعشاری ",
"keyboard_type": "number",
"decimal": true
}
},
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "health_q",
"label": "عدد اعشاری با 2 رقم اعشار",
"keyboard_type": "number",
"decimal": true,
"decimal_places": 2
}
},
{
"type": "text_form_field",
"visible": true,
"data": {
"key": "unit_date",
"label": "نام تاریییییییییییخ",
"keyboard_type": "text",
"type": "date_picker"
}
},
{
"type": "chip_selection",
"visible": true,
"data": {
"key": "grain_quality",
"label": "کیفیت دانه",
"selectedIndex": -1,
"options": [
{
"index": 0,
"label": "خوب",
"value": "خوب"
},
{
"index": 1,
"label": "متوسط",
"value": "متوسط"
},
{
"index": 2,
"label": "ضعیف",
"value": "ضعیف"
}
]
}
},
{
"type": "dropdown",
"visible": true,
"data": {
"key": "training_status",
"label": "آموزش‌دیده در حوزه بهداشت و امنیت زیستی",
"placeholder": "آموزش‌دیده در حوزه بهداشت و امنیت زیستی",
"items": [
"بله",
"خیر"
],
"selectedValue": null,
"enabled": true
}
},
{
"type": "image_picker",
"visible": true,
"data": {
"key": "hall_images",
"label": "ثبت عکس سالن (حداقل ۳ زاویه)",
"required": true
}
},
{
"type": "image_picker",
"visible": true,
"data": {
"key": "hall_images_klllll",
"label": "ثبت عکس",
"required": true,
"max_images": 3
}
}
]
}
}
]
}
}

View File

@@ -213,15 +213,20 @@ class _RTextFieldState extends State<RTextField> {
return widget.height;
}
bool get _isMultiLine {
return (widget.maxLines != null && widget.maxLines! > 1) ||
(widget.minLines != null && widget.minLines! > 1);
}
@override
Widget build(BuildContext context) {
return SizedBox(
height: _calculateHeight().h,
child: Padding(
final Widget textField = Padding(
padding: widget.padding ?? EdgeInsets.zero,
child: TextFormField(
key: _formFieldKey,
textAlignVertical: TextAlignVertical.center,
textAlignVertical: _isMultiLine
? TextAlignVertical.top
: TextAlignVertical.center,
controller: widget.controller,
focusNode: widget.focusNode,
textAlign: widget.textAlign ?? TextAlign.start,
@@ -253,8 +258,7 @@ class _RTextFieldState extends State<RTextField> {
textDirection: textDirection,
style: widget.style,
keyboardType: widget.keyboardType,
autovalidateMode:
widget.autoValidateMode ?? AutovalidateMode.disabled,
autovalidateMode: widget.autoValidateMode ?? AutovalidateMode.disabled,
cursorColor: widget.cursorColor,
textCapitalization: widget.textCapitalization,
autocorrect: widget.autocorrect ?? true,
@@ -264,7 +268,9 @@ class _RTextFieldState extends State<RTextField> {
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(
horizontal: 16,
vertical: widget.isFullHeight ? widget.height / 3 : 0,
vertical: _isMultiLine
? 12
: (widget.isFullHeight ? widget.height / 3 : 0),
),
errorStyle: widget.errorStyle,
@@ -281,8 +287,7 @@ class _RTextFieldState extends State<RTextField> {
labelStyle: AppFonts.yekan14
.copyWith(color: AppColor.lightGreyDarkActive)
.merge(widget.labelStyle),
filled:
widget.filled || widget._noBorder || widget._passwordNoBorder,
filled: widget.filled || widget._noBorder || widget._passwordNoBorder,
fillColor: widget.filledColor,
counter: widget.showCounter ? null : const SizedBox(),
hintStyle: widget.hintStyle,
@@ -291,8 +296,15 @@ class _RTextFieldState extends State<RTextField> {
border: widget._inputBorder,
),
),
),
);
// برای فیلدهای تک خطی، ارتفاع ثابت اعمال می‌کنیم
// برای فیلدهای چند خطی، اجازه می‌دهیم ارتفاع به صورت خودکار تنظیم شود
if (_isMultiLine) {
return textField;
}
return SizedBox(height: _calculateHeight().h, child: textField);
}
@override