單的本質是業務,沒有表單是無法完成業務系統的,而動態表單使業務系統更高級。動態表單是什么呢?它是如何工作的?應用場景有哪些?一起來看一下吧。
表單在網頁中主要負責數據采集功能,是提交數據的一切形式。表單的本質是提交數據,不僅僅包含輸入框、下拉選擇框等這些控件,常見的按鈕空間也屬于一個表單。
動態表單(Dynamic Form),指在前端運行過程中可依賴某些業務邏輯發生表單項變化的表單,還包括表單布局、表單數據管理、表單校驗、表單交互、表單項聯動邏輯等原本由前端編程完成的表單開發,轉由后端通過 API 接口輸出表單描述自動完成上述所有內容的表單開發形式。
(動態表單原理示意圖)
表單的本質是業務,而動態表單使業務系統更高級。
普通表單是一個表單寫一份前端的代碼,代碼全部由前端開發者完成(后端配合接口輸出)。而動態表單則是一個表單對應一個 JSON(由后端輸出),所有表單由一份代碼(動態表單引擎)進行加載和渲染。
所以,動態表單具有以下優勢:
表單控件是提供一組允許用戶操作的對象,從而接收用戶輸入的數據,用戶可操作該對象來執行對表單設計,修改等操作。
input元素無疑是一個龐大和復雜的元素,但它并不是唯一的表單控件。還有button、select、option、label、optgroup、textarea、fieldset、legend這八個傳統表單控件,datalist、progress、meter、output、keygen這五個新增表單控件。
動態表單是老廠商天翎核心技術之一,也是天翎公司核心產品MyApps的重要組成部分。通過對于動態表單的應用,可以避免在電子流程系統中硬編碼的數據采集及處理表單,提高系統的可維護性。
說明:
Form,動態表單實現的基本入口,描述了DynaForm的最基本屬性,比如名稱、ID、以及最核心的TemplateContext。TemplateContext中保存的是Form的描述XML,通過此XML描述兩類信息:
FormElement,接口,表示Form中的基本元素;
FormField,動態表單的最基本元素,在myApps/OBPM中被聲明為Abstract,具體Object行為依賴于具體的SubClass實現;
TextField,單行文本框,繼承FormField;
SelectField,下拉選擇框,繼承FormField;
TextareaField,多行文本框,繼承FormField;
CheckBoxField,復選框,繼承FormField;
RadioBoxField,單選框,繼承FormField;
Textpart,靜態文本段,除各種Field以外的靜態文本部分,繼承FormElement;
ComponentField,自定義組件,繼承FormField;
AttachmentUploadField,附件上傳組件,繼承FormField;
ImageUploadField,圖片上傳組件,繼承FormField;
ViewDialogField,視圖組件,用于實現主從結構的表單,繼承FormField;
CalctextField,計算文本組件,用于實現需要計算的文本,繼承FormField;
IncludeField,實現SubForm的包含,繼承FormField;
WordField,Word組件,繼承FormField;
OcrField,為將來預留的接口,系統暫未實現;
表單引擎是為快速實施項目研發的輕量級表單設計工具。采用表單引擎工具可在不開發和新增加代碼的情況下設計出新表單樣式,同比程序開發可省掉程序員差不多70%的開發工作量,并且后期維護相對簡單,管理方便。
在了解了表單的基本機構后,進一步看看表單引擎是如何工作的。
從客戶端(Client)輸入數據(Document),比如一個excel文件,表單(Form)結合excel文件自動生成HTML,如下圖:
(表單結合文檔生成HTML過程)
(XML解析為表單對象的過程)
(表單轉為HTML過程)
(表單生成數據庫)
天翎Myapps低代碼開發平臺的表單引擎是基于Web界面上可視化編輯的表單設計系統,同時支持印刷模式和拖拽模式兩種設計方式,形象可見,操作方便。印刷模式可以做一些復雜的表單配置,同時還支持word表格的導入;拖拽模式:基于Vue的表單設計器,采用可視化拖拉拽的模式進行表單的設計。
(表單前臺)
(表單后臺)
本文由 @周志軍Jarod 原創發布于人人都是產品經理,未經作者許可,禁止轉載。
題圖來自Unsplash,基于CC0協議
該文觀點僅代表作者本人,人人都是產品經理平臺僅提供信息存儲空間服務。
什么是表單呢?當前端想要提交數據給后端,怎么搞?那么在前端開發中,表單是常用的手段,比如常見的場景有:登錄框、賬號注冊頁、主機信息錄入CMDB等等場景都是需要表單。那么在本篇中,筆者除了講一些基本的知識點,還會再結合后端的方式來演示如何接收表單提交的數據。希望這些小小的演示可以起到拋磚引玉的效果。
構建表單,主要是通過from元素,我們先來一個最簡單的小栗子,看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>主機信息錄入CMDB</h3>
<form>
<label for="hostname">主機名:</label><br>
<input type="text" id="hostname" name="hostname"><br>
<label for="ipaddr">IP地址:</label><br>
<input type="text" id="ipaddr" name="ipaddr"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
通上面的小栗子可以知道,form表單的主要通途是用于收集用戶的輸入。在from表單里面,還包含著各種不同類型的input元素,比如我們上面小栗子中用到的文本(text)、提交按鈕(submit)。
input元素是表單里最重要的元素,它有很多type屬性,下面我們來總結下:
類型描述text文本輸入radio單選按鈕checkbox提交按鈕submit提交按鈕button可單擊按鈕
在上面小栗子中,除了input元素之外,不知道大家注意label元素沒有。label元素的主要用途是為input元素定義標簽,且用for屬性和input元素的id屬性進行綁定呢。
什么是單選按鈕?就是在多個選項中,你只能選其中1個,不能多選。下面我們看個小栗子,看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>問答題1(單選):某站長,工作經驗不足1年,僅從互聯網收集學習資料制定學習路線售賣盈利,從道德層面角度分析是否有問題?</h3>
<form>
<input type="radio" id="i1" name="problem" value="yes">
<label for="i1">有</label>
<input type="radio" id="i2" name="problem" value="no">
<label for="i2">沒有</label>
<input type="radio" id="i3" name="problem" value="not_clear">
<label for="i3">不清楚</label>
</form>
<h3>問答題2(單選):實際工作經驗不足1年的人員折騰的學習資料您覺得是否對你有幫助?</h3>
<form>
<input type="radio" id="w1" name="problem" value="yes">
<label for="w1">有</label>
<input type="radio" id="w2" name="problem" value="no">
<label for="w2">沒有</label>
<input type="radio" id="w3" name="problem" value="not_clear">
<label for="w3">不清楚</label>
</form>
</body>
</html>
效果如下圖:
上面的小栗子中,出了兩道問答題,均為單選題。那么,類似的需求都是可以使用輸入類型為radio來實現需要使用單選按鈕的場景。
什么是復選框?復選框就是可以選擇多個選項,當需要多選的時候,使用復選框輸入類型就對了。看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>問答題1(單選):某站長,工作經驗不足1年,僅從互聯網收集學習資料制定學習路線售賣盈利,從道德層面角度分析是否有問題?</h3>
<form>
<input type="checkbox" id="i1" name="problem" value="yes">
<label for="i1">有</label>
<input type="checkbox" id="i2" name="problem" value="no">
<label for="i2">沒有</label>
<input type="checkbox" id="i3" name="problem" value="not_clear">
<label for="i3">不清楚</label><br>
<input type="submit" value="提交">
</form>
<h3>問答題2(單選):實際工作經驗不足1年的人員折騰的學習資料您覺得是否對你有幫助?</h3>
<form>
<input type="checkbox" id="w1" name="problem" value="yes">
<label for="w1">有</label>
<input type="checkbox" id="w2" name="problem" value="no">
<label for="w2">沒有</label>
<input type="checkbox" id="w3" name="problem" value="not_clear">
<label for="w3">不清楚</label><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
上面的小栗子中,實現復選框的輸入類型是checkbox,這個是重點哦!
當有數據要提交給后端的時候怎么搞?如果后端是API服務,可以給它提交json。如果是前端頁面,就需要通過構建表單來獲取用戶的輸入。基于表單提交數據給后端,怎么提交?需要一個可以點擊的提交按鈕,那這個按鈕怎么來?先看下面代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form>
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
效果如下圖:
輸入類型為submit,說明它就是提交按鈕,注意上面代碼type="submit"了嗎?
在之前的例子中,前端表單需要將數據提交給后端,除了需要一個提交按鈕外,還需要action屬性。當點擊提交按鈕后,表單的數據該發到后端的哪個url進行處理,就是定義在action屬性中。接下來,我們結合前端和后端直接來個小實戰,后端代碼用Python的Flask框架。
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼:
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=["GET", "POST"])
def ttropsstack():
args = request.args
print 'ip addr is: %s' % args.get('ip')
return 'ok'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
前端和后端的代碼寫完后,我們接下來看看效果
輸入IP地址后,點擊提交
這個ok是后端返回的
后端接收到數據后,啥也沒做,只是做了簡單打印
這個小栗子很簡單,通過這個小栗子,是不是對action屬性的用法有了進一步的理解呢?
method屬性的用途是指定提交數據的http方法,通常有2個,get和post。接下來我們在上個小栗子的基礎上做個小改造,看下面代碼
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="get">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼:
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=["POST"])
def ttropsstack():
args = request.args
print 'ip addr is: %s' % args.get('ip')
return 'ok'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
當前端輸入數據后,提交表單時,直接告訴你這是不允許的方法
在這個例子中,是因為前端的表單了指定了method為get請求,而后端接收數據的method規定了需要post請求,故所以出現這個問題。
下面我們改造一下后端代碼:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
print request.get_data(as_text=True)
return 'ok'
else:
return '提交數據需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
前端表單中的method還是保持get請求,再次提交,后端的返回如下:
看到了嗎?后端判斷前端過來的請求是get還是post,很顯然,前端過來的請求是get,并且返回了非常友好的提示。
接下來我們繼續改造一下前端的代碼,將請求修改為post,代碼如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<h3>主機信息</h3>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="ipaddr">IP地址</label>
<input type="text" id="ipaddr" name="ip"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
后端代碼也稍微改造一下,改變接收前端數據的方法
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
a = request.form
print a.get('ip')
print type(a)
return 'ok'
else:
return '提交數據需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
輸入IP地址,并點擊提交
提交后,后端給前端返回了ok
接下來看下后端,后端啥也沒做,就獲取到表單的數據,然后打印了數據,并且打印了下數據類型
好了,關于前端的action屬性和Method屬性就講到這里了。為了講解action和method,還結合了后端的一丟丟知識,前端和后端的知識點以后都會慢慢講到哈!
先來個前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="opslist">運維開發應掌握的技能:</label>
<select id="opslist" name="opslist">
<option value="python">Python語言</option>
<option value="go">Go語言</option>
<option value="shell">Shell語言</option>
<option value="database">數據庫</option>
<option value="frontend">前端</option>
<option value="linux">Linux</option>
<option value="network">網絡</option>
<option value="storage">存儲</option>
</select>
<input type="submit">
</form>
</body>
</html>
后端代碼:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
a = request.form
print a.get('opslist')
return 'ok'
else:
return '提交數據需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
在下拉框中選擇“Go語言”,并提交
后端啥也沒干,就只做了打印
前端代碼:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>彩虹運維技術棧社區主頁</title>
</head>
<body>
<h2>彩虹運維技術棧社區,公眾號ID:TtrOpsStack</h2>
<form action="http://192.168.11.10:8088/ttropsstack" target="_blank" method="post">
<label for="opslist">運維開發應掌握的技能:</label>
<select id="opslist" name="opslist" size="6" multiple>
<option value="python">Python語言</option>
<option value="go">Go語言</option>
<option value="shell">Shell語言</option>
<option value="database">數據庫</option>
<option value="frontend">前端</option>
<option value="linux">Linux</option>
<option value="network">網絡</option>
<option value="storage">存儲</option>
</select>
<input type="submit">
</form>
</body>
</html>
上述前端代碼中,是使用multiple屬性來實現選擇多個值。
后端代碼的打印方式稍微做了些許調整:
# coding: utf8
from flask import Flask, request
webapp = Flask(__name__)
@webapp.route('/ttropsstack', methods=['GET','POST'])
def ttropsstack():
if request.method == 'POST':
data = request.get_data()
print data
return 'ok'
else:
return '提交數據需要post請求'
if __name__ == '__main__':
webapp.run(host="0.0.0.0", port=8088, debug=True)
按住ctrl或者shift鍵可進行多選
后端打印的效果圖下圖:
關于表單基礎知識點的講解就這么愉快的結束了,關于更多表單的元素、輸入屬性、輸入類型可自行查閱和實戰,筆者因時間有限就不一一演示。感謝您的閱讀,望多多關注我們、點贊、轉發!
本文轉載于(喜歡的盆友關注我們):https://mp.weixin.qq.com/s/L-Msv39JrF7AzRx4K1OLjA
lement UI 目前在中后臺項目中應用廣泛,是十分流行的 Vue 組件框架。而表單元素,作為最常用的用戶輸入組件,在設計開發過程中幾乎都要涉及,且往往大同小異。能不能減少重復的代碼編寫工作呢?能不能甚至不寫代碼,點幾下鼠標就能生成想要的表單呢?Form-Generator,這個基于 Element UI 框架 Form 元素的表單設計與代碼生成器,就能解放你的雙手。
ElementUI框架
Form-Generator,是 JakHuang 在 Github 和碼云上開源的表單設計與代碼生成器,項目代碼位于 https://github.com/JakHuang/form-generator,國內鏡像位于 https://gitee.com/mrhj/form-generator。
Form-Generator 基于 Element UI 組件庫的 Form 表單組件,開發了一個表單設計器,可以在設計器中,點選不同的輸入組件構建表單,設計器則會自動生成對應的 Vue 代碼,可以項目中使用。也可以把設計好的表單以 JSON 的格式導出,方便存儲傳輸,使用時利用配套的解析器把 JSON 解析為設計好的表單即可使用。
form-generator使用
Form-Generator 需要 Node.js 10+,可以使用 NPM 進行安裝:
npm i fms-form-generator
也可以自行下載項目代碼進行構建:
git clone https://github.com/JakHuang/form-generator.git
然后安裝依賴,使用 YARN
yarn
或 NPM 安裝依賴
npm install
在本地運行表單設計器,運行
npm run dev
也可以構建之后進行部署
npm run build
Form-Generator 項目配套有 JSON 解析器,可以把 JSON 轉化為真實的表單代碼,可以使用 NPM 安裝:
npm i form-gen-parser
另外,form-generator 還有配套的 VSCode 插件 Form Generator Plugin,使用 VSCode 的開發者們可以進行安裝,幫助完成基本的表單代碼搭建任務。
fms-form-generator庫
Form-Generator 的主要界面是一個表單設計器:
表單設計器
可以看到,界面的左側擺放了不同的輸入組件,包括單行文本、計數器、下拉選擇、日期范圍和按鈕等,基本滿足了一般項目對于表單的所有需求。
表單設計器的組件選擇
界面中間是設計得到的表單,點擊左側的組件,便可在表單中添加。同時,表單中還提供了組件的復制和刪除功能,可以自由進行編輯。
界面的右側是組件屬性和表單屬性,可以對當前選中的組件的各項屬性進行修改,如字段名、標題、標簽寬度、默認值、尺寸等,進行所需組件的定制;也可以對表單屬性進行修改,包括表單模型、校驗模型、標簽對齊等,實現表單層級的配置。
組件屬性編輯
在完成了表單的設計之后,就可以點擊界面上部的運行按鈕,在這里我們可以選擇生成類型,包括頁面和彈窗兩種,其中彈窗類型會把表單嵌入到對話框組件中。
生成類型
完成類型選擇后,我們就能得到生成的 Vue 代碼,包括 Vue 模板、JS 和 CSS 代碼:
Vue模板代碼
JS代碼
可以看到,生成的代碼可讀性高,質量較好,可以直接引入到項目中進行使用。代碼生成器也提供了一個美觀的編輯器界面,可以直接對生成的代碼進行編輯,并在右側重新渲染修改的表單。
除了直接生成代碼外,form-generator 還提供了把表單導出為 JSON 格式的功能,便于進行存儲和傳輸。Form-generator 設計了一種具有特定格式的 JSON 格式用于 Element UI 表單的表示,可以在代碼生成器中直接導出 JSON 文件,使用時再利用配套的 form-gen-parser 進行解析,重新生成表單代碼。
form-generator的JSON表示
表單的JSON表示以fields列表存儲各表單項,各表單項一般包括:
以此 JSON 文件,便可還原表單,得到生成的 Vue 代碼。我們還可以以此為模板,添加變量,只需修改 JSON 數據就進行相似表單的自動化批量生成。
表單的JSON表示
Form-Generator 作為 Element UI 的表單設計和代碼生成器,簡化了表單的設計和代碼編寫工作,使得表單的設計工作也能夠“所見即所得”,在一些前端設計定制化要求不高的場景下,使用起來十分方便,既使得設計人員能夠獲得期望的表單設計,也減輕了代碼開發人員的在前端設計方面的額外工作,一舉兩得。
Form-Generator 的實現需要對于 Vue 和 ElementUI 十分熟悉,尤其在表單的 JSON 表示的生成和解析方面的工作,頗具技巧;同時,該項目本身也是一個優秀的前端應用,感興趣的開發者可以進行代碼的閱讀學習,參與開源貢獻。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。