Просмотр исходного кода

Merge branch '1.0.0_online' of http://smartcost.f3322.net:3000/SmartCost/ConstructionOperation into 1.0.0_online

TonyKang 7 лет назад
Родитель
Сommit
41c111dd31

+ 4 - 0
modules/ration_repository/controllers/ration_repository_controller.js

@@ -197,6 +197,7 @@ class RationRepositoryController extends baseController {
                     await rationItem.batchUpdateSectionIdFromExcel(sheet[0].data);
                 if (rationItem.failGLJList && rationItem.failGLJList.length > 0) {
                     responseData.msg = rationItem.failGLJList.join("\r\n");
+                    rationItem.failGLJList = [];
                 }
                 // 删除文件
                 if(uploadFullName && fs.existsSync(uploadFullName)){
@@ -265,6 +266,9 @@ class RationRepositoryController extends baseController {
             let stdGLJList = {};
             let stdGLJListByID = {};
             for (const tmp of stdGLJData) {
+                if (tmp.priceProperty && tmp.priceProperty.price1) {
+                    tmp.basePrice = tmp.priceProperty.price1;
+                }
                 stdGLJList[tmp.code.toString()] = tmp.ID;
                 stdGLJListByID[tmp.ID] = tmp;
             }

+ 1 - 1
modules/std_billsGuidance_lib/routes/routes.js

@@ -24,7 +24,7 @@ module.exports = function (app) {
     router.post('/getItemsByBills', billsGuideLibController.auth, billsGuideLibController.init, billsGuideLibController.getItemsByBills);
     router.post('/updateItems', billsGuideLibController.auth, billsGuideLibController.init, billsGuideLibController.updateItems);
     //test
-    router.post('/testItems', billsGuideLibController.auth, billsGuideLibController.init, billsGuideLibController.testItems);
+    //router.post('/testItems', billsGuideLibController.auth, billsGuideLibController.init, billsGuideLibController.testItems);
 
 
     app.use('/billsGuidance/api', router);

+ 3 - 1
modules/users/controllers/compilation_controller.js

@@ -61,7 +61,9 @@ class CompilationController extends BaseController {
         } catch (error) {
             console.log(error);
         }
-
+        if (selectedCompilation.example) {
+            selectedCompilation.example = selectedCompilation.example.join(';');
+        }
         let renderData = {
             id: id,
             compilationList: compilationList,

+ 4 - 0
public/web/id_tree.js

@@ -781,6 +781,10 @@ var idTree = {
         Tree.prototype.getDownLevelDatas = function (nodes) {
             let dataMap = {},updateDatas=[],nextID,last;//注释同m_downLevel 方法
             let newParent = nodes[0].preSibling;//{"type":"update","data":{"ID":3,"ParentID":-1,"NextSiblingID":5}}
+            let newPre = newParent.children && newParent.children.length > 0 ? newParent.children[newParent.children.length -1]:null;
+            if(newPre){ //如果新的父节点有子节点,则把新的父节点的最后一个子节点的下一节点的值改成第一个选中节点的ID
+                dataMap[newPre.getID()] = {"ID":newPre.getID(),"NextSiblingID":nodes[0].getID()}
+            }
             for(let n of nodes){
                 nextID = n.getNextSiblingID();
                 last = n;

+ 50 - 43
web/maintain/billsGuidance_lib/html/zhiyin.html

@@ -31,67 +31,73 @@
         </nav>
     </div>
     <div class="main">
-        <div class="content">
+        <div class="content" style="overflow: hidden">
             <div class="container-fluid">
-                <div class="row">
-                    <div class="main-side col-lg-4 p-0">
+                <div class="row" id="dataRow">
+                    <div class="main-side p-0" id="leftContent" style="width: 33%">
                         <div id="billsSpread" class="main-side-top">
                         </div>
                         <div class="main-side-bottom">
                             <textarea class="form-control"></textarea>
                         </div>
                     </div>
-                  <div class="main-content col-lg-4 p-" style="margin: 0; padding: 0;">
-                    <div class="toolsbar px-1 d-flex justify-content-between">
-                      <div class="tools-btn btn-group align-top">
-                        <a id="insert" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="插入"><i class="fa fa-reply-all" aria-hidden="true"></i> 插入</a>
-                        <a id="del" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
-                        <a id="upLevel" href="javascript:void(0);" class="btn btn-sm disabled" data-toggle="tooltip" data-placement="bottom" title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
-                        <a id="downLevel" href="javascript:void(0);" class="btn btn-sm disabled" data-toggle="tooltip" data-placement="bottom" title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
-                        <a id="downMove" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
-                        <a id="upMove" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
-                        <a id="expandContract" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="收起定额"><i class="fa fa-minus-square-o" aria-hidden="true"></i> 收起定额</a>
-                      </div>
-                    </div>
-                      <div class="main-top-content">
-                          <div id="guideItemSpread" class="main-data"></div>
-                    </div>
-                      <div class="main-bottom-content">
-                          <textarea class="form-control"></textarea>
+                  <div class="main-content p-0" id="midContent" style="width: 34%">
+                      <div class="resize" id="slideResizeLeft" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                      <div style="width: 99%; float: left">
+                          <div class="toolsbar px-1 d-flex justify-content-between">
+                              <div class="tools-btn btn-group align-top">
+                                  <a id="insert" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="插入"><i class="fa fa-reply-all" aria-hidden="true"></i> 插入</a>
+                                  <a id="del" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                                  <a id="upLevel" href="javascript:void(0);" class="btn btn-sm disabled" data-toggle="tooltip" data-placement="bottom" title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
+                                  <a id="downLevel" href="javascript:void(0);" class="btn btn-sm disabled" data-toggle="tooltip" data-placement="bottom" title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
+                                  <a id="downMove" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
+                                  <a id="upMove" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
+                                  <a id="expandContract" href="javascript:void(0);" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="收起定额"><i class="fa fa-minus-square-o" aria-hidden="true"></i> 收起定额</a>
+                              </div>
+                          </div>
+                          <div class="main-top-content">
+                              <div id="guideItemSpread" class="main-data"></div>
+                          </div>
+                          <div class="main-bottom-content">
+                              <textarea class="form-control"></textarea>
+                          </div>
                       </div>
                   </div>
-                    <div class="main-side col-lg-4 p-" style="margin: 0; padding: 0;" id="de">
-                        <div class="sidebar-tools-bar container-fluid tools-bar-height-q">
-                            <div class="p-1 row">
-                                <div class="col-5 p-0">
-                                    <select class="form-control form-control-sm" id="rationLibSel">
-                                    </select>
-                                </div>
-                                <div class=" input-group col-5">
-                                    <input id="searchText" type="text" class="form-control form-control-sm" placeholder="搜索定额">
-                                    <span class="input-group-btn">
+                    <div class="main-side p-0" id="rightContent" style="width:33%">
+                        <div class="resize" id="slideResizeRight" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
+                        <div style="width: 99%; float: left" id="de">
+                            <div class="sidebar-tools-bar container-fluid tools-bar-height-q">
+                                <div class="p-1 row">
+                                    <div class="col-5 p-0">
+                                        <select class="form-control form-control-sm" id="rationLibSel">
+                                        </select>
+                                    </div>
+                                    <div class=" input-group col-5">
+                                        <input id="searchText" type="text" class="form-control form-control-sm" placeholder="搜索定额">
+                                        <span class="input-group-btn">
                                         <button id="searchBtn" class="btn btn-secondary btn-sm" type="button"><i class="fa fa-search" aria-hidden="true"></i></button>
                                     </span>
+                                    </div>
+                                    <div class="col-2">
+                                        <button id="insertRation" class="btn btn-primary btn-sm" type="button">插入定额</button>
+                                    </div>
                                 </div>
-                                <div class="col-2">
-                                    <button id="insertRation" class="btn btn-primary btn-sm" type="button">插入定额</button>
+                                <!--搜索结果窗体-->
+                                <div class="side-search-box col-12 p-0" id="rationSearchResult" style="display: none;">
+                                    <div class="d-flex justify-content-between">
+                                        <span id="searchCount">搜索结果:153</span><a title="关闭搜索" class="btn btn-link btn-sm" href="javascript:void(0)"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                                    </div>
                                 </div>
                             </div>
-                            <!--搜索结果窗体-->
-                            <div class="side-search-box col-12 p-0" id="rationSearchResult" style="display: none;">
-                                <div class="d-flex justify-content-between">
-                                    <span id="searchCount">搜索结果:153</span><a title="关闭搜索" class="btn btn-link btn-sm" href="javascript:void(0)"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                            <div class="top-content" style="overflow: hidden; width: 100%">
+                                <div class="main-data-top" id="sectionSpread">
                                 </div>
                             </div>
-                        </div>
-                        <div class="top-content" style="overflow: hidden">
-                            <div class="main-data-top" id="sectionSpread">
+                            <div class="resize" id="deResize"></div>
+                            <div class="bottom-content">
+                                <div class="main-data-bottom" id="rationSpread"></div>
                             </div>
                         </div>
-                        <div class="resize" id="deResize"></div>
-                        <div class="bottom-content">
-                            <div class="main-data-bottom" id="rationSpread"></div>
-                        </div>
                     </div>
                   </div>
                 </div>
@@ -139,6 +145,7 @@
     <script src="/public/web/tree_sheet/tree_sheet_controller.js"></script>
     <script src="/public/web/tree_sheet/tree_sheet_helper.js"></script>
     <script src="/web/maintain/billsGuidance_lib/js/billsGuidance.js"></script>
+    <script src="/web/common/js/slideResize.js"></script>
 </body>
 <script type="text/javascript">
     autoFlashHeight();

+ 78 - 17
web/maintain/billsGuidance_lib/js/billsGuidance.js

@@ -11,7 +11,7 @@ const billsGuidance = (function () {
     function _isDef(v) {
         return typeof v !== 'undefined' && v !== null;
     }
-
+    let moduleName = 'stdBillsGuidance';
     //自执行函数全局变量定义
     const libID = getQueryString('libID');
     //总工作内容数据
@@ -879,6 +879,8 @@ const billsGuidance = (function () {
             }
         });
     }
+    //编辑后自动去除换行符回车符
+    const deESC = /[\r, \n]/g;
     //项目指引编辑
     //@param {Object}sheet {Array}cells
     function edit(sheet, cells){
@@ -887,7 +889,9 @@ const billsGuidance = (function () {
         let syncDatas = [];
         for(let cell of cells){
             let text = sheet.getValue(cell.row, cell.col);
-            text = text ? text : '';
+            text = text ? text.toString() : '';
+            text = text.replace(deESC, '');
+            sheet.setValue(cell.row, cell.col, text);
             let node = bills.tree.selected.guidance.tree.items[cell.row];
             if(node.data.name != text){
                 syncDatas.push({node: node, text: text});
@@ -969,22 +973,42 @@ const billsGuidance = (function () {
     function del(){
         $.bootstrapLoading.start();
         let controller = bills.tree.selected.guidance.controller;
-        let selected = bills.tree.selected.guidance.tree.selected;
+        let selNodes = [];
+        let sheet = guideItem.workBook.getSheet(0);
+        let sel = sheet.getSelections()[0];
+        if(sel){
+            sel.row =  sel.row === -1 ? 0 : sel.row;
+            for(let i = 0; i < sel.rowCount; i++){
+                if(bills.tree.selected.guidance.tree.items[sel.row + i]){
+                    selNodes.push(bills.tree.selected.guidance.tree.items[sel.row + i]);
+                }
+            }
+        }
+        //选中的块节点
+        let blockNodes = getBlockNodes(selNodes);
         let updateDatas = [];
-        function getDelDatas(node){
-            updateDatas.push({updateType: updateType.del, findData: {ID: node.getID()}, updateData: {deleted: true}});
-            if(node.children.length > 0){
-                for(let c of node.children){
-                    getDelDatas(c);
+        function getDelDatas(nodes){
+            for (let node of nodes) {
+                updateDatas.push({updateType: updateType.del, findData: {ID: node.getID()}});
+                if (node.children.length > 0) {
+                    getDelDatas(node.children);
                 }
             }
         }
-        getDelDatas(selected);
-        if(selected.preSibling) {
-            updateDatas.push({updateType: updateType.update, findData: {ID: selected.preSibling.getID()}, updateData: {NextSiblingID: selected.getNextSiblingID()}});
+        getDelDatas(blockNodes);
+        //更新相关的前节点
+        for (let node of blockNodes) {
+            if (node.preSibling && !blockNodes.includes(node.preSibling)) {
+                let next = node;
+                while (next.nextSibling && blockNodes.includes(next.nextSibling)) {
+                    next = next.nextSibling;
+                }
+                updateDatas.push({updateType: updateType.update, findData: {ID: node.preSibling.getID()}, updateData: {NextSiblingID: next.getNextSiblingID()}});
+            }
         }
         updateGuideItems(updateDatas, function () {
-            controller.delete();
+            controller.m_delete(blockNodes);
+            guideItemInitSel(sheet.getActiveRowIndex());
             refreshBtn(bills.tree.selected.guidance.tree.selected);
             setNodesColor(guideItem.workBook.getActiveSheet(), bills.tree.selected.guidance.tree.items);
             $.bootstrapLoading.end();
@@ -1288,8 +1312,6 @@ const billsGuidance = (function () {
             delete data._id;
             updateDatas.push({updateType: updateType.create, updateData: data});
         }
-        console.log(`node`);
-        console.log(node);
         console.log(`pasteDatas`);
         console.log(pasteDatas);
         //更新粘贴到的节点的NextSiblingID
@@ -1735,6 +1757,45 @@ const billsGuidance = (function () {
                 ration.workBook.refresh();
             }
         });
+        //左右拖动
+        //清单表与项目指引表
+        let leftElesObj = {};
+        leftElesObj.resize = $('#slideResizeLeft');
+        leftElesObj.parent = $('#dataRow');
+        leftElesObj.left = $('#leftContent');
+        leftElesObj.right = $('#midContent');
+        horizontalSlide(moduleName, leftElesObj, {min: 200, max: `$('#dataRow').width() - $('#rightContent').width() - 200`}, function () {
+            refreshALlWorkBook();
+        });
+        //人材机表与人材机组成物表
+        let rightElesObj = {};
+        rightElesObj.resize = $('#slideResizeRight');
+        rightElesObj.parent = $('#dataRow');
+        rightElesObj.left = $('#midContent');
+        rightElesObj.right = $('#rightContent');
+        horizontalSlide(moduleName, rightElesObj, {min: 200, max: `$('#dataRow').width() - $('#leftContent').width() - 200`}, function () {
+            refreshALlWorkBook();
+        });
+    }
+    //刷新全部工作簿
+    //@return {void}
+    function refreshALlWorkBook() {
+        if (bills.workBook) {
+            bills.workBook.refresh();
+        }
+        if (guideItem.workBook) {
+            guideItem.workBook.refresh();
+        }
+        if (section.workBook) {
+            section.workBook.refresh();
+        }
+        if (ration.workBook) {
+            ration.workBook.refresh();
+        }
+        $('.main-side-bottom').find('textarea').height($('.main-side-bottom').height() - 20);
+        $('.main-side-bottom').find('textarea').width($('.main-side-bottom').width() - 25);
+        $('.main-bottom-content').find('textarea').height($('.main-bottom-content').height() - 20);
+        $('.main-bottom-content').find('textarea').width($('.main-bottom-content').width() - 25);
     }
     //初始化视图
     //@param {void} @return {void}
@@ -1752,6 +1813,9 @@ const billsGuidance = (function () {
                 ration.workBook.refresh();
             }
         });
+        loadHorizonWidth(moduleName, [$('#leftContent'), $('#midContent'), $('#rightContent')], function () {
+            refreshALlWorkBook();
+        });
     }
 
 
@@ -1760,7 +1824,4 @@ const billsGuidance = (function () {
 
 $(document).ready(function () {
     billsGuidance.initViews();
-    CommonAjax.post('/billsGuidance/api/testItems', {libID: getQueryString('libID')}, function (rstData) {
-        console.log(rstData);
-    });
 });

Разница между файлами не показана из-за своего большого размера
+ 1 - 1
web/maintain/main_col_lib/js/main_col_edit.js


+ 10 - 0
web/maintain/main_col_lib/js/main_tree_col.js

@@ -41,6 +41,16 @@ let MainTreeCol = {
 
     },
     readOnly: {
+        subType:function (node) {
+        },
+        calcProgramName:function (node) {
+        },
+        non_editSubType:function (node) {
+        },
+        commonUnitFee:function (node) {
+        },
+        commonTotalFee:function (node) {
+        },
         bills: function (node) {
             return node.sourceType === projectObj.project.Bills.getSourceType();
         },

+ 14 - 12
web/maintain/ration_repository/dinge.html

@@ -57,19 +57,21 @@
     <div class="main" style="overflow: hidden">
         <div class="content">
             <div class="container-fluid">
-                <div class="row">
-                    <div class="main-side p-0" style="width: 25%; height: 100%; overflow: hidden">
-                        <div class="tab-bar">
-                            <a href="javascript:void(0);" id="tree_Insert" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-plus" aria-hidden="true"></i></a>
-                            <a href="javascript:void(0);" id="tree_remove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
-                            <a href="javascript:void(0);" id="tree_upLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
-                            <a href="javascript:void(0);" id="tree_downLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
-                            <a href="javascript:void(0);" id="tree_downMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
-                            <a href="javascript:void(0);" id="tree_upMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
-                        </div>
-                        <div class="tab-content" id="sectionSpread" style="overflow: hidden">
-                            <!--<ul id="rationChapterTree" class="ztree"></ul>-->
+                <div class="row" id="dataRow">
+                    <div class="main-side p-0" id="leftContent" style="width: 25%; height: 100%; overflow: hidden">
+                        <div style="width: 99%; float: left">
+                            <div class="tab-bar">
+                                <a href="javascript:void(0);" id="tree_Insert" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-plus" aria-hidden="true"></i></a>
+                                <a href="javascript:void(0);" id="tree_remove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                                <a href="javascript:void(0);" id="tree_upLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="升级"><i class="fa fa-arrow-left" aria-hidden="true"></i></a>
+                                <a href="javascript:void(0);" id="tree_downLevel" class="btn btn-sm " data-toggle="tooltip" data-placement="bottom" title="" data-original-title="降级"><i class="fa fa-arrow-right" aria-hidden="true"></i></a>
+                                <a href="javascript:void(0);" id="tree_downMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
+                                <a href="javascript:void(0);" id="tree_upMove" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
+                            </div>
+                            <div class="tab-content" id="sectionSpread" style="overflow: hidden">
+                            </div>
                         </div>
+                        <div class="resize" id="slideResizeLeft" style="width: 1%; height: 100%; resize:horizontal; cursor: w-resize; float: left; background: #F1F1F1"></div>
                     </div>
                     <div class="main-content p-0" id="mainContent" style="width: 75%">
                         <!-- 右标签 -->

+ 6 - 0
web/maintain/ration_repository/js/gljSelect.js

@@ -50,6 +50,12 @@ let gljSelOprObj = {
             timeout:20000,
             success:function(result){
                 if(!result.error) {
+                    if(priceProperties && priceProperties.length > 0){
+                        let priceField = priceProperties[0].price.dataCode;
+                        for(let glj of result.data){
+                            glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
+                        }
+                    }
                     me.stdGljList = result.data;
                     me.switchToGljId(me.stdGljList);
                     me.sortGlj(me.stdGljList);

+ 6 - 0
web/maintain/ration_repository/js/ration_glj.js

@@ -439,6 +439,12 @@ var rationGLJOprObj = {
             success:function(result){
                 if (result) {
                     if(result.data.length > 0){
+                        if(priceProperties && priceProperties.length > 0){
+                            let priceField = priceProperties[0].price.dataCode;
+                            for(let glj of result.data){
+                                glj.basePrice = glj.priceProperty && glj.priceProperty[priceField] ? glj.priceProperty[priceField] : 0;
+                            }
+                        }
                         sheetCommonObj.cleanData(me.sheet, me.setting, -1);
                         var rstArr = [], dummyR = {gljId: 0, consumeAmt:0}, newAddArr = [];
                         for (var i = 0; i < result.data.length; i++) {

+ 1 - 1
web/users/views/compilation/index.html

@@ -100,7 +100,7 @@
             <table class="table">
                 <tr><td><p>软件版本介绍</p><textarea id="description" class="form-control" placeholder="请简要描述改版本"><%= selectedCompilation.description%></textarea></td></tr>
                 <tr><td><span>重写路径:</span><input class="form-control" type="text" id="overWriteUrl" value="<%= selectedCompilation.overWriteUrl%>"></td></tr>
-               <!-- <tr><td><span>例题建设项目ID:</span><input class="form-control" type="text" id="example" value="<%= selectedCompilation.example%>"></td></tr>-->
+                <tr><td><span>例题建设项目ID:</span><input class="form-control" type="text" id="example" value="<%= selectedCompilation.example%>"></td></tr>
                 <tr><td><p>显示办事处销售信息</p>
                     <select class="form-control" style="width:200px" id="category-select">
                         <% categoryList.forEach(function(category) { %>