npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@icreate/ics-basic-form-builder

v0.0.29

Published

表单设计器

Downloads

15

Readme

@[toc] 版本更新说明

  • [ 0.0.29] 引入新的地址组件
  • [ 0.0.28-beta.1] 更新ics-ui/ics-icon版本
  • [ 0.0.28-beta.1] multi-column-select支持多选以及自定义搜索条件customFilter(结合数据tbodyOptions的data属性)
  • [ 0.0.28-beta.0] 1.提供按钮点击时触发的方法buttonClickRender 2.地址组件支持添加同步按钮isShowButton,点击按钮触发方法syncAddress 3.栅格列支持设置padding
  • [ 0.0.28] 1.地址组件更新(增加level/返回数据为对象) 2.基础字段支持重复拖入repeatFlag
  • [ 0.0.27-beta.6] 修复:checkbox报错
  • [ 0.0.27-beta.4] 修复:combogrid的label报错
  • [ 0.0.27-beta.3] 修复:formData数据实时回显
  • [ 0.0.27-beta.2] 修复:打包引入地址组件
  • [ 0.0.27-beta.1] 1.地址级联组件(业务组件) area-cascader 2.新模板/ace-builds放入ics-ui
  • [ 0.0.27] 1.label添加tooltip (字段labelTooltipContent/labelTooltipPlacement) 2.添加multi-column-select(select自定义模板:多列select)
  • [ 0.0.26-beta.0] 修复栅格组件的自适应宽度问题
  • [ 0.0.25 ] 1.可隐藏保存模板按钮saveFormTemplate:false,提供了自己保存的方法customSaveTemplate 2.栅格垂直方向对齐
  • [ 0.0.24 ] 随ics-ui更新版本
  • [ 0.0.23 ] 计数器默认值问题
  • [ 0.0.22 ] 1.自定义组件的name值改为'自定义组件的类型(type) + Widget' 2.属性collapseTags:select多选时是否将选中值按文字的形式展示 - 3.组件设置增加了标签行高 4.表单设置:静态字段增加了左侧标识
  • [ 0.0.21 ] 1.input:placeholder 2.组件设置:组件大小 3.表单设置:设置标签颜色labelColor以及标签字体大小labelFontSize 4.子表单
  • [ 0.0.20 ] 支持引入自定义组件
  • [ 0.0.19 ] input组件只读属性的样式,设置属性 readOnlyNoBorder

说明

这是一个表单设计器

安装

npm i @icreate/ics-basic-form-builder   # 安装包

在vue使用

  1. 在vue项目的main.js中引入
import VForm from '@icreate/ics-basic-form-builder'  //引入VForm库
import '@icreate/ics-basic-form-builder/styles/form-builder.css'  //引入VForm样式
import IcsUI from '@icreate/ics-ui'  //引入ics-ui
import '@icreate/ics-ui/lib/ics-ui.css'
Vue.use(IcsUI)  //全局注册ics-ui
Vue.use(VForm)  //全局注册VForm(同时注册了v-form-designer和v-form-render组件)
  1. 在Vue模板中使用表单设计器组件
     <v-form-designer
      ref="vfDesignerRef"
      :designer-config="designerConfig"
      :basicFieldsTransfer="basicFieldsTransfer"
      :formJson="formJson"
      :formTemplateJson="formTemplateJson"
      @saveFormTemplateHandler="saveFormTemplateHandler"
      :customComponentObj="customComponentObj"
    ></v-form-designer>
  1. 在Vue模板中使用表单渲染器组件
 <v-form-render
       ref="vFormRef"
      :form-json="formJson"
      :form-data="formData"
      :option-data="optionData"
      @appendButtonClick="appendButtonClickHandler"
      @formChange="handleFormChange"
      @buttonClickRender="buttonClickHandler"
      @syncAddress="syncAddressHandler"
      :customComponentObj="customComponentObj"
    >
    </v-form-render>
    <ics-button type="primary" @click="submitForm">Submit</ics-button>
  1. 引入自定义组件(可选)
import customCom from "./customCom.vue";    //自定义组件的格式,请参考最后的示例

数据格式:

v-form-designer 表单设计器
designerConfig :表单设计器配置 (必传) basicFieldsTransfer : 基础字段组件(必传) formJson: 显示上次编辑的设计器页面 (选传) formTemplateJson :显示保存的模板 (选传) saveFormTemplateHandler :保存模板后的回调函数,可以获取到模板的json数据 customComponentObj: 自定义组件的对象格式

