mirror of https://gitee.com/karson/fastadmin.git
CRUD生成紧凑型表单、优化validator提示
parent
96192945a9
commit
63bab7ee88
|
|
@ -483,6 +483,7 @@ class Crud extends Command
|
|||
//循环所有字段,开始构造视图的HTML和JS信息
|
||||
foreach ($columnList as $k => $v) {
|
||||
$field = $v['COLUMN_NAME'];
|
||||
$langField = mb_ucfirst($field);
|
||||
$itemArr = [];
|
||||
// 这里构建Enum和Set类型的列表数据
|
||||
if (in_array($v['DATA_TYPE'], ['enum', 'set', 'tinyint'])) {
|
||||
|
|
@ -540,6 +541,7 @@ class Crud extends Command
|
|||
$formEditElement = $this->getReplacedStub('html/select', ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
||||
} else if ($inputType == 'datetime') {
|
||||
$cssClassArr[] = 'datetimepicker';
|
||||
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
|
||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||
$format = "YYYY-MM-DD HH:mm:ss";
|
||||
$phpFormat = "Y-m-d H:i:s";
|
||||
|
|
@ -595,6 +597,7 @@ class Crud extends Command
|
|||
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldList' => $this->getFieldListName($field), 'attrStr' => Form::attributes($attrArr), 'selectedValue' => "\$row.{$field}"]);
|
||||
} else if ($inputType == 'textarea') {
|
||||
$cssClassArr[] = $this->isMatchSuffix($field, $this->editorSuffix) ? $this->editorClass : '';
|
||||
$attrArr['placeholder'] = "{:__('Please input')}{:__('{$langField}')}";
|
||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||
$attrArr['rows'] = 5;
|
||||
$formAddElement = Form::textarea($fieldName, $defaultValue, $attrArr);
|
||||
|
|
@ -615,17 +618,20 @@ class Crud extends Command
|
|||
$formAddElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => $defaultValue, 'fieldSwitchClass' => $defaultValue == $no ? $stateNoClass : '']);
|
||||
$formEditElement = $this->getReplacedStub('html/' . $inputType, ['field' => $field, 'fieldName' => $fieldName, 'fieldYes' => $yes, 'fieldNo' => $no, 'attrStr' => Form::attributes($attrArr), 'fieldValue' => "{\$row.{$field}}", 'fieldSwitchClass' => "{eq name=\"\$row.{$field}\" value=\"{$no}\"}fa-flip-horizontal text-gray{/eq}"]);
|
||||
} else if ($inputType == 'citypicker') {
|
||||
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
|
||||
$attrArr['class'] = implode(' ', $cssClassArr);
|
||||
$attrArr['data-toggle'] = "city-picker";
|
||||
$formAddElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $defaultValue, $attrArr));
|
||||
$formEditElement = sprintf("<div class='control-relative'>%s</div>", Form::input('text', $fieldName, $editValue, $attrArr));
|
||||
} else {
|
||||
$attrArr['placeholder'] = "{:__('Please input')}{:__('{$langField}')}";
|
||||
$search = $replace = '';
|
||||
//特殊字段为关联搜索
|
||||
if ($this->isMatchSuffix($field, $this->selectpageSuffix)) {
|
||||
$inputType = 'text';
|
||||
$defaultValue = '';
|
||||
$attrArr['data-rule'] = 'required';
|
||||
$attrArr['placeholder'] = "{:__('Please select')}{:__('{$langField}')}";
|
||||
$cssClassArr[] = 'selectpage';
|
||||
$selectpageController = str_replace('_', '/', substr($field, 0, strripos($field, '_')));
|
||||
$attrArr['data-source'] = $selectpageController . "/index";
|
||||
|
|
@ -1243,8 +1249,8 @@ EOD;
|
|||
$langField = mb_ucfirst($field);
|
||||
return <<<EOD
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-12 col-sm-2">{:__('{$langField}')}:</label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<label for="c-{$field}" class="control-label">{:__('{$langField}')}:</label>
|
||||
<div class="pp_container">
|
||||
{$content}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1270,11 +1276,11 @@ EOD;
|
|||
return <<<EOD
|
||||
<div class="input-group">
|
||||
{$content}
|
||||
<span class="msg-box n-top" for="c-{$field}"></span>
|
||||
<div class="input-group-addon no-border no-padding">
|
||||
<span><button type="button" id="plupload-{$field}" class="btn btn-danger plupload" data-input-id="c-{$field}"{$uploadfilter}{$multiple}{$preview}><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
|
||||
<span><button type="button" id="fachoose-{$field}" class="btn btn-primary fachoose" data-input-id="c-{$field}"{$selectfilter}{$multiple}><i class="fa fa-list"></i> {:__('Choose')}</button></span>
|
||||
</div>
|
||||
<span class="msg-box n-right" for="c-{$field}"></span>
|
||||
</div>
|
||||
{$previewcontainer}
|
||||
EOD;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||
|
||||
<form id="add-form" role="form" data-toggle="validator" method="POST" action="">
|
||||
{%addList%}
|
||||
<div class="form-group layer-footer">
|
||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<div class="pp_container text-center">
|
||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -31,5 +31,15 @@ class {%controllerName%} extends Backend
|
|||
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
|
||||
*/
|
||||
|
||||
/**
|
||||
* 导入
|
||||
*/
|
||||
/*
|
||||
public function import()
|
||||
{
|
||||
return parent::import();
|
||||
}
|
||||
*/
|
||||
|
||||
{%controllerIndex%}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
|
||||
|
||||
<form id="edit-form" role="form" data-toggle="validator" method="POST" action="">
|
||||
{%editList%}
|
||||
<div class="form-group layer-footer">
|
||||
<label class="control-label col-xs-12 col-sm-2"></label>
|
||||
<div class="col-xs-12 col-sm-8">
|
||||
<div class="pp_container text-center">
|
||||
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
|
||||
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
<div class="radio">
|
||||
<div class="radio" id="c-{%field%}">
|
||||
{foreach name="{%fieldList%}" item="vo"}
|
||||
<label for="{%fieldName%}-{$key}"><input id="{%fieldName%}-{$key}" name="{%fieldName%}" type="radio" value="{$key}" {in name="key" value="{%selectedValue%}"}checked{/in} /> {$vo}</label>
|
||||
{/foreach}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
<select {%attrStr%}>
|
||||
<select {%attrStr%}>
|
||||
{foreach name="{%fieldList%}" item="vo"}
|
||||
<option value="{$key}" {in name="key" value="{%selectedValue%}"}selected{/in}>{$vo}</option>
|
||||
{/foreach}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|||
add_url: '{%controllerUrl%}/add',
|
||||
edit_url: '{%controllerUrl%}/edit',
|
||||
del_url: '{%controllerUrl%}/del',
|
||||
//import_url: '{%controllerUrl%}/import',
|
||||
multi_url: '{%controllerUrl%}/multi',
|
||||
table: '{%table%}',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -995,6 +995,40 @@ table.table-nowrap thead > tr > th {
|
|||
.wipecache li a {
|
||||
color: #444444 !important;
|
||||
}
|
||||
|
||||
.col-md-1-5 {
|
||||
width: 20% !important;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.col-xs-1-5,.col-sm-1-5,.col-md-1-5,.col-lg-1-5 {
|
||||
min-height: 1px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.col-sm-1-5 {
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.col-md-1-5 {
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.col-lg-1-5 {
|
||||
width: 20%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
div.pre {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
|
|
@ -1009,6 +1043,11 @@ div.pre {
|
|||
border-radius: 3px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#add-form .panel-body,#edit-form .panel-body{
|
||||
padding-bottom:0;
|
||||
}
|
||||
|
||||
/*修正开关关闭下的颜色值*/
|
||||
.btn-switcher.disabled {
|
||||
opacity: .6;
|
||||
|
|
|
|||
|
|
@ -12,9 +12,244 @@ define(['jquery', 'bootstrap', 'upload', 'validator'], function ($, undefined, U
|
|||
validClass: 'has-success',
|
||||
invalidClass: 'has-error',
|
||||
bindClassTo: '.form-group',
|
||||
formClass: 'n-default n-bootstrap',
|
||||
msgClass: 'n-right',
|
||||
formClass: 'n-yellow n-bootstrap',
|
||||
msgClass: 'n-top',
|
||||
theme: 'yellow_top',
|
||||
stopOnError: true,
|
||||
rules: {
|
||||
mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"],
|
||||
email: [/^[0-9A-Za-z][\.-_0-9A-Za-z]*@[0-9A-Za-z]+(\.[0-9A-Za-z]+)+$/, "请填写有效的邮箱地址"],
|
||||
chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"],
|
||||
money: [/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/, "请填写有效的金额"],
|
||||
ip: [/^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i, '请填写有效的 IP 地址'],
|
||||
// 身份证
|
||||
idcard: function (element) {
|
||||
var value = element.value,
|
||||
isValid = true;
|
||||
var cityCode = {11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江 ", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北 ", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏 ", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外 "};
|
||||
|
||||
/* 15位校验规则: (dddddd yymmdd xx g) g奇数为男,偶数为女
|
||||
* 18位校验规则: (dddddd yyyymmdd xxx p) xxx奇数为男,偶数为女,p校验位
|
||||
|
||||
校验位公式:C17 = C[ MOD( ∑(Ci*Wi), 11) ]
|
||||
i----表示号码字符从由至左包括校验码在内的位置序号
|
||||
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
|
||||
Ci 1 0 X 9 8 7 6 5 4 3 2
|
||||
*/
|
||||
var rFormat = /^\d{6}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$|^\d{6}\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}$/; // 格式验证
|
||||
|
||||
if (!rFormat.test(value) || !cityCode[value.substr(0, 2)]) {
|
||||
isValid = false;
|
||||
}
|
||||
// 18位身份证需要验证最后一位校验位
|
||||
else if (value.length === 18) {
|
||||
var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子
|
||||
var Ci = "10X98765432"; // 校验字符
|
||||
// 加权求和
|
||||
var sum = 0;
|
||||
for (var i = 0; i < 17; i++) {
|
||||
sum += value.charAt(i) * Wi[i];
|
||||
}
|
||||
// 计算校验值
|
||||
var C17 = Ci.charAt(sum % 11);
|
||||
// 与校验位比对
|
||||
if (C17 !== value.charAt(17)) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid || "请填写正确的身份证号码";
|
||||
},
|
||||
// 银行卡(借记卡、贷记卡)
|
||||
bankcard: function (element) {
|
||||
var value = element.value.replace(/\s/g, ''),
|
||||
isValid = true,
|
||||
rFormat = /^[\d]{12,19}$/;
|
||||
|
||||
if (!rFormat.test(value)) {
|
||||
isValid = false;
|
||||
} else {
|
||||
var arr = value.split('').reverse(),
|
||||
i = arr.length,
|
||||
temp,
|
||||
sum = 0;
|
||||
|
||||
while (i--) {
|
||||
if (i % 2 === 0) {
|
||||
sum += +arr[i];
|
||||
} else {
|
||||
temp = +arr[i] * 2;
|
||||
sum += temp % 10;
|
||||
if (temp > 9) sum += 1;
|
||||
}
|
||||
}
|
||||
if (sum % 10 !== 0) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid || "请填写有效的银行卡号";
|
||||
},
|
||||
// 信用卡
|
||||
creditcard: function (element, params) {
|
||||
var value = element.value,
|
||||
validTypes = 0x0000,
|
||||
types = {
|
||||
mastercard: 0x0001,
|
||||
visa: 0x0002,
|
||||
amex: 0x0004,
|
||||
dinersclub: 0x0008,
|
||||
enroute: 0x0010,
|
||||
discover: 0x0020,
|
||||
jcb: 0x0040,
|
||||
unknown: 0x0080
|
||||
};
|
||||
|
||||
if (/[^0-9\-]+/.test(value)) {
|
||||
return false;
|
||||
}
|
||||
value = value.replace(/\D/g, "");
|
||||
|
||||
if (!params) {
|
||||
validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
|
||||
} else {
|
||||
for (var i = 0; i < parmas.length; i++) {
|
||||
validTypes |= types[params[i]];
|
||||
}
|
||||
}
|
||||
|
||||
if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
|
||||
return value.length === 16;
|
||||
}
|
||||
if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
|
||||
return value.length === 16;
|
||||
}
|
||||
if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
|
||||
return value.length === 15;
|
||||
}
|
||||
if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
|
||||
return value.length === 14;
|
||||
}
|
||||
if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
|
||||
return value.length === 15;
|
||||
}
|
||||
if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
|
||||
return value.length === 16;
|
||||
}
|
||||
if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
|
||||
return value.length === 16;
|
||||
}
|
||||
if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
|
||||
return value.length === 15;
|
||||
}
|
||||
if (validTypes & 0x0080) { //unknown
|
||||
return true;
|
||||
}
|
||||
return "请填写有效的信用卡号";
|
||||
},
|
||||
// 组织机构代码证
|
||||
orgcode: function (element) {
|
||||
var value = element.value,
|
||||
isValid = true,
|
||||
rFormat = /^[A-Z\d]{8}-[X\d]/;
|
||||
|
||||
if (!rFormat.test(value)) {
|
||||
isValid = false;
|
||||
} else {
|
||||
var Wi = [3, 7, 9, 10, 5, 8, 4, 2];
|
||||
var Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
// 加权求和
|
||||
var sum = 0;
|
||||
for (var i = 0; i < 8; i++) {
|
||||
sum += Ci.indexOf(value.charAt(i)) * Wi[i];
|
||||
}
|
||||
// 计算校验值: C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
|
||||
var C9 = 11 - (sum % 11);
|
||||
if (C9 === 10) C9 = 'X';
|
||||
else if (C9 === 11) C9 = 0;
|
||||
C9 = '' + C9;
|
||||
// 与校验位比对
|
||||
if (C9 !== value.charAt(9)) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return isValid || "请填写正确的组织机构代码";
|
||||
},
|
||||
// 营业执照号
|
||||
bizcode: function (element) {
|
||||
var value = element.value,
|
||||
isValid = true,
|
||||
rFormat = /^[1-6]\d{14}$/;
|
||||
|
||||
// 共15位:6位首次登记机关代码 + 8位顺序码 + 校验位
|
||||
if (!rFormat.test(value)) {
|
||||
isValid = false;
|
||||
} else {
|
||||
var s = [],
|
||||
p = [10];
|
||||
|
||||
for (var i = 0; i < 15; i++) {
|
||||
s[i] = (p[i] % 11) + (+value.charAt(i));
|
||||
p[i + 1] = (s[i] % 10 || 10) * 2;
|
||||
}
|
||||
if (1 !== s[14] % 10) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
return isValid || "请填写正确的营业执照号";
|
||||
},
|
||||
// 统一社会信用代码
|
||||
unicode: function (element) {
|
||||
var value = element.value.replace(/^\s*|\s*$/g, ''),
|
||||
isValid = true,
|
||||
rFormat = /^[1-9A-GV][1239][1-9]\d{5}[A-Z\d]{8}[X\d][Y\d]/;
|
||||
|
||||
if (!rFormat.test(value)) {
|
||||
isValid = false;
|
||||
} else {
|
||||
var code, Wi, Ci, sum, C9, C18;
|
||||
|
||||
// 计算组织机构代码校验位:C9 = 11 - MOD ( ∑(Ci*Wi), 11 )
|
||||
code = value.slice(9, 17);
|
||||
Wi = [3, 7, 9, 10, 5, 8, 4, 2];
|
||||
Ci = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
// 加权求和
|
||||
sum = 0;
|
||||
for (var i = 0; i < Wi.length; i++) {
|
||||
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
|
||||
}
|
||||
C9 = 11 - (sum % 11);
|
||||
if (C9 === 10) C9 = 'X';
|
||||
else if (C9 === 11) C9 = 0;
|
||||
C9 = '' + C9;
|
||||
// 与校验位比对
|
||||
if (C9 !== code.charAt(9)) {
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
// 计算最后校验位:C18 = 31 - MOD ( ∑(Ci*Wi), 31 )
|
||||
code = value.slice(0, 17);
|
||||
Wi = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28];
|
||||
Ci = "0123456789ABCDEFGHJKLMNPQRTUWXY";
|
||||
// 加权求和
|
||||
sum = 0;
|
||||
for (var i = 0; i < Wi.length; i++) {
|
||||
sum += Ci.indexOf(code.charAt(i)) * Wi[i];
|
||||
}
|
||||
C18 = 31 - (sum % 31);
|
||||
if (C18 === 30) C18 = 'Y';
|
||||
else if (C18 === 31) C18 = 0;
|
||||
C18 = '' + C18;
|
||||
// 与校验位比对
|
||||
if (C18 !== code.charAt(18)) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isValid || "请填写正确的统一社会信用代码";
|
||||
}
|
||||
},
|
||||
display: function (elem) {
|
||||
return $(elem).closest('.form-group').find(".control-label").text().replace(/\:/, '');
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue