Submit and view custom tables
1. Usage scenarios
In YIDA, simple form submission can be implemented using ordinary forms, but ordinary forms cannot customize table styles. When we need complex table styles and submit them, how should we implement them? In YIDA, you can use custom pages for development. Custom pages include JSX and HTML Components to implement complex business scenarios. This document shows you how to configure the submission and viewing of custom tables.
2. Video tutorial
3. Procedure
3.1 Step 1: Create a data dependency form
Data dependency forms: data dependency forms are used to store data submitted on custom pages.
To pass data from a custom page to a form page through an interface, you need to obtain the unique identifier of the form page. Note that the handwritten signature component cannot pass values directly on the interface, therefore, use a single line of text as an aid.
Figure 3.1 data dependency form
3.2 Step 2: Create a custom submission page
3.2.1 form making tools
Generate a table style within the link:https://www.tablesgenerator.com/html_tables#
Note: Table making tools TablesGenerator is an online table code tool in LaTeX, HTML, and Markdown formats. It supports filling data in tables, modifying font/background colors, and aligning methods.
Figure 3.2-1 use TablesGenerator
Copy the code into JSX,JSX>Edit JSX code >Copy and paste the code
Figure 3.2-2 draw a table
Copy the generated styleJSX>Style>Source code editing. You can change the style by yourself in source code editing.
Figure 3.2-3 Copy to JSX source code editing
The following code can be directly copied to the source code for editing.
/*JSX样式->源码编辑*/
.tg {border-collapse:collapse;border-spacing:0;width:100%}
.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
overflow:hidden;padding:10px 5px;word-break:normal;}
.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px;
font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;}
.tg .tg-34fe{background-color:#c0c0c0;border-color:inherit;text-align:center;vertical-align:top}
.tg .tg-c3ow{border-color:inherit;text-align:center;vertical-align:top;}
.next-form-item{
margin:0
}
Obtain component tags>Define attributes>Rendering component
Figure 3.2-4 JSX rendering components
3.2.2 use variable data sources in JSX
In the future, you need to reuse attributes and pass values to the interface to add and view data. You need to use variable data sources to define attributes.
Define Variable Data sources>Replace attribute values with variables>Rendering component
Figure 3.2-5 set variable data source
Define a onchange method in the js panel, and then use this.onChange in JSX to set the onchange properties of the component. The function is to update the component value to the variable data source and render it.
Figure 3.2-6 obtain component values update variable data sources
The following code can be directly copied and edited in the JS panel,Note: the unique identifier of the JSX component is required.
export function onChange({ value }, index) {
//console.log(value, index);
//给 componentIds 变量数据源的 index 下标赋 value 值
this.state.componentIds[index] = value;
this.$('JSX_kt9ikv55').forceUpdate();
}
The following code can be directly copied and edited in JSX code.Note: to configure the variable data source and change the unique identifier to the unique identifier of the dependent form.
//JSX代码
function render(me, state, data, ctx) {
//将变量数据源引入到JSX中使用
const { radioDatas, componentIds, componentStatus } = this.state;
return (
<div>
<table class="tg">
<thead>
<tr>
<th class="tg-34fe" colspan="20">测试表格</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-c3ow" colspan="4">单选</td>
<td class="tg-c3ow" colspan="6"><RadioField dataSource={radioDatas} value={componentIds.radioField_kt8hni6y} onChange={(value) => { this.onChange(value, 'radioField_kt8hni6y') }} behavior={componentStatus} /></td>
<td class="tg-c3ow" colspan="4">日期</td>
<td class="tg-c3ow" colspan="6"><DateField value={componentIds.dateField_kt8hni6z} onChange={(value) => { this.onChange(value, 'dateField_kt8hni6z') }} behavior={componentStatus} /></td>
</tr>
<tr>
<td class="tg-c3ow" colspan="4">手写签名</td>
<td class="tg-c3ow" colspan="6"><DigitalSignatureField useLastSignature={false} value={componentIds.textField_kt8i83vj} onChange={(value) => { this.onChange(value, 'textField_kt8i83vj') }} behavior={componentStatus} /></td>
<td class="tg-c3ow" colspan="4">多行文本</td>
<td class="tg-c3ow" colspan="6"><TextareaField placeholder={"请输入"} value={componentIds.textareaField_kt8hni71} onChange={(value) => { this.onChange(value, 'textareaField_kt8hni71') }} behavior={componentStatus} /></td>
</tr>
<tr>
<td class="tg-c3ow" colspan="4">下拉单选</td>
<td class="tg-c3ow" colspan="6"><SelectField dataSource={radioDatas} hasClear={true} value={componentIds.selectField_kt8hni72} onChange={(value) => { this.onChange(value, 'selectField_kt8hni72') }} behavior={componentStatus} /></td>
<td class="tg-c3ow" colspan="4">数值</td>
<td class="tg-c3ow" colspan="6"><NumberField value={componentIds.numberField_kt8hni73} onChange={(value) => { this.onChange(value, 'numberField_kt8hni73') }} behavior={componentStatus} /></td>
</tr>
<tr>
<td class="tg-c3ow" colspan="4">单行文本</td>
<td class="tg-c3ow" colspan="6"><TextField hasClear={true} placeholder={"请输入"} value={componentIds.textField_kt8hni74} onChange={(value) => { this.onChange(value, 'textField_kt8hni74') }} behavior={componentStatus} /></td>
<td class="tg-c3ow" colspan="4">成员</td>
<td class="tg-c3ow" colspan="6"><EmployeeField hasClear={true} value={componentIds.employeeField_kt8hni75} onChange={(value) => { this.onChange(value, 'employeeField_kt8hni75') }} behavior={componentStatus} /></td>
</tr>
</tbody>
</table>
</div>
);
}
3.2.3 configure submit button
To make the page beautiful, you can drag a container component to place the button component into the container component and set the container style.
Configure remote data sources>Button Assembly>Action settings> onclik click event
The variable data source changes to the loading state when clicking submit, and disables the button and components on the page after the submission is completed. You are not allowed to click submit for the second time.
Call the remote data source 「Add a form instance"Interface to update the value of the component to after the onclik event is triggered.componentIds in the variable data source, the value is used as the request parameter to the interface to store the value of the custom page component to the form. In order to inform the custom page whether the submission is completed, a pop-up message box is defined. A prompt is configured for the submission success or failure.
Figure 3.2-7 data sources required to store data in dependent tables
Figure 3.2-call the interface to pass parameters when clicking the button at 8 points
The following code can be directly copied and edited in the JS panel.Note: replace formUuid and appType and complete the above operations before.
export function onClick(){
const componentIds = this.state.componentIds
console.log('componentIds',componentIds);
let loading = this.utils.toast({
type: "loading",
title: "提交中..."
});
this.setState({
bthLoading: true
});
let params = {
formUuid: "FORM-XJ866N71G7ET96RS09BNI5ZCKIZM3ZPO6F9TK13",
appType: "APP_JKH50FL33A0H8GJBQEHL",
formDataJson: JSON.stringify(componentIds)
};
this.dataSourceMap.createData.load(params).then(res => {
console.log(res);
if (res) {
loading();
this.utils.toast({
type: "success",
title: "提交成功!"
});
this.setState({
componentStatus: "DISABLED",
bthLoading: false,
bthStatus: "DISABLED",
});
}
}).catch(err => {
console.log(err);
loading();
this.utils.toast({
type: "error",
title: "提交失败!"
});
});
}
3.3 Step 3: Create a custom View page
Table components> configure a remote data source> bind a table data source> add a data column title and data field
For more information, see:Customize page tables to implement data management page functions
Figure 3.3-1 configure table components
Note that the handwritten signature component is an image and needs to be set.Custom rendering of columns.
Figure 3.3-2 set custom rendering images
The following code can be directly copied and edited in the JS panel.
export function renderCell(value, index, rowData) {
return <span>
<img src={value} style={{ display: "block", width: "100px" }} />
</span>;
}
3.4 Step 4: configure a custom View page
How to view data after submitting data is also a custom submitted table style.
3.4.1 The Custom Data View page carries parameters to the custom submit page.
Set the action column of the table>Add an action item named details>Click edit>Bind callback actions
Figure 3.4.1 Bind operation column callback function
The following code can be directly copied and edited in the JS panel,Note: replace the link with the custom submit page access link.
export function onActionClick(rowData) {
console.log(rowData)
this.utils.router.push("https://www.aliwork.com/APP_JKH50FL33A0H8GJBQEHL/custom/FORM-WO966N71Z6ETTREN3TD4T9QQWDG72EOPEH9TK85", { formInstId: rowData.formInstId }, true, true);
}
3.4.2 receive parameters on the custom submission page and call the interface to obtain the values of dependent tables and display them on the page.
(1) define remote data getDataById
Interface reference documents:Query Form instance details based on form instance ID
(2) write data back to the page through the passed Form ID
Bind the didmount event when the page is loaded, receive the parameter formInstId carried by the jump link and send it to the getDataById data source as the request parameter. After the data source is loaded, change the value in the variable.
Bind didimount and trigger
The following code can be directly copied to the JS panel.
export function didMount() {
console.log(`「页面 JS」:当前页面地址 ${location.href}`);
// console.log(`「页面 JS」:当前页面 id 参数为 ${this.state.urlParams.id}`);
// 更多 this 相关 API 请参考:https://www.yuque.com/yida/support/ocmxyv#OCEXd
// document.title = window.loginUser.userName + ' | 宜搭';
const { urlParams } = this.state;
if (urlParams.formInstId) {
let params = {
formInstId: urlParams.formInstId
};
this.dataSourceMap.getDataById.load(params).then(res => {
console.log(res);
this.setState({
//用远程数据源返回值赋值给componentIds变量
//给JSX内behavior属性引用的componentStatus变量赋值为只读
//给按钮绑定的状态赋值为禁用,最终让组件重定向渲染
componentIds: res.formData,
componentStatus: "READONLY",
bthStatus: "DISABLED",
});
this.$('JSX_kt9ikv55').forceUpdate();
});
}
}
3.5 temporary storage function
After the above operations are completed, you can refer to the following content to describe how to implement the temporary storage function of a custom page.
Prepare two pages: a temporary form and a custom submit page created above.
3.5.1 create a temporary storage form
Temporary storage form: used to store data stored temporarily on custom pages.
Note: the unique identifier of the temporary form component must be the same as that of the data-dependent form,Therefore, copy the dependent form page or copy the component to ensure that the unique identifier of the component is the same.
Two new components are added to the temporary storage form to store the Operation Manual Number of the temporary storage person ID and the temporary storage time to store the operation time.
Temporary form page
3.5.2 create a custom temporary save button
(1) define remote data sources
Add a form instance: The function is to pass the data in the custom page component to the dependency/temporary form for subsequent calls.
Search form instance details by criteria: The function is to call the interface to find the data of the current login person in the temporary storage table and make a judgment in the data processing. If there is a pop-up window to remind the user whether to reuse it, the returned data is sent to the componentIds variable data source.
Delete a form instance: determines that the data in the staging table is deleted after the data is reused on the page.
Temporary storage of required remote data sources
Perform data processing in the remote data source of the search form instance, and use the dialog method defined in the JS panel to make a pop-up dialog box. For more information, see the following code.
//远程数据源的数据处理
function didFetch(content) {
if (content.totalCount != 0) {
//调用 JS 面板的 dialog 方法并传参
this.dialog(content.data[0]);
}
return content; // 重要,需返回 content
}
// JS 面板中的方法
export function dialog(data) {
//暂存回写dialog
console.log(data);
//用于弹出对话框
this.utils.dialog({
method: 'confirm',
title: '提示',
content: `您于${this.utils.formatter("date", data.formData.dateField_kti1seu4, 'YYYY年MM月DD日hh时mm分ss秒')}暂存了一条数据,是否填充到表单内?`,
footerActions: ['cancel', 'ok'],
onOk: () => {
let params = {
formInstId: data.formInstId
};
//调用删除表单实例的接口删除这条数据
this.dataSourceMap.delTemporaryData.load(params);
this.setState({
componentIds: data.formData
});
//给变量数据源赋值后 JSX 渲染
this.$('JSX_kt9ikv55').forceUpdate();
},
onCancel: () => {
//当点击取消时将暂存按钮状态设置为禁用,需提前定义名为temporaryBtnStatus的变量数据源
this.setState({
temporaryBtnStatus: "DISABLED"
});
},
});
}
(2) define variable data sources
temporaryBtnLoading: the loading status of the temporary storage button
temporaryBtnStatus: temporary button status
Control the status of the temporary storage button
(3) drag button component binding action
Button binding action
The following code can be copied directly into the JS panel,Note: You need to change formUuid, appType, and the unique identifier of the temporary person ID/temporary time.
export function onClick2() {
//暂存按钮绑定动作
const { componentIds } = this.state;
//唯一标识需要替换成暂存表单中的暂存人ID和暂存时间唯一标识
componentIds.textField_kti1seu3 = window.loginUser.userId; //暂存人ID
componentIds.dateField_kti1seu4 = new Date().getTime(); //暂存时间
let loading = this.utils.toast({
type: "loading",
title: "暂存中..."
});
this.setState({
temporaryBtnLoading: true
});
//需要替换formUuid和appType
let params = {
formUuid: "FORM-2T866B813EITKW2P59M9KCYDINQB2144S1ITKHK",
appType: "APP_JKH50FL33A0H8GJBQEHL",
formDataJson: JSON.stringify(componentIds)
};
this.dataSourceMap.createData.load(params).then(res => {
console.log(res);
if (res) {
loading();
this.utils.toast({
type: "success",
title: "暂存成功!"
});
this.setState({
componentStatus: "DISABLED",
temporaryBtnLoading: false,
bthStatus: "DISABLED",
temporaryBtnStatus: "DISABLED"
});
}
}).catch(err => {
console.log(err);
loading();
this.utils.toast({
type: "error",
title: "暂存失败!"
});
});
}
4. Achieve results
Demonstration of JSX's implementation of custom tables
5. Try it online
Submit the online experience of the page, please go to the Developer Center👉Submit a custom form
To view the online experience on the page, go to the Developer Center.👉Custom table view
-------------------- Get the latest information YIDA, welcome to follow US--------------------