| // Copyright (c) 2000-2017 Ericsson Telecom AB // |
| // All rights reserved. This program and the accompanying materials are made available under the // |
| // terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at // |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html // |
| /////////////////////////////////////////////////////////////////////////////////////////////////////// |
| function CView_Table_Vertical(p_viewmodels, p_mainId, p_parentId, p_data) { |
| "use strict"; |
| |
| /** constructor */ |
| |
| var v_viewmodels = ViewUtils.getViewmodelsFromExpectedInterface(p_viewmodels, CView_Table_Vertical); |
| this.dataViewmodel = v_viewmodels[0]; |
| this.sortViewmodel = v_viewmodels[1]; |
| var v_conditionViewmodel = v_viewmodels[2]; |
| |
| var v_parentId = p_parentId; |
| this.mainId = p_mainId; |
| this.tableWrapperId = this.mainId + "_TableWrapper"; |
| this.tableId = this.mainId + "_Table"; |
| this.customData = p_data; |
| this.subViewDescriptors; |
| |
| this.mainClass = "ElementTable_Vertical"; |
| if (this.customData.class != undefined) { |
| this.mainClass = this.customData.class; |
| } |
| |
| var v_currentTableData = { |
| "selection": [], |
| "table": [], |
| "separators": [] |
| }; |
| var v_currentHeader = []; |
| this.subViews = []; |
| |
| var v_this = this; |
| |
| /** public functions */ |
| |
| this.applicationCreated = function() { |
| if (v_this.dataViewmodel != undefined) { |
| createTable(); |
| setupCallbacks(); |
| } |
| }; |
| |
| this.refresh = function(p_fullRefresh) { |
| if (v_this.dataViewmodel != undefined) { |
| if (ViewUtils.checkVisibility(v_conditionViewmodel, v_this.mainId)) { |
| var newTableData = v_this.dataViewmodel.getTable(); |
| if (newTableData == undefined || newTableData.table == undefined) { |
| return; |
| } |
| if (v_this.sortViewmodel != undefined) { |
| newTableData = v_this.sortViewmodel.getAlteredData(newTableData); |
| } |
| if (newTableData.separators == undefined) { |
| newTableData.separators = []; |
| } |
| |
| var newSeparatorsNeeded = JSON.stringify(v_currentTableData.separators) != JSON.stringify(newTableData.separators); |
| // we remove the existing separators |
| if (newSeparatorsNeeded) { |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_Separator").remove(); |
| } |
| |
| if (p_fullRefresh && !headerEquals(v_this.dataViewmodel.getHeader(), v_currentHeader)) { |
| v_currentHeader = v_this.dataViewmodel.getHeader(); |
| createSubviewList(); |
| destroyTableData(); |
| v_this.createHeader(v_currentHeader); |
| v_this.addDataToTable(newTableData.table.length, v_currentHeader.length); |
| } else if (newTableData.table.length != v_currentTableData.table.length) { |
| // If new table has more rows, the number will be positive, so we add as many rows. If it is negative, we remove the rows. |
| // This can be made protected, so the vertical table will only have to override this function... and a few others |
| v_this.addDataToTable(newTableData.table.length - v_currentTableData.table.length, v_currentHeader.length); |
| } |
| |
| v_currentTableData = newTableData; |
| |
| if (newSeparatorsNeeded) { |
| v_this.createSeparators(v_currentTableData.separators); |
| } |
| |
| for (var i = 0; i < v_this.subViews.length; ++i) { |
| for (var j = 0; j < v_this.subViews[i].length; ++j) { |
| // if we have a subview instance, we refresh it, or we simply update the content of the cell |
| if (v_this.subViews[i][j] != undefined && v_this.subViews[i][j].refresh != undefined) { |
| v_this.subViews[i][j].refresh(p_fullRefresh); |
| } else { |
| updateCell(i,j); |
| } |
| } |
| } |
| |
| v_this.setSelection(newTableData.selection); |
| setSearchAndFilter(); |
| |
| //setHeight(); |
| } |
| } |
| }; |
| |
| /** protected functions */ |
| |
| this.setSelection = function(selection) { |
| $("#" + v_this.tableId + " tbody tr td").removeClass(v_this.mainClass + "_Selected"); |
| if (selection != undefined) { |
| for (var i = 0; i < selection.length; ++i) { |
| $("#" + v_this.tableId + " tbody tr td:nth-child(" + (selection[i] + 2) + ")").addClass(v_this.mainClass + "_Selected"); |
| } |
| } |
| }; |
| |
| this.addDataToTable = function(p_numberOfRows, p_numberOfColumns) { |
| var numberOfRows = $("#" + v_this.tableId + " tbody tr:first td").length; |
| if (p_numberOfRows > 0) { |
| |
| var rows = $("#" + v_this.tableId + " tbody tr"); |
| |
| for (var j = 0; j < p_numberOfColumns; ++j) { |
| var html = ''; |
| for (var i = 0; i < p_numberOfRows; ++i) { |
| html += '<td id="' + v_this.tableId + "_SubView_" + (numberOfRows + i) + "_" + j + '"></td>'; |
| } |
| $(rows[j]).append(html); |
| } |
| |
| // create the subviews where applicable |
| |
| for (var i = 0; i < p_numberOfRows; ++i) { |
| var subViews = []; |
| for (var j = 0; j < p_numberOfColumns; ++j) { |
| if (v_this.subViewDescriptors != undefined && v_this.subViewDescriptors[j] != undefined && v_this.subViewDescriptors[j].subView != undefined && window[v_this.subViewDescriptors[j].subView] != undefined) { |
| var parentId = v_this.tableId + "_SubView_" + (numberOfRows + i) + "_" + j; |
| var viewId = v_this.tableId + "_SubView_" + (numberOfRows + i) + "_" + j + "_View"; |
| var viewmodel = new v_this.ViewmodelProxy(numberOfRows + i, j); |
| |
| var subView = new window[v_this.subViewDescriptors[j].subView]([viewmodel], viewId, parentId, v_this.subViewDescriptors[j]); |
| subView.applicationCreated(); |
| ViewUtils.applyCss(v_this.subViewDescriptors[j], viewId); |
| ViewUtils.processCss(v_this.subViewDescriptors[j], parentId); |
| subViews.push(subView); |
| } else { |
| // we must ensure that there are as many subviews as the number of cells in the table |
| subViews.push(null); |
| } |
| } |
| v_this.subViews.push(subViews); |
| } |
| } else { |
| for (var i = 0; i > p_numberOfRows; --i) { |
| v_this.subViews.pop(); |
| } |
| // we remove the correct number of rows from the DOM and the subviews |
| $("#" + v_this.tableId + " tbody tr").each(function() { |
| $(this).find("td").slice(numberOfRows + p_numberOfRows).remove(); |
| }); |
| } |
| }; |
| |
| this.createHeader = function(p_headerList) { |
| var html = ''; |
| for (var i = 0; i < p_headerList.length; ++i) { |
| html += '<tr><th>' + p_headerList[i].heading + '</th></tr>'; |
| } |
| |
| $("#" + v_this.tableId).append(html); |
| var firstCol = $("#" + v_this.tableId + " tbody tr th"); |
| firstCol.addClass(v_this.mainClass + "_Header"); |
| |
| if (v_this.customData.displayHeader === false) { |
| firstCol.css("display", "none"); |
| } |
| }; |
| |
| this.createSeparators = function(separators) { |
| // nothing to do yet |
| }; |
| |
| this.setupSelection = function() { |
| $("#" + v_this.tableId).on("click", "td", function() { |
| var index = $(this).index() - 1; |
| if (index >= 0) { |
| v_this.dataViewmodel.select(v_this.getUnalteredIndex(index)); |
| } |
| }); |
| }; |
| |
| this.getUnalteredIndex = function(index) { |
| if (v_this.sortViewmodel != undefined) { |
| return v_this.sortViewmodel.getUnalteredIndex(index); |
| } else { |
| return index; |
| } |
| }; |
| |
| this.displayFilter = function() { |
| return v_this.sortViewmodel != undefined && v_this.customData.filter !== false; |
| }; |
| |
| this.displaySort = function() { |
| return v_this.sortViewmodel != undefined && v_this.customData.sort === true; |
| }; |
| |
| this.getIndexOfTableHeaderBasedOnOrientation = function(obj) { |
| return obj.parent().index(); |
| }; |
| |
| /** private functions */ |
| |
| function updateCell(p_row, p_col) { |
| |
| if (v_currentTableData.table[p_row][p_col] == undefined) { |
| $("#" + v_this.tableId + "_SubView_" + p_row + "_" + p_col).addClass("NoData"); |
| $("#" + v_this.tableId + "_SubView_" + p_row + "_" + p_col).html(""); |
| } else { |
| $("#" + v_this.tableId + "_SubView_" + p_row + "_" + p_col).removeClass("NoData"); |
| $("#" + v_this.tableId + "_SubView_" + p_row + "_" + p_col).html(v_currentTableData.table[p_row][p_col].val); |
| } |
| } |
| /* |
| function setHeight() { |
| if (v_this.customData.autoHeight != true) { |
| if (v_this.customData.displayName !== false || v_this.displayFilter()) { |
| $("#" + v_this.tableWrapperId).height("" + ( $("#" + v_this.mainId).innerHeight() - $("#" + v_this.mainId + " ." + v_this.mainClass + '_HeaderBar').outerHeight() ) + "px"); |
| } else { |
| $("#" + v_this.tableWrapperId).height("100%"); |
| } |
| } |
| } |
| */ |
| function createSubviewList() { |
| if (v_this.customData.columns != undefined) { |
| v_this.subViewDescriptors = []; |
| for (var i = 0; i < v_currentHeader.length; ++i) { |
| if (v_currentHeader[i].elementIndex != undefined && v_this.customData.columns[v_currentHeader[i].elementIndex] != undefined) { |
| v_this.subViewDescriptors.push(v_this.customData.columns[v_currentHeader[i].elementIndex]); |
| } |
| } |
| } |
| } |
| |
| function setSearchAndFilter() { |
| if (v_this.displaySort()) { |
| var headers = $("#" + v_this.tableId + " tbody tr th"); |
| headers.removeClass(v_this.mainClass + "_Sort_Asc"); |
| headers.removeClass(v_this.mainClass + "_Sort_Desc"); |
| headers.addClass(v_this.mainClass + "_Sort_No"); |
| |
| var currentSort = v_this.sortViewmodel.getSort(); |
| if (currentSort != undefined) { |
| if (currentSort.sortDirection == "asc") { |
| $(headers[currentSort.sortBy]).removeClass(v_this.mainClass + "_Sort_No").addClass(v_this.mainClass + "_Sort_Asc"); |
| } else if (currentSort.sortDirection == "desc") { |
| $(headers[currentSort.sortBy]).removeClass(v_this.mainClass + "_Sort_No").addClass(v_this.mainClass + "_Sort_Desc"); |
| } |
| } |
| } |
| |
| if (v_this.displayFilter()) { |
| var inputBox = $("#" + v_this.mainId + " ." + v_this.mainClass + "_SearchInput"); |
| var currentVal = inputBox.val(); |
| var newVal = v_this.sortViewmodel.getFilter(); |
| if (newVal != currentVal) { |
| inputBox.val(newVal); |
| } |
| } else { |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_Name").width("100%"); |
| } |
| } |
| |
| function headerEquals(header1, header2) { |
| return JSON.stringify(header1) == JSON.stringify(header2); |
| } |
| |
| function destroyTableData() { |
| $("#" + v_this.tableId).empty(); |
| v_this.subViews = []; |
| } |
| |
| function createTable() { |
| var html = '<div id="' + v_this.mainId + '">' + |
| '<div class="' + v_this.mainClass + '_HeaderBar">' + |
| '<label class="' + v_this.mainClass + '_Name">' + getName() + '</label>' + |
| '<label class="' + v_this.mainClass + '_SearchLabel">Search:</label>' + |
| '<input class="' + v_this.mainClass + '_SearchInput"></input>' + |
| '</div>' + |
| '<div class="' + v_this.mainClass + '_TableWrapper" id="' + v_this.tableWrapperId + '">' + |
| '<table id="' + v_this.tableId +'"></table>' + |
| '</div>' + |
| '</div>'; |
| |
| $("#" + v_parentId).append(html); |
| $("#" + v_this.mainId).addClass(v_this.mainClass); |
| |
| if (v_this.customData.displayName === false && !v_this.displayFilter()) { |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_HeaderBar").css("display", "none"); |
| } else if (!v_this.displayFilter()) { |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_SearchLabel").css("display", "none"); |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_SearchInput").css("display", "none"); |
| } |
| } |
| |
| function getName() { |
| if (v_this.customData.displayName === false) { |
| return ""; |
| } else { |
| if (v_this.customData.name != undefined) { |
| return v_this.customData.name; |
| } else { |
| return v_this.dataViewmodel.getName(); |
| } |
| } |
| } |
| |
| function setupCallbacks() { |
| v_this.setupSelection(); |
| setupSortAndFilter(); |
| } |
| |
| function setupSortAndFilter() { |
| if (v_this.displayFilter()) { |
| $("#" + v_this.mainId + " ." + v_this.mainClass + "_SearchInput").on("input", function(event) { |
| v_this.sortViewmodel.setFilter(event.currentTarget.value); |
| }); |
| } |
| |
| if (v_this.displaySort()) { |
| $("#" + v_this.tableId).on("click", "th", function() { |
| var obj = $(this); |
| if (obj.hasClass(v_this.mainClass + "_Sort_Asc")) { |
| v_this.sortViewmodel.setSort({ |
| "sortBy": v_this.getIndexOfTableHeaderBasedOnOrientation(obj), |
| "sortDirection": "desc" |
| }); |
| } else if (obj.hasClass(v_this.mainClass + "_Sort_Desc")) { |
| v_this.sortViewmodel.setSort(undefined); |
| } else { |
| v_this.sortViewmodel.setSort({ |
| "sortBy": v_this.getIndexOfTableHeaderBasedOnOrientation(obj), |
| "sortDirection": "asc" |
| }); |
| } |
| }); |
| } |
| } |
| |
| /** protected classes */ |
| |
| this.ViewmodelProxy = function(p_row, p_col) { |
| |
| var v_row = p_row; |
| var v_col = p_col; |
| |
| this.select = v_this.dataViewmodel.select; |
| |
| this.getList = function() { |
| return { |
| "selections": [v_currentTableData.selection], |
| "values": [[v_currentTableData.table[v_row][v_col].val], undefined, v_currentTableData.table[v_row][v_col].isWritable] |
| }; |
| }; |
| |
| this.getListWithElementInfo = function() { |
| return { |
| "selections": [v_currentTableData.selection], |
| "values": [ |
| { |
| "element": v_currentHeader[v_col].heading, |
| "val": v_currentTableData.table[v_row][v_col].val, |
| "isWritable": v_currentTableData.table[v_row][v_col].isWritable |
| } |
| ] |
| }; |
| }; |
| |
| this.setValue = function(p_dataPathIndex, p_value, p_indexInList, p_lastSelectionIndexes, p_callback, p_additionalData) { |
| v_this.dataViewmodel.setValue(v_this.getUnalteredIndex(v_row), v_col, p_value, p_callback, p_additionalData); |
| }; |
| |
| this.getState = function() { |
| return v_currentTableData.table[v_row][v_col].tp != 0; |
| }; |
| |
| this.getDataList = v_this.dataViewmodel.getDataList; |
| }; |
| } |
| |
| CView_Table_Vertical.getHelp = function() { |
| return "A table view whose rows can contain single element subviews.\n" + |
| "It reguires a table viewmodel. Optionally, a sort and filter viewmodel can be connected to this view."; |
| }; |
| |
| CView_Table_Vertical.expectsInterface = function() { |
| return [ |
| { |
| "mandatory": ["select", "getName", "getHeader", "getTable", "setValue"], |
| }, |
| { |
| "optional": ["getAlteredData", "getFilter", "getSort", "setFilter", "setSort", "getUnalteredIndex"] |
| }, |
| { |
| "optional": ["getState"] |
| } |
| ]; |
| }; |
| |
| CView_Table_Vertical.getCustomDataSchema = function() { |
| var schema = { |
| "$schema": "http://json-schema.org/draft-04/schema#", |
| "title": "Custom data for CView_Table_Vertical", |
| "type": "object", |
| "properties": { |
| "class": { |
| "description": "The css class of the table", |
| "type": "string", |
| "default": "ElementTableVertical" |
| }, |
| "displayName": { |
| "description": "Whether we display the table name (default true)", |
| "type": "boolean", |
| "format": "checkbox", |
| "default": false |
| }, |
| "displayHeader": { |
| "description": "Whether we display the table header bar (default true)", |
| "type": "boolean", |
| "format": "checkbox", |
| "default": false |
| }, |
| "autoHeight": { |
| "description": "Whether the table will take up as much vertical space as needed (default false: takes up only the available space). Use true if the height of the parent is unknown.", |
| "type": "boolean", |
| "format": "checkbox", |
| "default": true |
| }, |
| "filter": { |
| "description": "Whether we allow filtering (default true)", |
| "type": "boolean", |
| "format": "checkbox", |
| "default": false |
| }, |
| "sort": { |
| "description": "Whether we allow sorting", |
| "type": "boolean", |
| "format": "checkbox", |
| "default": true |
| }, |
| "name": { |
| "description": "The table name", |
| "type": "string" |
| }, |
| "columns": { |
| "description": "The columns of the table can contain single element subviews. The name of the subview, the flex of the column and the custom data of the subview can be specified in an item.", |
| "type": "array", |
| "format": "tabs", |
| "items": { |
| "type": "object", |
| "title": "subView", |
| "properties": { |
| "subView" : { |
| "type" : "string", |
| "description": "the class name of the subview" |
| } |
| }, |
| "additionalProperties": true |
| } |
| } |
| }, |
| "additionalProperties": false |
| }; |
| $.extend(true, schema, ViewUtils.commonViewSchema); |
| return schema; |
| }; |
| |
| //# sourceURL=WebApplicationFramework\Views\View_Table_Vertical.js |