[入门到吐槽系列] Webix 10分钟入门 二 表单Form的使用
前言
继续接着上一篇的webix入门:https://www.cnblogs.com/zc22/p/15912342.html。今天完成剩下两个最重要的控件,表单和表格的使用。掌握了这两个,整个Webix就入门完成了,就会进入吐槽模式。
Webix 表单Form的使用
表单的初始化布局
本章节介绍表单的获取、设置、验证;表单控件的数据绑定。
表单和一般控件,最大的区别,就是提供了批量操作。包括批量的设置取值、批量输入验证。先创建一个表单:
webix.ui({
id: 'webix_domasticparts',
rows: [
{
id: 'form', view: 'form', borderless: true,
elements: [
{
cols: [
{ view: 'label', label: '无型号:', autowidth: true, },
{ id: 'lb_title', name: 'lb_title', view: 'label', label: '0', width: 50, align: 'center', },
{ id: 'sh_select', name: 'sh_select', view: 'switch', onLabel: "打开", offLabel: '关闭', width: 120, value: 0 },
{},
],
}, {
cols: [
{ id: 'txt_input', name: "txt_input", view: 'text', width: 200, placeholder: '商家编码', },
{ id: 'btn_update', view: 'button', value: '设置', width: 150, },
{},
],
},
],
},
]
});
效果演示:
代码解释:
- 代码创建了个基本行布局,第一行放入一个view:form,表单控件。
- 表单内容默认是行布局,使用elements,也可以使用rows,这里需要吐槽作者,设计API的时候任意乱来,一会element,一会cell,一会rows/columns,一会options。往后这类非常low的问题会越来越多,先预告下。
- 表单的控件,如果需要通过方法返回集合,需要声明name属性。
表单数据获取与设置
接下来就是表单绑定事件,实现设置、更新,先看代码:
$$('btn_update').attachEvent('onItemClick', function () {
var values = $$('form').getValues();
console.log(values); values.lb_title = values.txt_input;
values.sh_select = 1;
$$('form').setValues(values, true);
});
效果显示:
代码解释:
在输入框输入hello,点击设置,标签会变成同样内容,开关打开。
- 获取和设置都是通过getValues, setValues控制。
- 表单的控件通过attachEvent绑定点击事件
表单输入校验
绑定验证方法很多,我们只分享最干净的一种:
webix.ui({
id: 'webix_domasticparts',
rows: [
{
id: 'form', view: 'form', borderless: true,
elements: [
{
cols: [
{ view: 'label', label: '无型号:', autowidth: true, },
{ id: 'lb_title', name: 'lb_title', view: 'label', label: '0', width: 50, align: 'center', },
{ id: 'sh_select', name: 'sh_select', view: 'switch', onLabel: "打开", offLabel: '关闭', width: 120, value: 0 },
{},
],
}, {
cols: [
{ id: 'txt_input', name: "txt_input", view: 'text', width: 200, placeholder: '商家编码', },
{ id: 'btn_update', view: 'button', value: '设置', width: 150, },
{},
],
},
],
rules: {
txt_input: webix.rules.isNumber,
},
},
]
}); $$('btn_update').attachEvent('onItemClick', function () {
if (!$$('form').validate()) {
webix.alert('输入错误')
return;
} var values = $$('form').getValues();
console.log(values); values.lb_title = values.txt_input;
values.sh_select = 1;
$$('form').setValues(values, true);
});
效果演示:
代码解释:
- 在表单的elements节点下方,添加rules节点,里面键值对绑定控件的验证。webix默认内置了:
- isNotEmpty
- isNumber
- isEmail
- isChecked
- 更多参考:https://docs.webix.com/desktop__data_validation.html#validationrules
- 当然,rules节点的配置可以是自定义方法。具体不详细解释了。
- 调用form的validate方法,通过返回值判断输入是否正确。
小结
现在我们可以制作一个比较复杂的表单了,里面包含了上传、导出等操作。先看代码:
<style>
.warn_label .webix_el_box {
color: red;
font-size: 18px;
font-weight: bold;
} .default_label .webix_el_box {
font-weight: bold;
} a {
color: #333;
text-decoration: none;
}
</style>
<script type="text/javascript" charset="utf-8"> const aadp_mixmode_cb = [
{ id: 1, value: '自营模式', },
{ id: 2, value: '淘宝国产代发', },
{ id: 3, value: '淘宝全代发', },
{ id: 4, value: '混采模式', },
]; webix.ui({
id: 'webix_domasticparts',
rows: [
{
id: 'aadp_form', view: 'form', borderless: true,
elements: [
{
cols: [
{ view: 'label', label: '无型号:', autowidth: true, },
{ id: 'aadp_unknownpart', name: 'aadp_unknownpart', view: 'label', label: '0', width: 50, align: 'center', css: 'warn_label', },
{ view: 'label', label: '无颜色:', autowidth: true, },
{ id: 'aadp_unknowncolor', name: 'aadp_unknowncolor', view: 'label', label: '0', width: 50, align: 'center', css: 'warn_label', },
{ view: 'label', label: '无库存:', autowidth: true, },
{ id: 'aadp_unknownstock', name: 'aadp_unknownstock', view: 'label', label: '0', width: 50, align: 'center', css: 'warn_label', }, { view: 'label', label: '零件总数:', autowidth: true, },
{ id: 'aadp_totalpart', name: 'aadp_totalpart', view: 'label', label: '0', width: 50, align: 'center', css: 'default_label', },
{ view: 'label', label: '总价格:', autowidth: true, },
{ id: 'aadp_totalprice', name: 'aadp_totalprice', view: 'label', label: '0', width: 180, align: 'center', css: 'default_label', },
{ view: 'label', label: '代发价格:', autowidth: true, },
{ id: 'aadp_totaldiscount', name: 'aadp_totaldiscount', view: 'label', label: '0', width: 180, align: 'center', css: 'default_label', }, { id: 'aadp_unknownpart_cb', name: 'aadp_unknownpart_cb', view: 'switch', onLabel: "未知零件", offLabel: '未知零件', width: 120, value: 0 },
{ id: 'aadp_unknowncolor_cb', name: 'aadp_unknowncolor_cb', view: 'switch', onLabel: "未知颜色", offLabel: '未知颜色', width: 120, value: 0 },
{ id: 'aadp_unknownstock_cb', name: 'aadp_unknownstock_cb', view: 'switch', onLabel: "无库存", offLabel: '无库存', width: 120, value: 0 },
{},
],
},
{
cols: [
{ id: 'aadp_mixmode_cb', name: "aadp_mixmode_cb", view: 'richselect', label: '商家选择', width: 250, options: [], },
{ id: 'aadp_uploadsellercode', name: "aadp_uploadsellercode", view: 'text', width: 200, placeholder: '商家编码', },
{ id: 'aadp_reupload', view: 'uploader', value: '上传零件表', inputName: 'file', width: 150, css: 'webix_normal' },
{ id: 'aadp_download', view: 'button', value: '导出零件表', autowidth: true, },
{ id: 'aadp_createorder', view: 'button', value: '生成订单', autowidth: true, css: 'webix_primary' },
{ id: 'aadp_designcode', name: "aadp_designcode", view: 'text', width: 250, label: '零件编码', labelAlign: 'right', },
{ id: 'aadp_search', view: 'button', value: '搜索', autowidth: true, },
{},
],
},
],
},
]
}); // 设置加载中特效
webix.extend($$("webix_domasticparts"), webix.ProgressBar); // 代码设置下拉框
$$('aadp_mixmode_cb').define('options', aadp_mixmode_cb);
$$('aadp_mixmode_cb').refresh();
$$('aadp_mixmode_cb').setValue(2); // 代码设置上传组件
$$('aadp_reupload').define('formData', function () {
var formval = $$('aadp_form').getValues();
return {
mixmode: formval.aadp_mixmode_cb,
sellercode: formval.aadp_uploadsellercode,
};
});
$$('aadp_reupload').define('upload', 'http://localhost:8001/sso/page/upload');
$$('aadp_reupload').refresh();
$$('aadp_reupload').attachEvent('onFileUploadError', function (file, err) {
console.error(file, err);
$$('webix_domasticparts').hideProgress();
// 做一些补救措施,然后自动再上传
$$('aadp_reupload').send();
});
$$('aadp_reupload').attachEvent('onAfterFileAdd', function () {
$$('webix_domasticparts').showProgress({
type: 'icon',
delay: 1000,
});
});
$$('aadp_reupload').attachEvent('onFileUpload', function (file, response) {
console.log(response);
}); // 下载文件
$$('aadp_download').attachEvent('onItemClick', function (e) {
window.open(createRequestUrl('/wxss/moc/analysis/auth_exportbricklinkdomastic?orderNo=' + orderno));
}); </script>
服务端代码:
@RequestMapping("/upload")
@ResponseBody
public ApiResponseBody upload(String name, @RequestParam("file") MultipartFile file) {
return ApiResponseBody.success(file.getOriginalFilename().toLowerCase());
} // 管理员国产零件导出
@GetMapping("/analysis/auth_exportbricklinkdomastic")
@ResponseBody
public ApiResponseBody authExportBricklinkDomastic(String orderNo, HttpServletResponse response) throws Exception {
// 这里添加下载的数据组装,filename等
try {
response.setHeader("content-type", "application/octet-stream");
response.setContentType("application/octet-stream"); // 下载文件能正常显示中文
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
OutputStream os = response.getOutputStream();
// 数据写入返回
System.out.println("Download successfully!");
return null; } catch (Exception e) {
System.out.println("Download failed!");
return null;
} finally {
wb.close();
}
}
效果如下:
Label关键点说明:
- 如果要修改label的表现形式,需要增加css的属性,这是个非常常用的功能,但是这里有个巨坑,需要按照webix控件皮肤去改,改成:.warn_label .webix_el_box,原因是如果没这个css声明,会被官方的css覆盖了,导致一直改不成功。
- 再分享一个巨坑,一旦用了自己的css属性,设置了字体的大小等,会导致label的自动调整布局resize() 全部失效,对不齐。因为官方用了默认的css去计算label的部局尺寸。
- 从这里开始,大家应该可以理解到这个webix框架会有多烂。继续。
Uploader关键点说明:
- 使用上传控件,声明一个view:'uploader'的控件,他本质和button基本一样。同时要声明上传二进制的名字inputName: 'file',后台才能用file去接:@RequestParam("file")
- 动态绑定上传地址,需要使用define('upload'这个最原始的方法,再refresh()。又是个无语的地方。
- 同理,动态修改提交的formData,也需要使用define,然后使用方法返回运行时数据。
- 上传组件如果需要代码再次提交,使用send()方法。比如上传的时候,服务端返回登录超时,那么前端再做一次登录,然后直接再次上传。
- 上传组件几个关键事件:onAfterFileAdd、onFileUploadError、onFileUpload
其他说明:
- 如果要使用加载遮罩,需要扩展控件webix.extend,对控件增加webix.ProgressBar,然后就可以调用对应的showProgress, hideProgress。这是个透明的悬浮窗,可以遮挡用户操作行为,非常常用,但是webix竟然特么没有提供基础loading方法。
- 动态修改下拉框的数据,同样要非常弱智的使用define('options的方式,修改控件配置,再refresh。没有提供一般性的绑定数据接口。
- 要实现文件下载,建议使用window.open的方式。不然报错或者在iframe下,会有各种奇怪不爽问题。
由于webix的坑实在多如天上繁星,接下里的datatable的坑数会翻倍。所以咱们新开一篇继续。今天的分享完毕!
本文所有代码在这里可以下载:
链接: https://pan.baidu.com/s/1jRk6Zo6YtIvNza-8I6rOtA
提取码: eq2k
也欢迎大家关注咱们公众号:辰同学技术 微信公众号,同样会分享各种技术10分钟从入门到吐槽:
[入门到吐槽系列] Webix 10分钟入门 二 表单Form的使用的更多相关文章
- [入门到吐槽系列] Webix 10分钟入门 一 管理后台制作
前言 本人是服务端程序员,同时需要兼职前端开发.常用的就是原生态的HTML.Javascript,也用过ExtJS.Layui.可是ExtJS变公司后非常难用.Layui上手还行,用过一段时间,会觉得 ...
- HTML--HTML入门篇(我想10分钟入门HTML,可以,交给我吧)
我要正经的讲一节课,咳咳! HTML简介(废话) HTML称为超文本标记语言,是一种标识性的语言.它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整 ...
- Apache Shiro系列三,概述 —— 10分钟入门
一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...
- kafka原理和实践(一)原理:10分钟入门
系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...
- JavaScript 10分钟入门
JavaScript 10分钟入门 随着公司内部技术分享(JS进阶)投票的失利,先译一篇不错的JS入门博文,方便不太了解JS的童鞋快速学习和掌握这门神奇的语言. 以下为译文,原文地址:http://w ...
- Markdown - Typora 10分钟入门 - 精简归纳
Markdown - Typora 10分钟入门 - 精简归纳 JERRY_Z. ~ 2020 / 8 / 22 转载请注明出处! 目录 Markdown - Typora 10分钟入门 - 精简归纳 ...
- struts2官方 中文教程 系列十一:使用XML进行表单验证
在本教程中,我们将讨论如何使用Struts 2的XML验证方法来验证表单字段中用户的输入.在前面的教程中,我们讨论了在Action类中使用validate方法验证用户的输入.使用单独的XML验证文件让 ...
- [入门到吐槽系列] 微信小程序 敏感违规图片检测 mediaCheckAsync,客服接口 消息推送 的各种坑分享!
前言: 最近需要做个用户上传图片,服务端校验图片问题的需求.需要使用小程序消息推送,异步接受腾讯的图片验证回调.实在太多坑了. 相信10分钟看完本文的朋友,可以非常顺利避坑. 前期准备: 首先需要一个 ...
- UWP开发入门(十九)——10分钟学会在VS2015中使用Git
写程序必然需要版本控制,哪怕是个人项目也是必须的.我们在开发UWP APP的时候,VS2015默认提供了对微软TFS和Git的支持.考虑到现在Git很火,作为微软系的程序员也不得不学一点防身,以免被开 ...
随机推荐
- 使用PostGIS完成两点间的河流轨迹及流经长度的计算
基础准备工作 1.PostGIS 的安装 在安装PostGIS前首先必须安装PostgreSQL,然后再安装好的Stack Builder中选择安装PostGIS组件.具体安装步骤可参照 PostGI ...
- 【刷题-PAT】A1111 Online Map (30 分)
1111 Online Map (30 分) Input our current position and a destination, an online map can recommend sev ...
- js复制标题和链接
问题 常常在写博客和作业时候,需要附上参考链接. 希望可以一键得到标题和链接. 解决方案 普通元素 可以使用findid然后复制 但是标题无法使用 <!DOCTYPE html> < ...
- DEEP LEARNING WITH PYTORCH: A 60 MINUTE BLITZ | NEURAL NETWORKS
神经网络可以使用 torch.nn包构建. 现在你已经对autograd有所了解,nn依赖 autograd 定义模型并对其求微分.nn.Module 包括层,和一个返回 output 的方法 - f ...
- Docker 与 K8S学习笔记(十八)—— Pod的使用
Pod 是一组紧密关联的容器集合,它们共享IPC.Network和UTS namespace,是 Kubernetes 调度的基本单元.Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件 ...
- 花了半年时间,我把Pink老师的HTMLCSS视频课程,整理成了10万字的Markdown笔记!
说明:本文内容真实!!!不是推广!!! 学习前端的同学应该都或多或少听说过 Pink 老师,我个人觉得 Pink 老师的前端视频教程应该说是目前B站上最好的了,没有之一! Pink老师 HTML CS ...
- for each ……in
使用一个变量迭代一个对象的所有属性值,对于每一个属性值,有一个指定的语句块被执行. 作为ECMA-357(E4X)标准的一部分,for each...in语句已被废弃,E4X中的大部分特性已被删除,但 ...
- centos7语言更改
vim /etc/locale.conf 把 LANG="en_US.UTF-8" 改为 LANG="zh_CN.UTF-8"
- linux下查看开放的端口
Nmap是一款针对大型网络的端口扫描工具,它也适用于单机扫描,它支持很多扫描,也同时支持性能和可靠性统计. [root@localhost ~]# yum install namp [root@loc ...
- 字节Android Native Crash治理之Memory Corruption工具原理与实践
作者:字节跳动终端技术--庞翔宇 内容摘要 MemCorruption工具是字节跳动AppHealth (Client Infrastructure - AppHealth) 团队开发的一款用于定 ...