freeMark動態生成屬性組

項目開發中遇到的一個實際且實用的功能,就是對應一個項目數據,需要配套的屬性組數據,這一系列的屬性組數據是對項目數據的補充,說白了就是一個可以拓展該項目的其它信息,來進行保存。

實際需求

一個項目,可能對對應多個屬性組,屬性組的展示方式和一些特性可以設置,根據設置的特性來動態的生成該模塊,需要實現的功能是:

  1. 屬性組可能是表單或者表格,但是無論哪種展示方法,實際的數據都是保存在同一張表中
  2. 屬性可能為空,也可能為一個或者多個
  3. 必須以Tab頁的方式展示
    4.每一個屬性組都可以單獨的進行編輯,更新,保存,刪除等操作

問題分析

技術的大方向是固定的,即使用freeMark模板技術來進行動態生成前端代碼,包括UI和js的邏輯代碼。

特別注意點:
整個功能需要在系統中的多個頁面進行調用,所以需要抽象為一個獨立的頂層模塊,并且不是實際依賴實際頁面的數據。所以最后抽象為一個java方法,將必要的數據以參數的形式傳遞,然后加載ftl模板,生成前端代碼,最后添加到請求的頁面中去,完成整個邏輯。

//前端調用形式
${attrGroupProvider.getAttrGroup(base,"hpm.impl.dto.Project","projectId","${projectId!0}",attributeGroups)}

實際開發細節問題的思路:

思路整理分析
---

1. 根據提供的接口,拿到該項目設置的屬性組頭表ID結合
2. 拿到集合,查到集合對應的屬性組的集合,存儲進

    問題1:多個集合組,數據存儲形式

    >  解決思路:map<屬性頭表dto,List<屬性dto>>

3. java加載ftl模板,根據參數,初始化出來界面‘

    - map不為空,就建立tab標簽頁組件
    - 遍歷map,創建tab頁頭和對應的div
    - 根據屬性組頭類型屬性,確定加載grid或者form組
    - form組值遍歷循環,添加為input即可

   問題2:拿到屬性組加載對應的grid
    
    > 屬性頭id-》屬性組配置-》配置初始化grid和數據源的代碼

4. 頁面初始化完成,進行數據拉取綁定到viewModel,流程完成



項目新建頁面整體流程
---
請求方法controller請求,三種情況

- 項目id
    
    項目id是查看項目明細數據,先獲取模板id,初始化viewAndModel,獲取項目明細數據配置字段的數據,初始化項目明細數據的配置字段顯示

    接下來是屬性組配置,此時有項目id,獲取到項目的dto,調用屬性組接口,獲取數據,初始化配置數據頁面


- 模板id

    模板id,獲取模板配置數據,初始化頁面,拉取默認字段

    獲取屬性組,同上

- lineId

    行表id,獲取lineDto,獲取模板id,加載模板數據

模板代碼:

