前言

继续接着上一篇的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的使用的更多相关文章

  1. [入门到吐槽系列] Webix 10分钟入门 一 管理后台制作

    前言 本人是服务端程序员,同时需要兼职前端开发.常用的就是原生态的HTML.Javascript,也用过ExtJS.Layui.可是ExtJS变公司后非常难用.Layui上手还行,用过一段时间,会觉得 ...

  2. HTML--HTML入门篇(我想10分钟入门HTML,可以,交给我吧)

    我要正经的讲一节课,咳咳! HTML简介(废话) HTML称为超文本标记语言,是一种标识性的语言.它包括一系列标签.通过这些标签可以将网络上的文档格式统一,使分散的Internet资源连接为一个逻辑整 ...

  3. Apache Shiro系列三,概述 —— 10分钟入门

     一.介绍 看完这个10分钟入门之后,你就知道如何在你的应用程序中引入和使用Shiro.以后你再在自己的应用程序中使用Shiro,也应该可以在10分钟内搞定. 二.概述 关于Shiro的废话就不多说了 ...

  4. kafka原理和实践(一)原理:10分钟入门

    系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...

  5. JavaScript 10分钟入门

    JavaScript 10分钟入门 随着公司内部技术分享(JS进阶)投票的失利,先译一篇不错的JS入门博文,方便不太了解JS的童鞋快速学习和掌握这门神奇的语言. 以下为译文,原文地址:http://w ...

  6. Markdown - Typora 10分钟入门 - 精简归纳

    Markdown - Typora 10分钟入门 - 精简归纳 JERRY_Z. ~ 2020 / 8 / 22 转载请注明出处! 目录 Markdown - Typora 10分钟入门 - 精简归纳 ...

  7. struts2官方 中文教程 系列十一:使用XML进行表单验证

    在本教程中,我们将讨论如何使用Struts 2的XML验证方法来验证表单字段中用户的输入.在前面的教程中,我们讨论了在Action类中使用validate方法验证用户的输入.使用单独的XML验证文件让 ...

  8. [入门到吐槽系列] 微信小程序 敏感违规图片检测 mediaCheckAsync,客服接口 消息推送 的各种坑分享!

    前言: 最近需要做个用户上传图片,服务端校验图片问题的需求.需要使用小程序消息推送,异步接受腾讯的图片验证回调.实在太多坑了. 相信10分钟看完本文的朋友,可以非常顺利避坑. 前期准备: 首先需要一个 ...

  9. UWP开发入门(十九)——10分钟学会在VS2015中使用Git

    写程序必然需要版本控制,哪怕是个人项目也是必须的.我们在开发UWP APP的时候,VS2015默认提供了对微软TFS和Git的支持.考虑到现在Git很火,作为微软系的程序员也不得不学一点防身,以免被开 ...

随机推荐

  1. 【刷题-LeetCode】150 Evaluate Reverse Polish Notation

    Evaluate Reverse Polish Notation Evaluate the value of an arithmetic expression in Reverse Polish No ...

  2. azure flask 测试

    本机 flask on linux service 完美.选择部署槽 web app service

  3. 2022GDUT寒假专题学习-1 B,F,I,J题

    专题链接:专题学习1 - Virtual Judge (vjudge.net) B - 全排列 题目 思想 这道题可以用DFS进行求解,但是一看到全排列,其实可以立刻想到一个STL函数:next_pe ...

  4. MyCms 自媒体 CMS 系统 v2.8,支持织梦数据导入

    MyCms 是一款基于Laravel开发的开源免费的自媒体博客CMS系统,助力开发者知识技能变现. MyCms 基于Apache2.0开源协议发布,免费且不限制商业使用,欢迎持续关注我们. V2.8 ...

  5. gin框架中项目的初始化

    核心知识点 json配置文件解析成结构体 将路由对应的接口抽离到单独的文件中,main函数中直接注册路由即可 项目目录图 项目代码 app.json代码 { "app_name": ...

  6. 使用AJAX请求调用出现HTTPS协议错误问题

    前言: 这又是一个可能是半路就卡机的项目,在调用ajax的时候遇到了下面的这个错. js中有个ajax请求http,url是:http//:.js就提示请求了一个不安全的脚本,在发送ajax请求时,就 ...

  7. python数据操作--8

    转:https://www.tuicool.com/wx/MB7nieb 数据类型 整数, 浮点数, 字符串, 布林值(True,False) 列表(list), 不可变的列表 Tuple, 集合(没 ...

  8. kubernetes sticky session 配置

    kubernetes中经常需要配置sticky session,此时需要根据你使用的ingress controller来设置了. 1.Nginx Ingress apiVersion: extens ...

  9. python小兵之时间模块

    Python  日期和时间 Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 时间 ...

  10. Linux 常见文件管理命令

    Linux文件系统 根目录:/ 从根目录开始,下面有一堆小目录 root:根用户的目录 bin:可执行文件命令 etc:配置文件 var:日志 lib:安装包或头文件,库文件 home:所有用户的家目 ...