FileUpload
FileUpload
is a component that allows to view and attach single file
Info
- When a file is selected, it is stored in the storage system immediately, which then generates a unique "file ID". When the save button is clicked, only this "file ID" is sent to the backend
- If a new file is selected, it will be saved as a new file in storage. Previous file remains untouched (e.g. one is free to implement custom deletion logic)
Basics
How does it look?
How to add?
Example
For the entire application, a single file storage solution needs to be defined. In this example file storage is minio.
Step1 FileStorage Add file storage. see more
FileStorage
Step2 Add same String fields to corresponding BaseEntity.
@Entity
@Getter
@Setter
@NoArgsConstructor
public class MyEntity extends BaseEntity {
@Column
private String customField;
@Column
private String customFieldId;
}
Step3 Add two String fields (for file name and id) to corresponding DataResponseDTO.
@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {
@SearchParameter(name = "customField")
private String customField;
@SearchParameter(name = "customFieldId")
private String customFieldId;
public MyExampleDTO(MyEntity entity) {
this.id = entity.getId().toString();
this.customField = entity.getCustomField();
this.customFieldId = entity.getCustomFieldId();
}
}
Step4 Add to .widget.json.
Step4 Add to .widget.json.
{
"name": "MyExampleInfo",
"title": "Info title",
"type": "Info",
"bc": "myExampleBc",
"fields": [
{
"label": "Custom Field",
"key": "customField",
"type": "fileUpload",
"fileIdKey": "customFieldId"
}
],
"options": {
"layout": {
"rows": [
{
"cols": [
{
"fieldKey": "customField",
"span": 12
}
]
}
]
}
}
}
Step4 Add to .widget.json.
{
"name": "MyExampleForm",
"title": "Form title",
"type": "Form",
"bc": "myExampleBc",
"fields": [
{
"label": "Custom Field",
"key": "customField",
"type": "fileUpload",
"fileIdKey": "customFieldId"
}
],
"options": {
"layout": {
"rows": [
{
"cols": [
{
"fieldKey": "customField",
"span": 12
}
]
}
]
}
}
}
Placeholder
Placeholder
allows you to provide a concise hint, guiding users on the expected value. This hint is displayed before any user input. It can be calculated based on business logic of application
How does it look?
not applicable
How to add?
Example
Add fields.setPlaceholder to corresponding FieldMetaBuilder.
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
Long id, Long parentId) {
fields.setEnabled(MyExampleDTO_.customFieldId);
fields.setEnabled(MyExampleDTO_.customField);
fields.setPlaceholder(MyExampleDTO_.customField, "Placeholder text");
}
Works for List.
not applicable
Works for Form.
Color
not applicable
Readonly/Editable
Readonly/Editable
indicates whether the field can be edited or not. It can be calculated based on business logic of application
Editable
Live Sample ·
GitHub
Readonly
Live Sample ·
GitHub
How does it look?
not applicable
How to add?
Example
Step1 Add mapping DTO->entity to corresponding VersionAwareResponseService.
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
BusinessComponent bc) {
if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
entity.setCustomFieldId(data.getCustomFieldId());
}
if (data.isFieldChanged(MyExampleDTO_.customField)) {
entity.setCustomField(data.getCustomField());
}
return new ActionResultDTO<>(entityToDto(bc, entity));
}
Step2 Add fields.setEnabled to corresponding FieldMetaBuilder.
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
Long id, Long parentId) {
fields.setEnabled(MyExampleDTO_.customField);
//
}
Works for List.
not applicable
Works for Form.
Option 1 Enabled by default.
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
Long id, Long parentId) {
}
Option 2 Not recommended.
Property fields.setDisabled() overrides the enabled field if you use after property fields.setEnabled.
Works for List.
Works for Info.
Works for Form.
Filtering
Filtering
allows you to search data based on criteria.
For FileUpload field
filtering is case-insensitive and retrieves records containing the specified value at any position of file name (similar to SQL Like %value%
).
How does it look?
not applicable
not applicable
How to add?
Example
Step 1 Add @SearchParameter to corresponding DataResponseDTO. (Advanced customization SearchParameter)
@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {
@SearchParameter(name = "customField")
private String customField;
@SearchParameter(name = "customFieldId")
private String customFieldId;
public MyExampleDTO(MyEntity entity) {
this.id = entity.getId().toString();
this.customField = entity.getCustomField();
this.customFieldId = entity.getCustomFieldId();
}
}
Step 2 Add fields.enableFilter to corresponding FieldMetaBuilder.
@Override
public void buildIndependentMeta(FieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription, Long parentId) {
if (configuration.getForceActiveEnabled()) {
fields.setForceActive(MyExampleDTO_.customField);
}
fields.enableFilter(MyExampleDTO_.customField);
fields.enableSort(MyExampleDTO_.customField);
}
not applicable
not applicable
Drilldown
not applicable
Validation
Validation
allows you to check any business rules for user-entered value. There are types of validation:
1) Exception:Displays a message to notify users about technical or business errors.
Business Exception
:
Live Sample ·
GitHub
Runtime Exception
:
Live Sample ·
GitHub
2) Confirm: Presents a dialog with an optional message, requiring user confirmation or cancellation before proceeding.
3) Field level validation: shows error next to all fields, that validation failed for
Option 1
:
Live Sample ·
GitHub
Option 2
:
Live Sample ·
GitHub
How does it look?
not applicable
How to add?
Example
BusinessException
describes an error within a business process.
Add BusinessException to corresponding VersionAwareResponseService.
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
BusinessComponent bc) {
if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
entity.setCustomFieldId(data.getCustomFieldId());
}
if (data.isFieldChanged(MyExampleDTO_.customField)) {
entity.setCustomField(data.getCustomField());
if (!String.valueOf(data.getCustomField()).matches("[A-Za-z]+")) {
throw new BusinessException().addPopup(ONLY_LETTER);
}
}
return new ActionResultDTO<>(entityToDto(bc, entity));
}
Works for List.
not applicable
Works for Form.
RuntimeException
describes technical error within a business process.
Add RuntimeException to corresponding VersionAwareResponseService.
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
BusinessComponent bc) {
if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
entity.setCustomFieldId(data.getCustomFieldId());
}
if (data.isFieldChanged(MyExampleDTO_.customField)) {
try {
//call custom function
throw new Exception("Error");
} catch (Exception e) {
throw new RuntimeException("An unexpected error has occurred.");
}
}
return new ActionResultDTO<>(entityToDto(bc, entity));
}
Works for List.
not applicable
Works for Form.
Add PreAction.confirm to corresponding VersionAwareResponseService.
@Override
public Actions<MyExampleDTO> getActions() {
return Actions.<MyExampleDTO>builder()
.action(act -> act
.action("save", "save")
.withPreAction(PreAction.confirm("You want to save the value ?"))
)
.build();
}
Works for List.
not applicable
Works for Form.
Add javax.validation to corresponding DataResponseDTO.
Use if:
Requires a simple fields check (javax validation)
@Getter
@Setter
@NoArgsConstructor
public class MyExampleDTO extends DataResponseDTO {
@SearchParameter(name = "customField")
@Pattern(regexp = "[A-Za-z]+", message = ONLY_LETTER)
private String customField;
@SearchParameter(name = "customFieldId")
private String customFieldId;
public MyExampleDTO(MyEntity entity) {
this.id = entity.getId().toString();
this.customField = entity.getCustomField();
this.customFieldId = entity.getCustomFieldId();
}
}
Works for List.
not applicable
Works for Form.
Create сustom service for business logic check.
Use if:
Business logic check required for fields
Step 1
Create сustom method for check.
private void validateFields(BusinessComponent bc, MyExampleDTO dto) {
BusinessError.Entity entity = new BusinessError.Entity(bc);
if (!String.valueOf(dto.getCustomField()).matches("[A-Za-z]+")) {
entity.addField(MyExampleDTO_.customField.getName(), "The field 'customField' can contain only letters.");
}
if (!String.valueOf(dto.getCustomFieldAdditional()).matches("[A-Za-z]+")) {
entity.addField(
MyExampleDTO_.customFieldAdditional.getName(),
"The field 'customFieldAdditional' can contain only letters."
);
}
if (entity.getFields().size() > 0) {
throw new BusinessException().setEntity(entity);
}
}
Step 2
Add сustom method for check to corresponding VersionAwareResponseService.
@Override
protected ActionResultDTO<MyExampleDTO> doUpdateEntity(MyEntity entity, MyExampleDTO data,
BusinessComponent bc) {
validateFields(bc, data);
if (data.isFieldChanged(MyExampleDTO_.customFieldAdditionalId)) {
entity.setCustomFieldAdditionalId(data.getCustomFieldAdditionalId());
}
if (data.isFieldChanged(MyExampleDTO_.customFieldAdditional)) {
entity.setCustomFieldAdditional(data.getCustomFieldAdditional());
}
if (data.isFieldChanged(MyExampleDTO_.customFieldId)) {
entity.setCustomFieldId(data.getCustomFieldId());
}
if (data.isFieldChanged(MyExampleDTO_.customField)) {
entity.setCustomField(data.getCustomField());
}
return new ActionResultDTO<>(entityToDto(bc, entity));
}
Sorting
Sorting
allows you to sort data in ascending or descending order.
FileUpload field
is a text field, so lexicographic sorting is used for it
How does it look?
not applicable
not applicable
How to add?
Example
Enabled by default.
not applicable
not applicable
Required
Required
allows you to denote, that this field must have a value provided.
How does it look?
not applicable
How to add?
Example
Add fields.setRequired to corresponding FieldMetaBuilder.
@Override
public void buildRowDependentMeta(RowDependentFieldsMeta<MyExampleDTO> fields, InnerBcDescription bcDescription,
Long id, Long parentId) {
fields.setEnabled(MyExampleDTO_.customFieldId);
fields.setEnabled(MyExampleDTO_.customField);
fields.setRequired(MyExampleDTO_.customField);
}
Works for List.
not applicable
Works for Form.