Vue结合jqGrid数据绑定的通用弹出选择框

公共组件input弹出选择控件-用于建立快速的表之间的关联绑定

说明:

1、提高开发工作效率,目前主流脚手架基本上提供代码生成,单表增删改查很方便,但是针对某个数据需要绑定另外一个表的数据没有,这里希望能尽量做到通用组件化,通过一个配置,点击一个input弹出查询列表选择数据再回写,一步到位。
2、如果结合vue的v-model数据绑定,需要优先初始化vm对象如:vm = new Vue({...});因为$watch监听需要vue支持
3、之后再调用bindInputFormOpen();
4、全局匹配input,检测inputfromopen属性
5、参数说明:
参数名必填描述
inputfromopen申明此控件需要绑定弹出选择框
vModelFullPath仅在配合使用v-model时使用,需配置通过vue对象直接访问的全路径
valueField在弹出框选择数据时,指定弹出框里面要取值的字段名用于建立绑定关系,必须是唯一性类似id的作用
displayField默认同valueField,区别不建立绑定关系,仅显示,因为如果valueField是id的话不方便显示
queryPageUrl仅在配合使用v-model时使用,用于第一次打开查询后台回显displayField
selectCallbackFn默认调getSelectedRowData函数在common.js,用于从弹出页面选中jqGrid表格数据
layerOptionlayer弹出框相关配置,参考原生api,这里直接丢给layer.open

js示例:

$(function(){
  var vm = new Vue({...});
  bindInputFormOpen();
});

html示例:

<input type="text" name="serverIp" v-model="apiServer.serverIp" class="form-control" placeholder="服务器IP" inputfromopen vModelFullPath="vm.apiServer.serverIp" valueField="apiCode" displayField="apiCode" queryPageUrl="${request.contextPath}/apiManage/apiloglist/list" selectCallbackFn="getSelectedRowData" layerOption="{content:'${request.contextPath}/modules/apiManage/apiloglist.html'}"/>


bindFromOpen.js 代码如下