v-form-render 表单渲染器 formJson:需要渲染的表单的json数据(从设计器复制json数据)(必传) formData:需要渲染的表单数据(选传) optionData:动态传入的选项数据(例如:多选框的选项)(选传) appendButtonClickHandler : 输入框后置按钮的回调函数(选传) handleFormChange: 表单数据改变时触发 submitForm: 可以获取到表单数据formData customComponentObj: 自定义组件的对象格式

export default {
  data() {
    return {
      customComponentArr:[customCom],    //自定义组件的数组
      customComponentObj:{},   //将数组转成对象的格式 (写在created())
      designerConfig: {         
        resetFormJson: false,  
        toolbarMaxWidth: 490,
        saveFormTemplate: false, //隐藏保存模板
      },     
      basicFieldsTransfer: [
        {                                //自定义组件
          type: "customType",            //自定义类型
          repeatFlag: true, // 组件可重复
          formItemFlag: true,
          options: {
            name: "customName", //name唯一值
            label: "自定义组件", //label值
            labelAlign: "", //label对齐方式
            defaultValue: null, //默认值
            labelWidth: null, //标签宽度
            labelHidden: false, //标签是否隐藏
            hidden: false, //是否隐藏
            required: false, //是否必填
            requiredHint: "", //必填提示
            columnWidth: '200px',  //在子表单中的组件列宽
            optionItems: [   //选项(ics-radio/ics-checkbox/ics-select...)
              { label: "选项1", value: 1 },
              { label: "选项2", value: 2 },
            ],
          },
        },
          {
          type: "data-table",   //数据表格
          options: {
            name: "dataTable",
            label: "数据表格",
            tableWidth: "100%", //表格宽度
            tableHeight: "300px", //表格高度
            showCheckBox: true, //是否显示复选框列
            stripe: true, //是否斑马线
            tableBorder: true, //是否带有边框
            showActionButton: true, //显示操作按钮列
            optionItems: {
              thOptions: [
                //表头
                {
                  label: "日期",
                  value: "date",
                  width: "180",
                },
                {
                  label: "姓名",
                  value: "name",
                  width: "180",
                },
                {
                  label: "地址",
                  value: "address",
                  width: "",
                },
              ],
              tbodyOptions: [
                {
                  id: "1",
                  date: "2016-05-02",
                  name: "张三",
                  address: "上海市普陀区金沙江路 1518 弄",
                },
                {
                  id: "2",
                  date: "2016-05-04",
                  name: "李四",
                  address: "上海市普陀区金沙江路 1517 弄",
                },
                {
                  id: "3",
                  date: "2016-05-01",
                  name: "王二麻子",
                  address: "上海市普陀区金沙江路 1519 弄",
                },
              ], //表格内容
            },
          },
        },
        {
          type: "input",     //表单组件类型(必传)
          options: {
            label: "输入框",   //组件label(必传)
            name: "inputtext",    //组件name(必传,而且必须是唯一值)
            type: "text",         //input 输入框的类型(可传)
            defaultValue:"",    //默认值(可传)
            required: true,      //是否必填(可传)
            requiredHint:'',     //必填提示(可传)
            validation: "/^[\u4e00-\u9fa5]+$/",    //组件的正则校验规则 (可传)
            validationHint: "只能输入中文哦",      //校验提示语(可传)
            reverseValidation:'/[^\u4e00-\u9fa5]/g',   //数据格式:正则取反+g  (需要限制输入时,必传)
            max:"" ,//限制输入的最大值  (限制输入是数字的情况)
            readOnlyNoBorder: true,   //只读时的样式  不要边框
            labelTooltipContent:"标签文字提示内容",   //标签文字提示内容
            labelTooltipPlacement:"top"   //标签文字提示位置
          },
        },
        {
          type: "input",
          options: {
            label: "输入框",
            name: "inputpsw",
            type: "password",
          },
        },
        {
          type: "textarea",
          options: {
            label: "文本域",
            name: "textarea",
          },
        },
        {
          type: "radio",
          options: {
            name: "radio",
            label: "单选项",
            optionItems: [    //选项列表(必传)
              {
                label: "选项1",
                value: "1",
              },
              {
                label: "选项2",
                value: "2",
              },
            ],
          },
        },
        {
          type: "checkbox",
          options: {
            name: "checkbox",
            label: "多选框",
            max: 1, // 可被勾选的 checkbox 的最大数量
            optionItems: [     //选项列表(必传)
              {
                label: "选项1",
                value: "1",
              },
              {
                label: "选项2",
                value: "2",
              },
              {
                label: "选项3",
                value: "3",
              },
            ],
          },
        },
        {
          type: "number",
          options: {
            name: "number",
            label: "计数器",
            min: 0,         //最小值(可传)
            max: 100000,    //最大值(可传)
            precision: 0,   //精度(可传)
            step: 1,        //增减步长(可传)
          },
        },
        {
          type: "select",
          options: {
            name: "select",
            label: "下拉框",
            labelAndValue: true, // 获取选项数据的格式(例如:选中下拉框,是否需要获取label值,默认不获取)
            collapseTags: true, //多选时是否将选中值按文字的形式展示  默认为fale
            optionItems: [      //下拉列表(必传)
              {
                id:"",     //   唯一key值  (如果value值不唯一,id必传)
                label: "select 1",
                value: 1,
              },
              {
                label: "select 2",
                value: 2,
              },
              {
                label: "select 3",
                value: 3,
              },
            ],
          },
        },
        {
          type: "select-plus",
          options: {
            name: "select-plus",
            label: "下拉框加强版",
            optionItems: [
              {
                label: "select 1",
                value: 1,
              },
              {
                label: "select 2",
                value: 2,
              },
              {
                label: "select 3",
                value: 3,
              },
            ],
          },
        },
        {
          type: "multi-column-select",
          options: {
            name: "multi-column-select",
            label: "多列select",
            labelColumn: "name", //label绑定的列
            valueColumn: "id", //value绑定的列
            showHeader: true, //是否显示表头
            labelAndValue: true, //返回值是对象(label和value)
            customFilter: ['id', 'name'],  //自定义搜索的字段
            optionItems: {
              thOptions: [
                // 表头
                {
                  label: "日期",
                  value: "date",
                  width: "100",
                },
                {
                  label: "姓名",
                  value: "name",
                  width: "100",
                },
                {
                  label: "地址",
                  value: "address",
                  width: "260",
                },
              ],
              tbodyOptions: [
                {
                  id: "1",
                  date: "2016-05-02",
                  name: "张三",
                  address: "上海市普陀区金沙江路 1518 弄",
                  data: {
                    id: '1',
                    name: '张三'
                  }
                },
                {
                  id: "2",
                  date: "2016-05-04",
                  name: "李四",
                  address: "上海市普陀区金沙江路 1517 弄",
                  data: {
                    id: '2',
                    name: '李四'
                  }
                },
                {
                  id: "3",
                  date: "2016-05-01",
                  name: "王二麻子",
                  address: "上海市普陀区金沙江路 1519 弄",
                  data: {
                    id: '3',
                    name: '王二麻子'
                  }
                },
              ], // 表格内容
            },
          },
        },
        {
          type: "time",
          options: {
            name: "time",
            label: "时间",
            format: "HH:mm:ss", //时间格式(可传)
          },
        },

        {
          type: "time-range",
          options: {
            name: "time-range",
            label: "时间范围",
            format: "HH:mm:ss", //时间格式(可传)
          },
        },

        {
          type: "date",
          options: {
            name: "date",
            label: "日期",
            format: "yyyy-MM-dd",  //日期显示格式(可传)
            valueFormat: "yyyy-MM-dd",  //日期对象格式(可传)
          },
        },

        {
          type: "date-range",
          options: {
            name: "date-range",
            label: "日期范围",
            format: "yyyy-MM-dd", //日期显示格式(可传)
            valueFormat: "yyyy-MM-dd", //日期对象格式(可传)
          },
        },
            {
          type: "datetime",
          options: {
            name: "datetime",
            label: "日期时间",
            format: "yyyy-MM-dd HH:mm:ss", //日期显示格式(可传)
            valueFormat: "yyyy-MM-dd HH:mm:ss", //日期对象格式(可传)
          },
        },
        {
          type: "switch",
          options: {
            name: "switch",
            label: "开关",
          },
        },

        {
          type: "rate",
          options: {
            name: "rate",
            label: "评分",
          },
        },
        {
          type: "button",
          options: {
            name: "button",
            label: "按钮",
          },
        },
        {
          type: "cascader",
          options: {
            name: "cascader",
            label: "级联选择",
            optionItems: [    //级联选择选项(必传)
              {
                label: "select 1",
                value: 1,
                children: [{ label: "child 1", value: 11 }],
              },
              { label: "select 2", value: 2 },
              { label: "select 3", value: 3 },
            ],
          },
        },
        {
          type: "combo-grid",
          options: {
            name: "comboGrid",
            label: "组合网格",
            labelColumn: "name",   //name列对应label
            valueColumn: "id",     //id列对应value(选中列表,获取的值)
            valueKey:"",           //添加表格数据的唯一key值属性(不传,默认是valueColumn)
            labelAndValue: true,   //true: 绑定的值是对象(含label)    默认为false
            customFilter: ["id", "name"],     //自定义搜索字段
            optionItems: {         //选项值:表头字段+表格数据 (必传)
              thOptions: [
                //表头
                {
                  label: "日期",
                  value: "date",
                  width: "180",
                },
                {
                  label: "姓名",
                  value: "name",
                  width: "180",
                },
                {
                  label: "地址",
                  value: "address",
                  width: "260",
                },
              ],
              tbodyOptions: [
                //表格内容
                {
                  id: "111111",
                  date: "2016-05-02",
                  name: "王小虎1",
                  address: "上海市普陀区金沙江路 1518 弄",
                },
                {
                  id: "111112",
                  date: "2016-05-04",
                  name: "王小虎2",
                  address: "上海市普陀区金沙江路 1517 弄",
                },
                {
                  id: "111113",
                  date: "2016-05-01",
                  name: "王小虎3",
                  address: "上海市普陀区金沙江路 1519 弄",
                },
              ], 
            },
          },
        },
      {
          type: 'area-cascader', // 业务组件 地址级联选择器
          options: {
            name: 'area-cascader',
            label: '地址级联',
            level: 1,
            isShowButton: true,   //是否显示右侧按钮
            syncAddressData: [    //右侧checkbox-group的数据
              { id: 'nativeAddress', name: '籍贯地址' },
              { id: 'residenceAddress', name: '户口地址' },
              { id: 'birthAddress', name: '出生地址' },
              { id: 'unitAddress', name: '单位地址' },
              { id: 'connectAddress', name: '联系人地址' },
              { id: 'currentAddress', name: '现住址' }
            ]
          }
        },
        {
          type: 'address-cascader', // 新地址级联
          options: {
            name: 'address-cascader',
            label: '新地址组件',
            level: 3,
            isShowButton: true,
            syncAddressData: [
              { id: 'nativeAddress', name: '籍贯地址' },
              { id: 'residenceAddress', name: '户口地址' },
              { id: 'birthAddress', name: '出生地址' },
              { id: 'unitAddress', name: '单位地址' },
              { id: 'connectAddress', name: '联系人地址' },
              { id: 'currentAddress', name: '现住址' }
            ]
          }
        }
      ],
      formTemplateJson:
        JSON.parse(localStorage.getItem("saveFormTemplateJson")) || null,

      formJson: {
        widgetList: [
          {
            type: "input",
            options: {
              labelAlign: "",
              defaultValue: "",
              placeholder: "",
              columnWidth: "200px",
              size: "",
              labelWidth: null,
              labelHidden: false,
              readonly: false,
              disabled: false,
              hidden: false,
              clearable: true,
              showPassword: false,
              required: true,
              requiredHint: "",
              validation: "/^[一-龥]+$/",
              validationHint: "只能输入中文哦",
              minLength: null,
              maxLength: null,
              showWordLimit: false,
              appendButton: true,
              appendButtonDisabled: false,
              buttonIcon: "el-icon-search",
              label: "用户名",
              name: "username",
              type: "text",
            },
            icon: "text-field",
            formItemFlag: true,
            id: "username",
          },
          {
            type: "input",
            options: {
              labelAlign: "",
              defaultValue: "",
              placeholder: "",
              columnWidth: "200px",
              size: "",
              labelWidth: null,
              labelHidden: false,
              readonly: false,
              disabled: false,
              hidden: false,
              clearable: true,
              showPassword: false,
              required: false,
              requiredHint: "",
              validation: "",
              validationHint: "",
              minLength: null,
              maxLength: null,
              showWordLimit: false,
              appendButton: false,
              appendButtonDisabled: false,
              buttonIcon: "el-icon-search",
              label: "密码",
              name: "password",
              type: "password",
            },
            icon: "text-field",
            formItemFlag: true,
            id: "password",
          },
          {
            type: "textarea",
            options: {
              labelAlign: "",
              defaultValue: "",
              placeholder: "",
              columnWidth: "200px",
              size: "",
              labelWidth: null,
              labelHidden: false,
              readonly: false,
              disabled: false,
              hidden: false,
              clearable: true,
              showPassword: false,
              required: false,
              requiredHint: "",
              validation: "",
              validationHint: "",
              minLength: null,
              maxLength: null,
              showWordLimit: false,
              appendButton: false,
              appendButtonDisabled: false,
              buttonIcon: "el-icon-search",
              label: "留言板",
              name: "message",
              rows: 3,
            },
            icon: "text-field",
            formItemFlag: true,
            id: "message",
          },
        ],
        formConfig: {
          labelWidth: 80,
          labelPosition: "left",
          size: "",
          labelAlign: "label-left-align",
          labelColor:"",   //label颜色
          labelFontSize:"", //label字体大小
          labelLineHeight: "", //标签行高
          cssCode: "",
          customClass: "",
          functions: "",
          layoutType: "PC",
          modelName: "formData",
          refName: "vForm",
          rulesName: "rules",
          onFormCreated: "",
          onFormMounted: "",
          onFormDataChange: "",
        },
      },
      formData: {},
      optionData: {        //动态传入的选项数据
        checkbox: [       //checkbox  是name名称 
          {
            label: "动态选项1",
            value: "1",
          },
          {
            label: "动态选项2",
            value: "2",
          },
          {
            label: "动态选项3",
            value: "3",
          },
        ],
      },
    };
  },
    methods: {
    submitForm() {
      this.$refs.vFormRef
        .getFormData()
        .then((formData) => {
          // Form Validation OK
          alert(JSON.stringify(formData));
        })
        .catch((error) => {
          // Form Validation failed
          this.$message.error(error);
        });
    },
    saveFormTemplateHandler(data) {
      //保存模板json数据
      localStorage.setItem("saveFormTemplateJson", data);
      this.$message.success("模板保存成功");
    },
    appendButtonClickHandler(data) {
      //输入框添加后置按钮,回调函数
      console.log("appendButtonClickHandler=======", data.$data.fieldModel);
    },
    handleFormChange(
      fieldName,
      newValue,
      oldValue,
      formDataModel,
      subFormName,
      subFormRowIndex,
      comboGridItem
    ) {
      //fieldName  name
      //newValue   新值
      //oldValue   旧值
      //formDataModel  表单数据
      //comboGridItem  组合网格组件,传过来的对象

     console.log(this.$refs["vFormRef"].widgetRefList)   //获取每个组件的属性方法

      this.$refs["vFormRef"].widgetRefList["select"].setRequired(true);  //设置select组件必填属性为true
      this.$refs["vFormRef"].widgetRefList["select"].setValue("1");     //设置select组件值为1
 
      this.$refs["vFormRef"].widgetRefList["input"].setWidgetOption("max",newValue)  //设置input组件的最大值为newValue

      this.$refs["vFormRef"].widgetRefList["comboGrid"].setValueNotEmitHandler(newValue);   //给组合网格赋值(赋值不会触发handleFormChange)  //改变组合网格选项,会触发
     
    this.$refs["vFormRef"].widgetRefList["select"].$refs.fieldEditor.toggleMenu();    //select组件  自动展开下拉框

    },
    customSaveTemplate(){
      //自己保存模板的方法  
      this.$refs.vfDesignerRef.$refs.toolbarRef.saveFormTemplate()  //方法的返回值即是保存的数据
    },
    buttonClickHandler(){}
  },
  created(){
    this.customComponentArr.map((item) => {
      return (this.customComponentObj[item.name] = item);
    });
  }
}

