custom-form-fields
Creating Custom form fields
The library automatically generates a form based on Java entity classes. It automatically generates form fields (e.g., TextField, DateField, SearchableSelectField, etc.) based on entity attributes and annotations. It defaults to a TextField ie
<input type="text" name="" id="" placeholder="" required value="">
To generate a custom input type like image field, you can annotate your entity field with @FormInputType.The annotation @FormInputType allows you to define how a field should be rendered on the admin form:
@Entity
public class Product {
@Id
private UUID id;
// renders input type text
@FormInputType(FormInputType.Type.TEXT)
private String name;
// renders intype type number
@FormInputType(FormInputType.Type.NUMBER)
private Double price;
// renders input type file
@FormInputType(FormInputType.Type.IMAGE)
private String thumbnail;
// renders quill editor
@FormInputType(FormInputType.Type.WYSIWYG)
private String description;
// getters & setters...
}
This means you can declaratively control whether a field appears as a textbox, number input, image uploader, WYSIWYG editor, etc., just by annotating the field.
Kraft Admin will automatically reflect this in the UI form without extra frontend code.
Supported form fields
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FormInputType {
Type value(); // type of input field
enum Type {
TEXT, NUMBER, COLOR, CHECKBOX, IMAGE, DATE, EMAIL, PASSWORD, FILE, TEXTAREA, WYSIWYG, DATETIME, TIME, RANGE, TEL, URL, RADIO, CURRENCY
}
}
Example of a customized entity
@Entity(name = "talents")
@Table(name = "talents")
public class Talent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
@Size(min = 3, max = 256, message = "Name should not be less than 3 characters long")
private String name;
@Enumerated(EnumType.STRING)
private Gender gender;
private List<String> hobbies;
private LocalDate dob;
@Column(length = 3000)
@FormInputType(value = FormInputType.Type.TEXTAREA)
private String about;
private Boolean isHirable;
private Integer age;
// @FormInputType(FormInputType.Type.CURRENCY)
private Double salary;
private LocalTime timeAvailable;
@Embedded
// @DisplayField("address")
private Contact contact;
@Lob
@Basic(fetch = FetchType.LAZY)
private byte[] introVideo;
@FormInputType(FormInputType.Type.COLOR)
private String favColor;
@FormInputType(FormInputType.Type.IMAGE)
private String avatar;
@FormInputType(FormInputType.Type.FILE)
private String resume;
@FormInputType(FormInputType.Type.PASSWORD)
private String password;
@FormInputType(FormInputType.Type.EMAIL)
private String email;
@FormInputType(FormInputType.Type.TEL)
private String phone;
@FormInputType(FormInputType.Type.URL)
private String url;
@OneToMany(mappedBy = "talent", fetch = FetchType.EAGER)
@DisplayField("title")
private List<Project> projects;
// @ElementCollection
// private List<Experience> experiences;
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
}
which gives the following in UI

Use FormInputType.CURRENCY, FormInputType.RADIO and FormInputType.RANGE with caution. They haven't been implemented fully.