java部分

    public String getAttrGroupByDto(RequestContext requestContext,String dtoFullName,String pkName,String primaryKey) throws IOException, TemplateException{

        //根據條件獲取要展示的屬性組
        List<AttributesGroup> attributeGroups = null;
        try {
            String str = dtoFullName.replace("dto", "service");
            String serviceName = str.substring(0, str.lastIndexOf(".") + 1) + "I" + str.substring(str.lastIndexOf(".") + 1) + "Service";
            String serviceImplName = serviceName.substring(serviceName.lastIndexOf(".")+2).substring(0,1).toLowerCase() + serviceName.substring(serviceName.lastIndexOf(".")+2).substring(1) + "Impl";
            if(attributeGroups ==  null ){
                Class<?> dtoClass = Class.forName(dtoFullName);
                Object dtoObj = dtoClass.newInstance();
                WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

                Object serviceImpl = wac.getBean(serviceImplName, Class.forName(serviceName));
                Method selectByPrimaryKey = serviceImpl.getClass().getDeclaredMethod(QUERY_METHOD_NAME, dtoClass);
                if(!"".equals(primaryKey)) {
                    Field nameField = dtoClass.getDeclaredField(pkName);
                    nameField.setAccessible(true);
                    nameField.set(dtoObj, Long.parseLong(primaryKey));
                }
                Object resultDto = selectByPrimaryKey.invoke(serviceImpl,dtoObj);
                if(resultDto == null){
                    attributeGroups = attributesAssignService.selectGroupsByBaseDTO((BaseDTO) dtoObj);
                }else
                {
                    attributeGroups = attributesAssignService.selectGroupsByBaseDTO((BaseDTO) resultDto);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "<p>屬性組查詢失敗</p>";
        }

        if(attributeGroups == null){
            return "";
        }

        return getAttrGroup(requestContext,dtoFullName,pkName,primaryKey,attributeGroups);

    }

    public String getAttrGroup(RequestContext requestContext,String dtoFullName,String pkName,String primaryKey,List<AttributesGroup> attributeGroups) throws IOException, TemplateException{

        String extUrl = dtoFullName.substring(dtoFullName.lastIndexOf(".")+1).substring(0,1).toLowerCase()+ dtoFullName.substring(dtoFullName.lastIndexOf(".")+1).substring(1)+"Ext";

        if(attributeGroups == null){
            return "";
        }

        Template template = getConfiguration().getTemplate("AttributeGroup.ftl");

        try(StringWriter out = new StringWriter()){

            Map<String, Object> param = new HashMap<>();

            Map<String, String> lovDatas = new HashMap<>();

            Map<String, List<AttributesCols>> groupsCols = new HashMap<>();

            List<String> codeResources = new ArrayList();

            AttributesCols attributesCols = new AttributesCols();

            for(AttributesGroup group : attributeGroups){

                attributesCols.setAttributeGroupId(group.getAttributeGroupId());
                List<AttributesCols> attributeRestoutCols=  attributesColsService.selectColsByGroupId(attributesCols);
                for(AttributesCols col:attributeRestoutCols){
                    if("LOV".equals(col.getFormatCode())){
                        if(col.getFormatValue() != null){
                            String lovData = kendoLovService.getLov(requestContext.getContextPath(),requestContext.getLocale(),col.getFormatValue());
                            lovDatas.put(col.getFormatValue(),lovData);
                        }
                    };
                    if("LIST".equals(col.getFormatCode())){
                        if(col.getFormatValue() != null) {
                            codeResources.add(col.getFormatValue());
                        }
                    }
                }
                groupsCols.put(group.getAttributeGroupId().toString(),attributeRestoutCols);
            }

            param.put("groupsCols", groupsCols);
            param.put("attributeGroups", attributeGroups);
            param.put("lovDatas", lovDatas);
            param.put("base", requestContext);
            param.put("listSources", codeResources);
            param.put("pkName", pkName);
            param.put("dtoFullName", dtoFullName);
            param.put("primaryKey", primaryKey);
            param.put("extUrl", extUrl);
            template.process(param, out);
            out.flush();
            String html = out.toString();
            return html;

        }

    }

freeMark部分

<#-- 屬性組動態配置模板 -->

<div class="row" >
    <div class="col-md-12">
        <h4>屬性組</h4>
        <hr/>
    </div>
</div>
<#-- 下拉列表取值源 -->
<#if listSources?? >
    <#list listSources as ls>
        <script src="${base.contextPath}/common/code?${ls+ "Resource"}=${ls}"type="text/javascript"></script>
    </#list>
</#if>
<#if groupsCols?? >
<#-- 屬性組數據存在,遍歷創建tab頁 -->
<script>

    var groupModel = kendo.observable({
    <#-- 創建form綁定對象 -->
        <#list attributeGroups as group>

            <#if group.displayType == "FORM">

            ${group.groupInternalName}${group.attributeGroupId}:{
                ${pkName}:${primaryKey!null},
                attributeGroupId:${group.attributeGroupId},
                ext1:2
            },

            <#elseif group.displayType == "GRID">
                <#-- 生成grid的操作方法,包括新增,保存,取消-->
                ${"grid" + group_index + "Insert"}:function(e){

                    if(typeof(viewModel.model.${pkName}) === "undefined"){
                        kendo.ui.showInfoDialog({
                            message: '請先保存,再進行屬性組操作!'
                        });

                        return;
                    }

                    ${"grid" + group_index}.addRow();
                },
                ${"grid" + group_index + "Save"}:function(e){

                    if(typeof(viewModel.model.${pkName}) === "undefined"){
                        kendo.ui.showInfoDialog({
                            message: '請保存先保存項目,再進行屬性組操作!'
                        });

                        return;
                    }

                    ${"grid" + group_index}.saveChanges();
                },
                ${"grid" + group_index + "Cancel"}:function(e){

                    if(typeof(viewModel.model.${pkName}) === "undefined"){
                        kendo.ui.showInfoDialog({
                            message: '請保存先保存項目,再進行屬性組操作!'
                        });

                        return;
                    }

                    ${"grid" + group_index}.cancelChanges();
                },
            </#if>
        </#list>

        //以下所有操作,必須保證當前頁面的viewModel里有pkName,否則視為當前沒有已創建項目,會提示:請保存先保存項目,再進行屬性組操作
        groupFromsRead:function () {
            if(typeof(viewModel.model.${pkName}) === "undefined" || viewModel.model.${pkName} == null){
                return;
            }
            //構造 查詢條件參數
            var groups = [
            <#list attributeGroups as group>
                <#if group.displayType == "FORM">
                    <#if (attributeGroups?size)-1 == group_index >
                        {
                            ${pkName}:viewModel.model.${pkName},
                            attributeGroupId:${group.attributeGroupId}
                        }
                    <#else>
                        {
                            ${pkName}:viewModel.model.${pkName},
                            attributeGroupId:${group.attributeGroupId}
                        },
                    </#if>
                </#if>
            </#list>
            ];

            $.ajax({
                url:"${base.contextPath}/attr/${extUrl}/formQuery",
                contentType: "application/json",
                type: "POST",
                data:kendo.stringify(groups),
                success:function(data){

                    //將數據綁定到form中去
                    var formatModel = groupModel.toJSON();
                    var formatGroup;
                    var group;
                    for(var modelKey in formatModel){
                        group = groupModel[modelKey];
                        var remoteData = data[group.attributeGroupId.toString()];
                        formatGroup = group.toJSON();
                        for(var groupKey in remoteData){
                            if(remoteData[groupKey] != null){
                                group.set(groupKey,remoteData[groupKey]);
                            }
                        }
                    }
                }
            })
        },
        //新建和更新
        GroupFromSync:function (formKey) {

            if(typeof(viewModel.model.${pkName}) === "undefined"){
                kendo.ui.showInfoDialog({
                    message: '請保存先保存項目,再進行屬性組操作!'
                });

                return;
            }

            if(viewModel.model.${pkName} == null){
                kendo.ui.showInfoDialog({
                    message: '請保存先保存項目,再進行屬性組操作!'
                });

                return;
            }

            var groupFormValidateResult = $('#'+formKey).kendoValidator({
                valid: function (e) {
                },
                //驗證樣式 默認為default
                invalidMessageType : "tooltip"
            }).data("kendoValidator").validate();


           if(!groupFormValidateResult){
                // num數字輸入組件樣式加載會出問題,在這里進行修復
                var Numerics = $('#'+formKey).find('.k-numeric-wrap');
               for(var i = 0,len = Numerics.length; i < len; i++){
                   Numeric = Numerics[i];
                   var child  = $($(Numeric).children()[1]);
                   if((child.val() === undefined || child.val() === null || child.val() === "") && child.attr("required") === "required"){
                       $(Numeric).addClass("k-valid-custom");
                   }else{
                       $(Numeric).removeClass("k-valid-custom");
                   }
               }

               // LOV輸入組件樣式加載會出問題,在這里進行修復
               var Lovs = $('#'+formKey).find('.k-lov');
               for(var i = 0,len = Lovs.length; i < len; i++){
                   Lov = Lovs[i];
                   childSpan  = $(Lov).children()[0];
                   var childInput  = $($(Lov).children()[1]);
                   if((childInput.val() === undefined || childInput.val() === null || childInput.val() === "") && childInput.attr("required") === "required"){
                       $(childSpan).addClass("k-valid-custom");
                   }else{
                       $(childSpan).removeClass("k-valid-custom");
                   }
               };

               // LOV輸入組件樣式加載會出問題,在這里進行修復
               var Lists = $('#'+formKey).find('.k-combobox');
               for(var i = 0,len = Lists.length; i < len; i++){
                   list = Lists[i];
                   childSpan  = $(list).children()[0];
                   var childInput  = $($(list).children()[1]);
                   if((childInput.val() === undefined || childInput.val() === null || childInput.val() === "") && childInput.attr("required") === "required"){
                       $(childSpan).addClass("k-valid-custom");
                   }else{
                       $(childSpan).removeClass("k-valid-custom");
                   }
               }
                return;
            }

            var groupData = this[formKey];
            groupData.set("${pkName}",viewModel.model.${pkName});

            $.ajax({
                url:"${base.contextPath}/attr/${extUrl}/formSubmit",
                contentType: "application/json",
                type: "POST",
                dataType:"JSON",
                data:kendo.stringify(groupData),
                success:function(data){

                    if(data.insert === true || data.update === true){
                        kendo.ui.showInfoDialog({
                            message: '保存成功!'
                        });

                        var formatGroup = groupData.toJSON();
                        for(var k in data.${extUrl}){

                            groupData.set(k,data.projectExt[k]);
                        }
                    }else{
                        kendo.ui.showErrorDialog({
                            message: '保存失敗!'
                        });
                    }
                }
            });
        },
        //清空該form,form不支持刪除,提供清空選項,抹掉所有數據
        GroupFromClear:function (formKey) {

            var groupData = this[formKey];

            var col = "ext";
            for(var i = 1; i < 51; i++){

                groupData.set(col+i, null);
            }
        }

    });



</script>

<div id="tabstrip-groups" style="margin-left:5px;">
        <#-- 遍歷,tab頁頭 -->
        <ul class="nav nav-tabs">
            <#list attributeGroups as group>

                <li <#if group_index == 0> class="k-state-active"</#if> >${group.groupDisplayName}</li>

            </#list>

        </ul>

            <#list attributeGroups as group>

                <div style="padding: 0px">
                    <#--表單形式的展示-->
                    <#if group.displayType == "FORM">

                    <div class="panel panel-default" style="border: 0px;margin-bottom: 0px">

                        <div class="panel-heading" style="padding: 4px">

                            <button style="float: right;margin-left: 5px" type="button" onclick="groupModel.GroupFromClear('${group.groupInternalName}${group.attributeGroupId}')" class="btn btn-warning">
                                <i class="fa  fa-eraser" style="margin-right:3px;"></i>清空</button>
                            <button style="float: right" type="button" onclick="groupModel.GroupFromSync('${group.groupInternalName}${group.attributeGroupId}')" class="btn btn-success">
                                <i class="fa fa-save" style="margin-right:3px;"></i>保存</button>

                        </div>

                        <div class="panel-body">

                            <form class="form-horizontal"
                                  id="${group.groupInternalName}${group.attributeGroupId}"
                                  role="form">
                                <div class="row" style="margin: 0px" >
                                <#-- 直接獲取id本身沒有任何問題,但是隱式的number轉string的時候,freemark會自動加 “,”
                                例如: 123345 =》 “123,345” ,這個隱式的問題會導致key錯誤,從而導致找不到key而報錯,所以強制調用 c 方法轉換-->
                                    <#assign cols = groupsCols[group.attributeGroupId?c]>
                                    <#if (cols?size>0) >
                                        <#list cols as col>
                                            <#if col_index%4==0>
                                            <div class="col-md-12">
                                            </#if>
                                            <div class="col-md-3">
                                                <div class="form-group">
                                                    <label class="col-md-3 control-label" style="padding: 0px">${col.colDisplayName}</label>
                                                    <div class="col-md-9">
                                                        <#if col.formatCode == "BOOLEAN">
                                                            <input  type="checkbox"
                                                                    <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                        required
                                                                    </#if>
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    id="${group.groupInternalName}_${col.colInternalName}"/>
                                                            <script>
                                                                $("#${group.groupInternalName}_${col.colInternalName}").kendoCheckbox({
                                                                            checkedValue:'Y',
                                                                            uncheckedValue:'N'
                                                                });
                                                            </script>
                                                        <#elseif col.formatCode == "DATE">
                                                            <input  type="text"
                                                                <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                    required
                                                                </#if>
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    id="${group.groupInternalName}_${col.colInternalName}"
                                                                    style="width: 100%;"/>
                                                            <script>
                                                                $("#${group.groupInternalName}_${col.colInternalName}").kendoDatePicker({
                                                                    <#if col.formatMask??>
                                                                        format:"${col.formatMask}"
                                                                    </#if>
                                                                });
                                                                    <#if col.defaultValue??>
                                                                        groupModel.set('${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}','${col.defaultValue}');
                                                                    </#if>
                                                            </script>
                                                        <#elseif col.formatCode == "DATETIME">
                                                            <input  type="text"
                                                                <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                    required
                                                                </#if>
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    id="${group.groupInternalName}_${col.colInternalName}"
                                                                    style="width: 100%;"/>
                                                            <script>
                                                                $("#${group.groupInternalName}_${col.colInternalName}").kendoDateTimePicker({
                                                                    <#if col.formatMask??>
                                                                        format:"${col.formatMask}"
                                                                    </#if>
                                                                });
                                                                    <#if col.defaultValue??>
                                                                        groupModel.set('${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}','${col.defaultValue}');
                                                                    </#if>
                                                            </script>
                                                        <#elseif col.formatCode == "NUM">
                                                            <input  type="text"
                                                                    <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                        required
                                                                    </#if>
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    id="${group.groupInternalName}_${col.colInternalName}"
                                                                    style="width: 100%;"/>
                                                            <script>
                                                                $("#${group.groupInternalName}_${col.colInternalName}").kendoNumericTextBox({
                                                                    <#if col.formatMask??>
                                                                        format:"${col.formatMask}"
                                                                    </#if>
                                                                });
                                                                <#if col.defaultValue??>
                                                                    groupModel.set('${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}','${col.defaultValue}');
                                                                </#if>
                                                            </script>
                                                        <#elseif col.formatCode == "LIST">
                                                            <script src='${base.contextPath}/common/code?${group.groupInternalName}_${col.colInternalName+ "Resource"}=${col.formatValue}' type="text/javascript"></script>
                                                            <select data-role="combobox"
                                                                    id="${group.groupInternalName}_${col.colInternalName}"
                                                                    <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                        required
                                                                    </#if>
                                                                    data-value-primitive="true"
                                                                    style="width:100%;"
                                                                    data-text-field="meaning"
                                                                    data-value-field="value"
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    data-source="${col.formatValue+ "Resource"}">
                                                            </select>
                                                            <script>
                                                                <#if col.defaultValue??>
                                                                    groupModel.set('${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}','${col.defaultValue}');
                                                                </#if>
                                                            </script>
                                                        <#elseif col.formatCode == "LOV">
                                                            <input
                                                                id="${group.groupInternalName}_${col.colInternalName}"
                                                                <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                required
                                                                </#if>
                                                                type="text"
                                                                data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                style="width: 100%;"/>

                                                            </input>
                                                            <script>
                                                                <#if lovDatas?? && col.formatValue??>
                                                                    <#assign lovData = lovDatas[col.formatValue]>
                                                                    <#if lovData??>
                                                                    $("#${group.groupInternalName}_${col.colInternalName}").kendoLov($.extend(${lovData},
                                                                            {
                                                                                select: function(e) {
                                                                                    /*viewModel.model.set('unitId', e.item.unitId);
                                                                                    viewModel.model.set('unitName', e.item.name);*/
                                                                                }
                                                                            }));
                                                                    </#if>
                                                                </#if>
                                                            </script>
                                                        <#else>
                                                            <input  type="text"
                                                                    data-bind="value:${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}"
                                                                    <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                                        required
                                                                    </#if>
                                                                    id="${group.groupInternalName}_${col.colInternalName}"
                                                                    class="k-textbox"
                                                                    style="width: 100%;"/>
                                                            <script>
                                                                <#if col.defaultValue??>
                                                                    groupModel.set('${group.groupInternalName}${group.attributeGroupId}.${col.colInternalName}','${col.defaultValue}');
                                                                </#if>

                                                            </script>

                                                        </#if>

                                                    </div>
                                                </div>
                                            </div>
                                            <#if (col_index+1)%4==0>
                                            </div>
                                            </#if>
                                        </#list>
                                    </div>
                                    <#else>
                                        <p style="margin: 10px;font-size: 17px">未配置屬性列!</p>
                                    </#if>


                                </div>
                            </form>
                        </div>

                    </div>



                    <#--表格形式-->
                    <#elseif group.displayType == "GRID">
                        <#assign cols = groupsCols[group.attributeGroupId?c]>
                        <#if (cols?size>0) >
                            <div id='${"grid" + group_index}' style="border: 1px;"></div>
                            <script>
                                var ${"dataSource" + group_index} = new kendo.data.DataSource({
                                    transport: {
                                        read:  {
                                            url: "${base.contextPath}/attr/${extUrl}/gridQuery",
                                            type : "POST",
                                            dataType: "json"
                                        },
                                        update: {
                                            url: "${base.contextPath}/attr/${extUrl}/gridSubmit",
                                            contentType: "application/json",
                                            type: "POST"
                                        },
                                        create: {
                                            url: "${base.contextPath}/attr/${extUrl}/gridSubmit",
                                            contentType: "application/json",
                                            type: "POST"
                                        },
                                        destroy: {
                                            url: "${base.contextPath}/attr/${extUrl}/gridRemove",
                                            contentType: "application/json",
                                            type: "POST"
                                        },
                                        parameterMap: function(options, type) {
                                            if (type !== "read" && options.models) {
                                                var datas = Hap.prepareSubmitParameter(options, type);
                                                for(var i = 0,len = datas.length; i < len ; i++){
                                                    datas[i].primaryKey = viewModel.model.${pkName};
                                                    datas[i].${pkName} = viewModel.model.${pkName};
                                                }
                                                return kendo.stringify(datas);
                                            } else if (type === "read") {
                                                return Hap.prepareQueryParameter(
                                                        {
                                                            primaryKey:viewModel.model.${pkName},
                                                            <#if primaryKey??>
                                                                ${pkName}:viewModel.model.${pkName},
                                                            <#else>
                                                                ${pkName}:viewModel.model.${pkName},
                                                            </#if>
                                                            attributeGroupId:${group.attributeGroupId},
                                                            pkName:"${pkName}",
                                                            dtoFullName :"${dtoFullName}"

                                                        }, options);
                                            }
                                        }
                                    },
                                    requestEnd:function(e){
                                        if((e.type === "create" ||  e.type === "update") && e.response.success === true){
                                            kendo.ui.showInfoDialog({
                                                message:"保存成功!"
                                            })
                                        }
                                    },
                                    batch: true,
                                    pageSize: 10,
                                    schema: {
                                        data:'rows',
                                        total:'total',
                                        model: {
                                            id: "extId",
                                            fields: {
                                <#-- 數據源的數據配置 -->
                                    <#list cols as col>
                                        ${col.colInternalName}:{
                                            field :"${col.colInternalName}",

                                            <#if col.formatCode == "BOOLEAN">
                                                type:"boolean",
                                                checkedValue: 'Y',
                                                uncheckedValue: 'N',
                                            <#elseif col.formatCode == "GEN">
                                                type:"string",
                                            <#elseif col.formatCode == "DATE">
                                                type:"date",
                                            <#elseif col.formatCode == "DATETIME">
                                                type:"date",
                                            <#elseif col.formatCode == "NUM">
                                                type:"number",
                                            </#if>

                                            <#if col.defaultValue??>
                                                    defaultValue: "${col.defaultValue}",
                                            </#if>
                                            <#if col.requiredFlag?? && col.requiredFlag == "Y">
                                                validation: { required: true}
                                            </#if>
                                        },
                                    </#list>
                                        primaryKey: {
                                            type:"number",
                                            field:"${pkName}"
                                        },
                                        dtoFullName: {
                                            type:"string",
                                            field:"dtoFullName",
                                            defaultValue: "${dtoFullName}"
                                        },
                                        pkName: {
                                            type:"string",
                                            field:"pkName",
                                            defaultValue: "${pkName}"
                                        },
                                        attributeGroupId: {
                                            type:"number",
                                            field:"attributeGroupId",
                                            defaultValue: ${group.attributeGroupId}
                                        }
                                    }
                                }
                                }
                                });

                                var ${"grid" + group_index} =$("#${"grid" + group_index}").kendoGrid({
                                    toolbar: [
                                        {
                                            template:'<span style="float: right" class="btn btn-warning"  data-bind="click:${"grid" + group_index + "Cancel"}">' +
                                            '<i class="fa fa-warning"></i>取消</span>'

                                        },
                                        {
                                            template:'<span style="float: right" class="btn btn-success"  data-bind="click:${"grid" + group_index + "Save"}">' +
                                            '<i class="fa fa-save" style="margin-right:3px;"></i>保存</span>'

                                        },
                                        {
                                            template:'<span style="float: right" class="btn btn-primary"  data-bind="click:${"grid" + group_index + "Insert"}">' +
                                            '<i class="fa fa-plus-square" style="margin-right:3px;"></i>新增</span>'

                                        }
                                    ],
                                    dataSource: ${"dataSource" + group_index},
                                    navigatable: false,
                                    height:'100%',
                                    resizable: true,
                                    scrollable: true,
                                    editable:true,
                                    height:350,
                                    selectable:'row',
                                    rownumber: true,
                                    edit:function(e){

                                        if(typeof(viewModel.model.${pkName}) === "undefined"){
                                            kendo.ui.showInfoDialog({
                                                message: '請保存先保存項目,再進行屬性組操作!'
                                            });
                                            preventDefault();
                                            return;
                                        }

                                        if(viewModel.model.${pkName} == null){
                                            kendo.ui.showInfoDialog({
                                                message: '請保存先保存項目,再進行屬性組操作!'
                                            });
                                            preventDefault();
                                            return;
                                        }

                                    },
                                    pageable   : {
                                        pageSizes  : [5, 10, 20, 50],
                                        refresh    : true,
                                        buttonCount: 5
                                    },
                                    columns: [
                                        <#list cols as col>
                                            <#if !col.displayFlag?? || col.displayFlag =="Y" >
                                                {
                                                    field: "${col.colInternalName}",
                                                    title: '${col.colDisplayName}',
                                                    <#if col.formatMask??>
                                                        format:'{0:${col.formatMask}}',
                                                    </#if>
                                                    <#-- 當類型屬于Boolean的時候,checkbox需要居中 -->
                                                    <#if col.formatCode == "BOOLEAN">
                                                        width:100,
                                                        attributes:{
                                                            style: "text-align: center;"
                                                        }
                                                    <#elseif col.formatCode == "LIST">
                                                        template: function (dataItem) {
                                                            var v = dataItem.${col.colInternalName};
                                                            $.each(${col.formatValue+ "Resource"}, function (i, n) {
                                                                if ((n.value || '')
                                                                        == (v || '')) {
                                                                    v = n.meaning;
                                                                    return v;
                                                                }
                                                            });
                                                            return v;
                                                        },
                                                        editor: function (container, options) {
                                                        $('<input  name="' + options.field + '"/>')
                                                                .appendTo(container)
                                                                .kendoDropDownList({
                                                                    dataTextField: "meaning",
                                                                    dataValueField: "value",
                                                                    dataSource: ${col.formatValue+ "Resource"}
                                                                });
                                                        }
                                                    <#elseif col.formatCode == "LOV">
                                                        template: function (dataItem) {
                                                            return dataItem['${col.colInternalName}'] || '';
                                                        },
                                                        editor: function(container, options){
                                                            <#if lovDatas?? && col.formatValue??>
                                                                <#assign lovData = lovDatas[col.formatValue]>
                                                                <#if lovData??>
                                                                    $('<input name="${col.colInternalName}" class="k-input k-text-box"/>')
                                                                            .appendTo(container)
                                                                            .kendoLov($.extend(${lovData}, {
                                                                                textField: '${col.colInternalName}',
                                                                                select:function(e){
                                                                                },
                                                                                model: options.model
                                                                            }));
                                                                </#if>
                                                            </#if>
                                                        }
                                                    </#if>
                                                },
                                            </#if>
                                        </#list>
                                        {
                                            title: '刪除',
                                            width : 50,
                                            attributes  : {style: "text-align:center"},
                                            headerAttributes: {
                                                style  : "text-align: center"
                                            },
                                            command:[{
                                                name:"destroy",
                                                text:""
                                            }]
                                        }

                                    ]
                                }).data("kendoGrid");

                            </script>

                        <#else >
                            <p style="margin: 10px;font-size: 17px">未配置屬性列!</p>

                        </#if>
                    </#if>
                </div>
            </#list>

</div>

<script>

    $("#tabstrip-groups").kendoTabStrip({
    });


    <#-- bind groupModel -->
    kendo.bind($('#tabstrip-groups'), groupModel);

    <#-- 屬性組form數據的綁定, 讀取,更新和新建操作 -->

    groupModel.groupFromsRead();

</script>
<#else>
<div>

</div>
</#if>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容