自定义组件的格式(.vue文件):

<!-- template 按需编写, 示例如下 -->
 <div>
    <ics-switch
      ref="fieldEditor"
      v-model="fieldModelData.switchVal"
    ></ics-switch>
    <ics-input
      class="marginBottom"
      ref="fieldEditor"
      v-model="fieldModelData.inputVal"
      placeholder="请输入内容"
      clearable
      show-password
    />
    <ics-select v-model="fieldModelData.selectVal" placeholder="请选择">
      <ics-option
        v-for="item in field.options.optionItems"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      >
      </ics-option>
    </ics-select>
    </div>
</template>
  export default {
    name: "customTypeWidget", //自定义组件的类型(type) + 'Widget'
    data() {
      return {
        fieldModelData: {
          switchVal: false, //每个组件的绑定值(名称自定义),都放在fieldModelData里面
          inputVal: "",
          selectVal: "",
        }
      };
    },
    props: {
      field: Object, //basicFieldsTransfer的自定义组件的数据
      value: Object, 
    },
    model: {
      prop: "value",
      event: "change",
    }, // v-model
    methods: {
    },
    watch: {
      value: {
        handler(val) {
          if (val) {
            this.fieldModelData = this.value;
          }
        },
        deep: true,
        immediate: true,
      },
      fieldModelData: {
        handler(val) {
          this.$emit("change", val);
        },
        deep: true,
      },
    },
  };
<style scoped>
.marginBottom {
  margin-bottom: 20px;
}
</style>