About the editor
First come to a gif, have a preliminary understanding
Sorry, the picture is a bit blurry
github: https://github.com/Liberty-liu/Everright-formEditor
demo: https://everright.site/zh-cn/module/formEditor/introduction.html
Everright-formEditor is a visual editor based on vue3, which depends on element-plus and vant for development. An adapter is provided internally for parameter transcoding.
- Flexible interaction(You can decide whether to insert a field into a row or a column by dragging and dropping, without a layout container)
- Providing multiple components(Input,email,ID number、Cellphone,URL,Textarea,Number,Radio,Checkbox,Time,Date,Rate,Switch,Slider,Html,Cascader,Upload file,Signature,Region)
- Layout fields(Grid、Table、Tabs、Collapse、Divider)
- i18n(Chinese and English)
- Built-in two modes:Fields and layout not separated、Fields and layout separated
- The editor,previewer,and configuration panel can all be used independently, and the configuration panel can be selectively used separately according to actual needs to meet the needs of different scenarios
Sample screenshot
Editor
Previewer on PC
Previewer on mobile
Config panel
Internal realization principle
Field
Field as one of the elements
In the form editor, the main operation is an element, the layout container(also one of the elements) is used as the carrier of the Field. use the following figure to represent a Field,and the Field itself will have many attributes.
Note the white pattern in the upper right corner, indicating that the internal properties of this Field are jointly determined by the input of the two pipelines.
- From the canvas panel and the selection below the canvas panel
- From the configuration panel configuration properties
Field is inserted into the Canvas drawing board by the user's click or drag and drop
Canvas
Use the following figure to represent the Canvas drawing board
The data inside the Canvas drawing board is represented by a two-dimensional array Array[r][c]
, where r is the row and c is the column. In fact, it is the same as the table, and the interior can be nested infinitely (the layout container can be nested ).
When an element is inserted into the Canvas artboard, the element will be automatically wrapped by Selection.
Selection
Use the following figure to represent the Selection
The white area in the figure represents the slot, where elements are placed.
Selection provides whether it can be dragged, deleted, copied, resized, and parented.
When an element is selected, it will be highlighted on the Canvas panel.
Config panel
Use the following figure to represent the configuration panel
Used to configure field properties.
When an element is selected, the Config panel will display all the properties of the selected element itself
Data Flow Diagram
Combined with the above schematic diagram, the user's behavior is shown in the following diagram
- Solid arrows represent user actions
- Solid arrow with a dot represents an automatically occurring event
- Dashed arrows indicate data flow
Add a paragraph of text description to facilitate understanding
- When the user drags an element into the artboard by clicking or dragging, the editor will automatically wrap a selection for the element
- When the user selects the selection area, the Config panel will display all the properties of the selected element itself
- When the user modifies the attribute of the element through the Config panel or the Selection (Selection), the data will be synchronized to the Canvas drawing board, so that what you see is what you get
Adapter
Use the following figure to represent the adapter
Since pc depends on element-plus, and mobile depends on vant, the functional parameters of the intersection between them are somewhat different, and the adapter does this physical work.
example
The Rate rating component wants to set the number of stars ⭐️, the element-plus parameter is max, and the vant is count.
Insert a little code below to show what the adapter does
if (!isPc) {
result.count = options.max
} else {
result.max = options.max
}
Two modes of the editor
Recall that the main data flowing inside the editor is elements, which are divided into fields and layout containers.
The real data inside the editor is a tree structure.
By default, the editor adopts a mode in which the layout and fields are not separated. Of course, the mode in which the layout and fields are separated is also supported.
-
layoutType1 Fields and layout not separated
Designing the form on the PC side will adapt to the mobile side.
-
layoutType2 Fields and layout separated
When designing a form on a PC, for example, if a field such as "email" is placed in a tabs container, switching to the mobile end will not synchronize the tabs container. In this case, if a new Collapse container is created on mobile and the email field is placed in it, switching to the PC end will not synchronize the Collapse container. For fields added on one end, when switching to the other end, with newly added fields pushed to the bottom of the canvas and deleted fields removed from the layout structure. All properties of the fields themselves are synchronized.
Regardless of the mode used, the exported data will extract the fields, and for the backend, they are more concerned with the fields rather than the tree structure.
About the internal drag and drop principle
The implementation relies on sortablejs, but inserting rows or columns is not supported by sortablejs. When inserting a row, wrap it with an inline container (inserting an element in a row will automatically wrap it with a virtual inline container). In short, when dragging an element, if a row is inserted, an inline container will be wrapped; if a column is inserted, it will be inserted below the inline container.
Therefore, a sortablejs plugin was written to intercept dragOver and drop events to achieve this.
When dragging, the dragOver event is continuously triggered. Based on the x/y coordinates of the current mouse position, it is determined in which of the four directions of the target element to insert a row or a column. The four directions are determined based on the slope calculation, which can be easily understood by referring to a figure. When dropping, the last dragOver element and instance are recorded to implement the feature.
Existing functional defects
- history record
- Reflect the tree structure interface
- GUI mode to control field display and hiding and logic verification
The above functions will be developed next
Top comments (1)
could we setup logical control for each fields? What I seeing from the demo the logical control is applies to form-attribute globally?