Implementation
Widget? buildFieldContent(
dynamic field, String container, List<dynamic> fields) {
if (field["id"] == null) {
return Container();
}
var visibility = field?['props']?['visibility'];
if (visibility != null) {
//print('FFFFFFF $visibility');
var canShow = evaluateCondition(visibility, qsParams);
if (!canShow) return Container();
}
var id = field['id'] as String;
if (field['droppableContainerId'] != null) {
var fieldContainer = field['droppableContainerId'] as String;
if (fieldContainer != container) {
return null;
}
}
if (field["props"]?["value"] != null) {
if (fieldValues[id] == null)
fieldValues[id] = replaceStringJsonPath(
field["props"]?["value"].toString() ?? '', qsParams);
}
switch (field['type']) {
case 'tab-layout':
return UXPTabContainer(
field: field, allFields: fields, fieldBuilder: buildField);
case 'horizontal-container':
return UXPHorizontalContainer(
field: field, allFields: fields, fieldBuilder: buildField);
case 'rating':
return UXPRatingField(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? '', qsParams),
filledColor: getColorFromString(field['props']?['fontColor']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'text':
return UXPFieldText(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? '', qsParams),
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
readOnly: field['readonly'] == true,
mode: field['mode'],
required: field["props"]?['fieldLabel']?["required"] ?? false,
borderColor:
getColorFromString(field["props"]?["border"]?['borderColor']),
borderWidth: parseDouble(field["props"]?["border"]?['borderWidth']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'number':
if (fieldValues[id] == null) {
fieldValues[id] = '0';
}
return UXPFieldNumber(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? '0', qsParams),
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
readOnly: field['readonly'] == false,
step: field["props"]?['step'] != null
? double.tryParse(field["props"]?['step'])
: null,
minValue: field["props"]?['minValue'] != null
? double.tryParse(field["props"]?['minValue'])
: null,
maxValue: field["props"]?['maxValue'] != null
? double.tryParse(field["props"]?['maxValue'])
: null,
allowDecimals: field["props"]?['allowDecimals'] ?? false,
allowNegativeValues: field["props"]?['allowNegativeValues'] ?? false,
required: field["props"]?['fieldLabel']?["required"] ?? false,
onChange: (value) {
fieldValues[id] = value.toString();
},
);
case 'textarea':
return UXPFieldText(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? '', qsParams),
placeholder: "",
readOnly: field['readonly'] == true,
mode: "multiline",
required: field["props"]?['fieldLabel']?["required"] ?? false,
borderColor:
getColorFromString(field["props"]?["border"]?['borderColor']),
borderWidth: parseDouble(field["props"]?["border"]?['borderWidth']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'dropdown':
return UXPFieldDropDown(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
required: field["props"]?['fieldLabel']?["required"] ?? false,
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? "", qsParams),
uiProps: field["props"],
datasources: datasources,
contextData: qsParams,
onChange: (UXPFieldDropDownItem item) {
fieldValues[id] = item.value;
});
case 'name':
if (fieldValues[id] == null)
fieldValues[id] = (AuthRepository().loggedInUser?.name ?? "");
return UXPFieldText(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? "", qsParams),
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
readOnly: field['readonly'] == true,
mode: field['mode'],
required: field["props"]?['fieldLabel']?["required"] ?? false,
borderColor:
getColorFromString(field["props"]?["border"]?['borderColor']),
borderWidth: parseDouble(field["props"]?["border"]?['borderWidth']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'email':
return UXPFieldText(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(
fieldValues[id] ?? (AuthRepository().loggedInUser?.email ?? ""),
qsParams),
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
readOnly: field['readonly'] == true,
mode: 'email',
required: field["props"]?['fieldLabel']?["required"] ?? false,
borderColor:
getColorFromString(field["props"]?["border"]?['borderColor']),
borderWidth: parseDouble(field["props"]?["border"]?['borderWidth']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'phone':
var v = replaceStringJsonPath(fieldValues[id] ?? '', qsParams);
return UXPMobileNumberInputWidget(
key: Key(id + ":" + v),
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: v,
placeholder: replaceStringJsonPath(
field["props"]?['placeholder'] ?? "", qsParams),
readOnly: field['readonly'] == true,
required: field["props"]?['fieldLabel']?["required"] ?? false,
borderColor:
getColorFromString(field["props"]?["border"]?['borderColor']),
defaultCountry: replaceStringJsonPath(
field["props"]?["defaultCountry"] ?? "", qsParams),
borderWidth: parseDouble(field["props"]?["border"]?['borderWidth']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'event-list':
return UXPEventListField(
uiProps: field['props'],
contextData: qsParams,
datasources: datasources,
);
case 'datetime':
String dv = replaceStringJsonPath(fieldValues[id] ?? '', qsParams);
return UXPFieldDateTime(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
required: field["props"]?['fieldLabel']?["required"] ?? false,
value: dv != '' ? DateTime.parse(dv) : null,
onChange: (DateTime? value) {
fieldValues[id] = value?.toUtc().toIso8601String() ?? '';
},
labelText:
replaceStringJsonPath(field["props"]['title'] ?? "", qsParams),
);
case 'date':
String dv = replaceStringJsonPath(fieldValues[id] ?? '', qsParams);
if (dv == '') {
dv = DateTime.now().toUtc().toIso8601String();
}
return UXPFieldDate(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
required: field["props"]?['fieldLabel']?["required"] ?? false,
value: dv != '' ? DateTime.parse(dv) : null,
onChange: (DateTime value) {
fieldValues[id] = value.toUtc().toIso8601String();
},
labelText: replaceStringJsonPath(
field["props"]['title'] ?? "Date", qsParams),
);
case 'time':
String dv = replaceStringJsonPath(fieldValues[id] ?? '', qsParams);
if (dv == '') {
dv = DateTime.now().toUtc().toIso8601String();
}
return UXPFieldTime(
label: field["props"]?["label"],
required: field["props"]?['fieldLabel']?["required"] ?? false,
value: dv != '' ? DateTime.parse(dv) : null,
onChange: (DateTime value) {
fieldValues[id] = value.toUtc().toIso8601String();
},
labelText: replaceStringJsonPath(
field["props"]['title'] ?? "Time", qsParams),
);
case 'daterange':
String _from = id + "_from";
String _to = id + "_to";
if (fieldValues[_from] == null) {
fieldValues[_from] = DateTime.now().toUtc().toIso8601String();
}
if (fieldValues[_to] == null) {
fieldValues[_to] =
DateTime.now().add(Duration(days: 7)).toUtc().toIso8601String();
}
return UXPFieldDateRange(
label: replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: DateTimeRange(
start: DateTime.parse(
fieldValues[_from] ?? DateTime.now().toIso8601String()),
end: DateTime.parse(fieldValues[_to] ??
DateTime.now().add(Duration(days: 7)).toIso8601String()),
),
minDate: DateTime.tryParse(field["props"]?['minDate'] ?? ""),
maxDate: DateTime.tryParse(field["props"]?['maxDate'] ?? ""),
onChange: (DateTimeRange newvalue) {
fieldValues[_from] = newvalue.start.toUtc().toIso8601String();
fieldValues[_to] = newvalue.end.toUtc().toIso8601String();
},
);
case 'label':
LMAction? lmAction;
if (field["props"]['onClick'] != null) {
lmAction = LMAction.fromJson(
convertMapStringDynamic(field["props"]['onClick']));
}
return UXPFieldLabel(
text: localizedText(
replaceStringJsonPath(field["props"]?["text"], qsParams)),
label: localizedText(
replaceStringJsonPath(field["props"]?["label"], qsParams)),
design: field["props"]?["design"] ?? 'default',
style: field["props"]?["style"],
//fieldLabel: field["props"]?["fieldLabel"]?["label"],
hideLabel: field["props"]?["hideLabel"] == true,
backgroundColor:
getColorFromString(field["props"]?["backgroundColor"]),
color: getColorFromString(field["props"]?["color"]),
fontSize: parseFontSize(field["props"]?["fontSize"] ?? 12),
icon: field["props"]?["icon"],
iconImage: field["props"]?["iconImage"],
iconPosition: field["props"]?["iconPosition"] ?? 'left',
onClick: lmAction,
data: {
'form': fieldValues.map,
'initialData': qsParams['initialData'],
'params': qsParams['params'],
},
);
case 'label-list':
return UXPFieldLabelList(
uiProps: field['props'],
binding: field['props']['binding'],
datasources: (widget.uiProps?['datasources'] as List?),
contextData: {
'form': fieldValues.map,
'initialData': qsParams['initialData'],
'params': qsParams['params'],
},
);
case 'image':
return Container(
child: CachedNetworkImage(
imageUrl: replaceStringJsonPath(field['url'] ?? '', qsParams),
imageBuilder: (context, imageProvider) => Container(
height: (field['height'] as double? ?? 200),
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: field['size'] == 'cover' ? BoxFit.cover : BoxFit.contain,
// colorFilter: ColorFilter.mode(Colors.red, BlendMode.colorBurn)
),
),
),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) =>
Column(children: [Icon(Icons.error), Text(field['alt'] ?? '')]),
));
case 'checkbox':
return UXPFieldCheckBox(
label: localizedText(replaceStringJsonPath(
field["props"]?['fieldLabel']?["label"] ?? "", qsParams)),
description: replaceStringJsonPath(
field["props"]?['fieldLabel']?["description"] ?? "", qsParams),
value: replaceStringJsonPath(fieldValues[id] ?? '', qsParams),
labelText: field["props"]?['label'] ?? '',
onChange: (value) {
fieldValues[id] = value;
},
);
case 'gps':
return UXPFieldGPS(
label: localizedText(field["props"]?['fieldLabel']?["label"]),
description:
localizedText(field["props"]?['fieldLabel']?["description"]),
value: fieldValues[id] ?? '',
labelText: localizedText(field["props"]['placeholder']),
onChange: (value) {
fieldValues[id] = value;
},
);
case 'upload':
return LMUploadField(
onChange: (value) {
fieldValues[id] = value;
},
allowOnlyOne: field["props"]['allowOnlyOnePhoto'],
text: localizedText(field["props"]['text']),
);
case 'markdown':
String data =
replaceStringJsonPath(field["props"]['text'] ?? "", qsParams);
data = data.replaceAll("![]()", "");
return UXPFieldWrapper(
child: MarkdownBody(
selectable: true,
styleSheet: MarkdownStyleSheet(
a: TextStyle(
decorationStyle: TextDecorationStyle.solid,
color: Color(0xFF0066FF))),
onTapLink: (text, url, b) async {
if (url == null) {
return;
}
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
}
},
data: data,
),
);
case "statistic":
return UXPFieldStatics(
color: getColorFromString(field["props"]['color']),
label: replaceStringJsonPath(field["props"]['label'] ?? "", qsParams),
units: replaceStringJsonPath(field["props"]['units'] ?? "", qsParams),
value: replaceStringJsonPath(field["props"]['value'] ?? "", qsParams),
icon: getIconFromName(field["props"]['icon']),
size: parseDouble(field["props"]['size']) ?? 12,
);
case 'toggle':
List<dynamic> items = field['props']?['options'] ?? [];
String _value = '';
// What is the use of selectedValues?
widget.selectedValues?.forEach((key, value) {
if (key == id) {
_value = value;
}
});
if (_value == '')
_value = replaceStringJsonPath(fieldValues[id] ?? '', qsParams);
return UXPFieldToggle(
label: localizedText(field["props"]?['title']),
description:
localizedText(field["props"]?['fieldLabel']?["description"]),
value: _value,
items: items,
buttonStyle: field["props"]?['buttonStyle'],
probs: field['props'], // take all probs
onChange: (value) {
fieldValues[id] = value;
},
);
case 'space':
var height = parseDouble(field["props"]['height']) ?? 12;
return SizedBox(
height: height,
width: height,
);
case 'seperator':
return Container(
height: (parseDouble(field["props"]['thickness']) ?? 10) * 0.1,
margin: EdgeInsets.symmetric(vertical: 4),
color: getColorFromString(field["props"]['color'] ?? '#000000'),
width: double.infinity,
);
case 'custom-ui':
return DynamicUIEx(
json: jsonDecode(field['props']?['mobile']),
qsParams: {},
context: context,
);
//return DynamicUIEx(field['props']?['mobile']?.toString() ?? "");
case 'item-card':
return new UXPCardField(
uiProps: field['props'],
contextData: qsParams,
showBottomBorder: true,
showTopBorder: true,
showFieldTitle: true,
);
case 'item-card-list':
return new UXPCardListField(
uiProps: field['props'],
contextData: qsParams,
datasources: datasources,
);
case 'carousel-with-tabs':
return new MobileCarouselWithTabs(
key: Key(field["id"]),
uiProps: field['props'],
isField: true,
contextData: qsParams,
datasources: datasources,
);
case 'profilePicture':
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () async {
setState(() {});
},
child: UserProfileAvatar(
radius: 40,
width: MediaQuery.of(context).size.width * 0.25,
height: MediaQuery.of(context).size.width * 0.25,
ivivaUser: AuthRepository().loggedInUser,
),
),
]),
);
case 'item-card-carousel':
return UXPCardCarouselField(
uiProps: field['props'],
contextData: qsParams,
dataSourceData: dataSourceData,
);
case 'additional-mobile-section':
var sectionRepo = MobileAdditionalUISectionsRepository.getInstance();
return sectionRepo?.buildField(field['props']?["fieldId"]) ??
Text("Additional Section Repo Uninitialized");
case 'map-ui':
return new UXPMapField(
uiProps: field['props'],
contextData: qsParams,
datasources: datasources,
);
case 'button':
var buttonField = field;
var title = buttonField['props']['title']?.toString() ?? "";
var iconOnly = title == "";
var fontSize = parseFontSize(buttonField['props']['fontSize'] ?? 12);
var iconSize = parseFontSize(buttonField['props']['iconSize'] ?? 12);
var borderRadius =
parseFontSize(buttonField['props']['borderRadius'] ?? 30);
if (buttonField != null) {
Widget? buttonIcon = buttonField['props']["icon"] == null
? null
: Icon(
getIconFromName(buttonField['props']["icon"]),
size: iconSize,
color: getColorFromString(
buttonField['props']["iconColor"] ?? 'white'),
);
Widget buttonText = iconOnly
? Container()
: Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: Text(
localizedText(buttonField['props']['title'].toString()),
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.w600,
color: getColorFromString(
buttonField['props']["color"],
) ??
Colors.white,
),
),
);
List<Widget> buttonWidget = [];
if ((buttonField['props']["iconPosition"] ?? "left") == "right") {
buttonWidget.add(Flexible(flex: 0, child: buttonText));
if (buttonIcon != null)
buttonWidget.add(Flexible(flex: 0, child: buttonIcon));
} else {
if (buttonIcon != null)
buttonWidget.add(Flexible(flex: 0, child: buttonIcon));
buttonWidget.add(Flexible(flex: 0, child: buttonText));
}
return GestureDetector(
child: Container(
child: Container(
margin: EdgeInsets.only(top: 0),
padding: EdgeInsets.fromLTRB(15, 15, 15, 15),
alignment: Alignment.center,
// width: 300,
decoration: BoxDecoration(
color: getColorFromString(
buttonField['props']["backgroundColor"]) ??
Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(borderRadius),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: buttonWidget,
),
),
),
onTap: () async {
if (_formKey.currentState!.validate()) {
//Navigator.pop(context);
if (buttonField["props"]['onClick'] != null) {
LMAction? lmAction = LMAction.fromJson(
convertMapStringDynamic(buttonField["props"]['onClick']));
await lmAction.execute(context, data: {
'form': fieldValues.map,
'initialData': qsParams['initialData'],
'params': qsParams['params'],
});
}
}
},
);
} else
return Container();
default:
return Container();
}
}