JSFiddle - React, Tailwind, and code Playground
by niuuin
HTML
<main>
<form id="user-form">
<h2>添加用户</h2>
<input type="number" name="index" hidden>
<input type="text" name="username" placeholder="用户名">
<input type="text" name="email" placeholder="邮箱">
<input type="number" name="balance" placeholder="余额">
<button type="submit">提交</button>
</form>
<table id="user-table">
<thead>
<th>用户名</th>
<th>邮箱</th>
<th>余额</th>
<th class="text-right">操作</th>
</thead>
<tbody></tbody>
</table>
</main>
CSS
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
:root {
font-family: sans-serif;
font-size: 15px;
}
input, button {
border: 1px solid;
padding: .5em;
font-size: inherit;
margin-bottom: .5em;
}
form input,
form button {
width: 100%;
}
button {
background: #000;
color: #fff;
}
main {
padding: .5em;
margin-left: auto;
margin-right: auto;
max-width: 40em;
}
.error-container {
font-size: 90%;
padding: .5em;
background: pink;
color: #c10;
margin-bottom: .5em;
}
input.error {
border: 2px solid #c10;
outline: 0;
}
table {
width: 100%;
text-align: left;
border-collapse: collapse;
}
td, th {
padding: .5em;
border-bottom: 1px solid rgba(0, 0, 0, .1);
}
th {
border-width: 2px;
border-color: #888;
}
[hidden] {
display: none;
}
.text-right {
text-align: right;
}
JavaScript
/*
|--------------------------------------------------------------------------
| biaoForm.js
|--------------------------------------------------------------------------
| * 快速存取数据
| * 自定义提交行为
*/
;(function () {
'use strict';
let form;
// 将biaoForm暴露出去,否则别的文件访问不到
window.biaoForm = function (selector, onSubmit) {
form = document.querySelector(selector);
form.addEventListener('submit', e => {
e.preventDefault();
onSubmit(getData());
form.reset();
});
return {
getData, // 相当于 getData: getData
setData, // 相当于 setData: setData
};
};
/**
* 解析表单数据(取值)
* @param {HTMLFormElement} form 选好的form元素
* @return {Object}
*/
function getData () {
// 初始化纯数据,否则解析后的数据没地方存
let data = {};
// 取到所有输入组件,也就是所有有name属性的元素
// 如<input name="xxx">或者<textarea name="xxx">...
let inputs = form.querySelectorAll('[name]');
// 循环所有的输入组件
inputs.forEach(it => {
// it就是每个输入组件
// 以<input name="age" value="10">为例:
// it.name ==> 'age'
// it.value ==> '10'
// 检查组件的类型
switch (it.type) {
// 如果是数字,就将值转换为数字类型
case 'number':
data[ it.name ] = parseFloat(it.value);
break;
// 如果是单选框
case 'radio':
// 检查它当前是否打钩了,如果没打勾就跳过
if (!it.checked)
return;
// 否则就存到data中
// ↓'age' ↓10
data[ it.name ] = it.value;
break;
// 如果是复选框,那么取到的值就应该是个数组,
// 因为可能会选中多项
case 'checkbox':
// 第一次碰到复选框,就应该将data中对应的那一项初始化为空数组
// 否则后面没法推入选中的值
if (!Array.isArray(data[ it.name ]))
data[ it.name ] = [];
/*
如果当前的复选框打钩了,就应该推入到数组中
<input value=a checked>
<input value=b checked> ==> ['a', 'b']
<input value=c>
*/
if (it.checked)
data[ it.name ].push(it.value);
break;
// 如果是以下类型中的任何一项
case 'date':
...