function _bindInputChange(newVal, oldVal, queryPageUrl, index){
    queryPageUrl = ctx + queryPageUrl;
    var valueInput = $("input[_idcard='value_"+index+"']")[0];
    var displayInput = $("input[_idcard='display_"+index+"']")[0];
    if(typeof(newVal) == "undefined"){
        displayInput.value = "";
    }else {
        if(valueInput.getAttribute("valueField") == valueInput.getAttribute("displayField")){
            displayInput.value = newVal;
            return;
        }
        var data = {};
        //框架后台查询都是基于表字段,此处将大写字母转下划线加小写拼接
        var field = valueInput.getAttribute('valueField').replace(/[A-Z]/g,function(a,b){
            return "_"+a.toLocaleLowerCase();
        });
        data[field] = newVal;
        $.ajax({
            type: "POST",
            url: queryPageUrl,
            data: data,
            success: function(r){
                if(r.code=='0' && r.page.list.length == 1){
                    displayInput.value = r.page.list[0][valueInput.getAttribute('displayField')];
                }else{
                    throw "服务器返回错误!或者目标查询字段["+valueInput.getAttribute("valueField")+"]有多条数据!查询地址:"+queryPageUrl;
                }
            }
        });
    }
}
function _bindInputBtnYes(index, layero){
    var currentLayer = this;
    var iframeWin = window[layero.find('iframe')[0]['name']];
    var data;
    if(typeof(currentLayer.callback) != "undefined" && currentLayer.callback != ""){
        data = eval("iframeWin."+currentLayer.callback+"();");
    }else{
        data = iframeWin.getSelectedRowData();
    }

    if(typeof(data[currentLayer.valueField]) != "undefined"){
        $("input[_idCard=display_"+currentLayer.bindInputIndex+"]")[0].value=data[currentLayer.displayField];
        if(currentLayer.vModelFullPath){
            $("input[_idCard=value_"+currentLayer.bindInputIndex+"]")[0].value=data[currentLayer.valueField];
            eval(currentLayer.vModelFullPath+"='"+data[currentLayer.valueField]+"';");
        }else{
            $("input[_idCard=value_"+currentLayer.bindInputIndex+"]")[0].value=data[currentLayer.valueField];
        }
        layer.close(index);
    }else{
        throw "valueField:"+currentLayer.valueField+"在选中数据行中未匹配属性;row:"+JSON.stringify(data);
    }
}
function _bindInputBtnSuccess(layero, index){
    var body = layer.getChildFrame('body', index);
    body.find('.grid-btn').remove();
}
function bindInputFormOpen(){
    var input = $("input");
    var defaultOption = {
        type : 2,
        title : '选择窗口',
        area : ['100%','100%'],
        shadeClose:true,
        move: false,
        content : ""
    };
    $.each(input,function(index,valueInput){
        var attr = valueInput.getAttribute('inputfromopen');
        if (attr != null) {
            valueInput = $(valueInput);
            if(valueInput.attr("v-model")){
                throw "控件申明了v-model,必须在new Vue({...});初始化之后再执行本方法!因为$watch监听需要vue支持";
            }
            var option = valueInput.attr('layerOption');
            var valueField = valueInput.attr("valueField");
            var displayField = valueInput.attr("displayField");
            displayField = !displayField || displayField=='' ? valueField : displayField;
            var callback = valueInput.attr("selectCallbackFn");
            var vModelFullPath = valueInput.attr("vModelFullPath");
            var queryPageUrl = valueInput.attr("queryPageUrl");

            valueInput.removeAttr("layerOption")
                .removeAttr("selectCallbackFn")
                .removeAttr("queryPageUrl")
                .removeAttr("inputfromopen");
            var displayInput = valueInput.clone()
                .removeAttr("valueField")
                .removeAttr("displayField")
                .attr("readonly","true")
                .removeAttr("v-model")
                .attr("name","display_"+valueInput.attr("name"))
                .attr("id","display_"+valueInput.attr("id"))
                .attr("_idCard", "display_"+index);
            valueInput.after(displayInput);
            valueInput
                .css("display","none")
                .attr("_idCard", "value_"+index);
            defaultOption.displayField = displayField;
            defaultOption.valueField = valueField;
            defaultOption.callback = callback;
            defaultOption.bindInputIndex = index;

            option = eval("("+option+")");
            $.each(option, function(key,value){
                defaultOption[key] = value;
            })
            defaultOption.btn = ['确定'];
            defaultOption.yes = '_bindInputBtnYes';
            defaultOption.success = '_bindInputBtnSuccess';

            if(vModelFullPath){//如果有配置vModelFullPath,需要监听属性变换,使用vue支持的特定的方式
                defaultOption.vModelFullPath = vModelFullPath;//传递给layer,用于在yes按钮确定后赋值,v-model一旦绑定数据,不能通过传统方式赋值
                var vueObjName = vModelFullPath.substring(0,vModelFullPath.indexOf("."));
                var dataPath = vModelFullPath.substring(vModelFullPath.indexOf(".")+1,vModelFullPath.length);
                //监听值变化,为了巧妙的增加额外参数,重新定义了function 并增加了第三个参数,巧妙的给vue回调的函数传过去我们需要的参数
                eval(vueObjName+".$watch('"+dataPath+"', function(a,b,c='"+queryPageUrl+"',d="+index+"){return _bindInputChange(a,b,c,d);})");
            }

            var layerOption = JSON.stringify(defaultOption);
            layerOption = layerOption.replace("\"_bindInputBtnYes\"",'_bindInputBtnYes');
            layerOption = layerOption.replace("\"_bindInputBtnSuccess\"",'_bindInputBtnSuccess');
            displayInput.attr('onclick', "layer.open("+layerOption+");");
        }
    });
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大麦牛奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值