若html自带的输入控件,如text、select等都无法满足你的需求时,可以编写自定义输入控件,如多级联动下拉列表、ip地址输入框,此时,仅需定义控件的渲染html和取值规则即可。
可以使用 AForm.registerControl(myControlName,[baseName],obj)
来注册一个输入控件,参数解释:
一个完整的输入控件需包含如下几个方法:
render(k, v, conf, i, af,jpath)
用于渲染控件,返回渲染后的htmlrenderComplete(rootElement)
用于渲染控件,返回渲染后的htmlgetJsonPartString(ele)
返回控件的键值对字符串注册输入控件事实上是创建了一个类,一旦任意一个aform使用了该控件,则创建了该控件的一个实例,控件实例有这么一些属性,可在组件的任何方法中使用this
调用:
this.config
当前输入控件的配置,即aform针对该字段的配置信息this.name
当前字段的name或indexthis.aform
当前控件所在的aform实例this.rootElement
当前控件渲染后的包裹器dom元素(注意getJsonPartString返回的是键值对字符串,而不仅仅是值)
使用控件非常简单,设置字段的type
为你注册的控件名即可,如type:"myControlName"
,aform会自动寻找已注册的控件并调用它相关的方法渲染和取值。
使用 AForm.registerControl(myControlName,obj)
即可注册一个输入控件
//注册一个带两个输入框的区间输入控件
AForm.registerControl("rangeInput": {
desc: "区间范围输入框",
render: function (k, v, config , i ,af) {
v = v.split(",");
var html = "";
var itemType = config.itemType || "text";
html += "<input style='" + config.ctrlCssText + "' class='form-control' name=\"" + k + "_begin\" type='text' itemType='" + itemType + "' value='" + v[0] + "' />";
html += " - ";
html += "<input style='" + config.ctrlCssText + "' class='form-control' name=\"" + k + "_end\" type='text' itemType='" + itemType + "' value='" + (v[1] || "") + "' />";
return html;
},
"getJsonPartString": function (ele,conf)//ele为插件的外层容器dom对象
{
var ips = ele.getElementsByTagName("input");
var k = ips[0].name.replace("_begin", "");
return "\"" + k + "\":\"" + ips[0].value + "," + ips[1].value + "\"";
}
});
注意:getJsonPartString 是返回一个key-value键值对,而不是纯粹的value,建议使用双引号包裹key,否则若key包含空格、中划线则在后续的解析中将会报语法错误
设置字段的type属性为控件名即可:
var jf = new AForm("divOutput",{
fields:{
range:{label:"价格区间",type:"rangeInput"}//注意type的值即控件注册的名字
}
});
jf.render()
可以使用 AForm.registerControl(name,baseName,obj)
来继承一个输入控件,并可覆盖父控件的render
或getJsonPartString
方法,并可以通过 this.__super
来引用父控件原型。
//基类控件
AForm.registerControl("date", {
desc:"date",
render: function(k, v, conf, i, af) {
return "我是date";
},
getJsonPartString: function(ele) {
return "my value";
}
});
//子控件
AForm.registerControl("datetime", "date", {
desc:"datetime",
render: function(k, v, conf, i, af) {
var html = this.__super.render.call(this ,k, v, conf, i, af);//this.__super 为父类对象
html += " -- datetime";
return html;
}
});
//继承aform默认的基本输入控件,针对控件仅包含一个input的情况
//这样直接使用父类的getJsonPartString方法而无需自己实现
AForm.registerControl("myControl", "__AFORM_BASIC_PLUGIN__", {...});
字段的type
设置了字段使用的输入控件,如type:"text"
代表使用单行文本输入框,但aform会先寻找是否注册了名为text
的自定义输入控件,若有,则优先使用自定义的输入控件,因此运用这一特性,可以重写传统 html 的输入控件,增加自己业务需要的特性。
范例:
//完全自己实现render和getJsonPartString
AForm.registerControl("text", {...});
AForm.registerControl("select", {...});
AForm.registerControl("textarea", {...});
//继承aform基本输入控件
AForm.registerControl("text", "__AFORM_BASIC_PLUGIN__", {...});
AForm.registerControl("select", "__AFORM_BASIC_PLUGIN__", {...});
AForm.registerControl("textarea", "__AFORM_BASIC_PLUGIN__", {...});
使用renderComplete函数即可绑定事件。
范例(注册一个日期选择器):
//继承aform基本输入控件,避免重写取值函数
AForm.registerControl("datetime", "__AFORM_BASIC_PLUGIN__", {
desc: "日期",
render: function(k, v, conf, i, af,jpath) {
conf.pattern = conf.pattern || ymdPattern;//校验年月日格式
//公共属性
var attrHtml = [];
if (conf.required) {
attrHtml.push("required");
}
if (conf.readonly) {
attrHtml.push("readonly");
}
if (conf.disabled) {
attrHtml.push("disabled");
}
var id = 'ele-date-' + i;
this.id = id;
attrHtml.push("name='" + k +"'");
attrHtml.push("jpath='" + jpath +"'");
attrHtml.push("value='" + v +"'");
attrHtml.push("id=" + id);
attrHtml.push("class='json-field-input datetime dpl-text dpl-text-calendar " + AForm.Config.extClassName.control + "'");
attrHtml = attrHtml.join(" ");
var html = "<input " + attrHtml + " />";
return html;
},
renderComplete:function(rootElement){
var dp = new Datepicker({
target: "#" + this.id
});
dp.on("select", function(o) {
$('#' + this.id).val(dateUtil.format(o.date, 'yyyy-MM-dd'));
})
}
});
在getJsonPartString
中若字段未通过验证,仅需使用emit
发送相应事件以通知业务方即可,其他的逻辑就交给aform处理吧,阅读表单验证获取更多详情。
实例:
getJsonPartString: function (con ,fd, af) {
var sel = $(con).find(".xyz");
if (fd.required && !sel.val()) {
af.emit("empty",[sel[0], fd]);//触发empty事件
}
if (sel.val().indexOf("http://") !== 0) {
af.emit("invalid",[sel[0], fd,"xx需以http开头"]);//触发invalid事件
}
return sel.attr("name") + ":\"" + sel.val() + "\"";
}