/** * created by Menna & Yara */ import { ElementRef, Input, Component, ViewChild, OnInit, AfterViewInit, OnDestroy } from '@angular/core'; import { GridComponent } from '../kendo-widgets/grid/grid.component'; import { HttpService } from '../services/service-interface'; import * as GridMessagesEN from '../translation/grid-messages-EN'; import * as GridMessagesAR from '../translation/grid-messages-AR'; import { Mediator } from '../services/mediator'; import { CoreMediatorChannels } from '../utils/mediator-channels'; import { CoreNotificationsMessages } from '../utils/notifications-messages'; import { CookieService } from '../services/cookie-service'; import { GRID_GROUPING_MESSAGE, GRID_PAGER_MESSAGES } from '../translation/grid-messages-AR'; import { TranslateService } from '../services/translate-service'; import { GeneralGridOptions } from '../types/grid-types'; @Component({ selector: 'general-grid', templateUrl: './general-grid-component.html', styleUrls: ['./general-grid-component.css'], }) export class GeneralGridComponent implements OnInit, AfterViewInit, OnDestroy { //********************************Start Of Variables*****************************// @ViewChild("gridRef") private gridRef: GridComponent; @Input() private optionsAdded: GeneralGridOptions; @Input() private httpService: HttpService; private gridMessages: Map; // map contains all options messages which change when change language private selectedItemsCount: number = 0; private checkboxCounter: number = 0; private actionSigns: any = { width: 45, template: (currentRow) => { return `
`; }, filterable: { cell: { enabled: false } }, attributes: { style: "text-align: center;" }, headerAttributes: { style: "text-align: center;" } } //********************************Start Of Columns Intialization*****************************// objectRemoteRestUrl: string; private _selectedItems: any[] = []; private gridColumns: any[] = []; private dataSource: any; private actionsCommands: any[] = []; private selectionColumn: any[] = [ { title: "", template: (currentRow) => { this.checkboxCounter++; return " "; }, width: 45, } ]; private deleteAction: any = { name: 'deleteItem', text: '', className: 'fa fa-trash-o', click: (e) => { e.preventDefault(); let myGrid = $('.k-grid').data('kendoGrid'); let currentRow: any = myGrid.dataItem($(e.target).closest("tr")), id = currentRow.get('id'), code = currentRow.get('code'); var actionSignsId = "#actionsSigns" + currentRow.uid; var actionsSigns = myGrid.tbody.find("tr[data-uid='" + currentRow.uid + "'] span" + actionSignsId); actionsSigns.removeClass("fa fa-check"); actionsSigns.removeClass("fa fa-times"); Mediator.emit(CoreMediatorChannels.CONFIRMATION_DIALOG, { message: this.translateService.instant(CoreNotificationsMessages.DELETE_SINGLE_INSTANCE_MSG), confirm: () => { this.httpService.deleteInstances(this.optionsAdded.objectRemoteRestUrl, [id.toString()], (response) => { let myGrid = $('.k-grid').data('kendoGrid'); myGrid.dataSource.remove(currentRow); //removes it actually from the grid }, (responseBody) => { actionsSigns.addClass("fa fa-times"); var responseErrors = responseBody.data[0].__errors__; var responseGeneralErrors = responseBody.data[0].__general_errors__; currentRow.set("responseErrors", responseErrors); currentRow.set("responseGeneralErrors", responseGeneralErrors); currentRow.set("actionFlag", true); }); }, cancel: () => { } }); } }; private actionsHeader: any[] = [ { title: ' ', width: 150, headerAttributes: { style: "text-align: center;" }, command: this.actionsCommands, filterable: { cell: { enabled: false } }, attributes: { style: "text-align: center;" } }, { title: '', width: 50, filterable: { cell: { enabled: false } }, attributes: { style: "text-align: center;" }, template: "" } ]; private systemLangListener: string; //********************************End of Variables*******************************// //********************************Start of Public Functions***********************************// constructor(httpService: HttpService, private cookieService: CookieService, private translateService: TranslateService) { this.httpService = httpService; this.intializeGridLocalization(); } //#region Grid_Translation /** * @desc Fill Gridmessages map with messages according to selected language and Grid Direction * @memberOf GeneralGridComponent */ intializeGridLocalization() { this.gridMessages = new Map(); if (this.cookieService.getCookie("lang") == "en") { this.tranformRightToLeft(); } else if (this.cookieService.getCookie("lang") == "ar") { this.tranformLeftToRight(); } } /** * @desc set grid messages map with english locale and change grid direction to ltr * @memberOf GeneralGridComponent */ tranformRightToLeft() { this.gridMessages.set("filterOperators", GridMessagesEN.GRID_OPERATORS); this.gridMessages.set("groupingMessages", GridMessagesEN.GRID_GROUPING_MESSAGE); this.gridMessages.set("pagerMessages", GridMessagesEN.GRID_PAGER_MESSAGES); this.gridMessages.set("selectedItemsMessage", GridMessagesEN.GRID_SELECTED_ITEMS_MESSAGE); $('.k-grid').removeClass('k-rtl').addClass('k-ltr'); } /** * @desc set grid messages map with arabic locale and change grid direction to rtl * @memberOf GeneralGridComponent */ tranformLeftToRight() { this.gridMessages.set("filterOperators", GridMessagesAR.GRID_OPERATORS); this.gridMessages.set("groupingMessages", GridMessagesAR.GRID_GROUPING_MESSAGE); this.gridMessages.set("pagerMessages", GridMessagesAR.GRID_PAGER_MESSAGES); this.gridMessages.set("selectedItemsMessage", GridMessagesAR.GRID_SELECTED_ITEMS_MESSAGE); $('.k-grid').removeClass('k-ltr').addClass('k-rtl'); } /** * @desc set options from grid messages map to grid * @memberOf GeneralGridComponent */ gridLanguageTransformation(lang: string) { if (lang == "en") { this.tranformRightToLeft(); } else if (lang == "ar") { this.tranformLeftToRight(); } if (this.gridRef.ProtoType.element) { this.gridRef.ProtoType.setOptions({ filterable: { operators: this.gridMessages.get("filterOperators"), messages: this.gridMessages.get("filterMenuMessages") }, groupable: { messages: this.gridMessages.get("groupingMessages") }, pageable: { messages: this.gridMessages.get("pagerMessages") } }); } } //#endregion ngAfterViewInit() { // In case of reload without select language from menubar and on start at first time if (this.cookieService.getCookie("lang") == "en") { $('.k-grid').removeClass('k-rtl').addClass('k-ltr'); } else if (this.cookieService.getCookie("lang") == "ar") { $('.k-grid').removeClass('k-ltr').addClass('k-rtl'); } this.gridLanguageTransformation(this.cookieService.getCookie("lang")); /** * listen to menubar language button action when , change get the value of it and send it to * gridLanguageTransformation(lang); which set options to grid according to language */ this.systemLangListener = Mediator.subscribe(CoreMediatorChannels.CHANGE_SYSTEM_LANGUAGE, (lang: string) => { this.gridLanguageTransformation(lang); if (this.gridRef.ProtoType.element) { //change grid columns title according to language change let gridColumns = $('.k-grid').data("kendoGrid").columns; for (let column of gridColumns) { $(".k-grid th[data-field=" + column.field + "]").html(this.translateService.instant(column["titleKey"])); } //refresh grid to reparsing data model if (this.gridRef && this.gridRef.ProtoType) { this.gridRef.ProtoType.dataSource.data(this.gridRef.ProtoType.dataSource.options.schema.parse(JSON.parse(JSON.stringify(this.gridRef.ProtoType.dataSource.data())))); } } }); } ngOnInit() { this.addColumns(); this.dataSource = this.optionsAdded.dataSource; } addColumns() { if (this.optionsAdded.validity && this.optionsAdded.validity.length > 0) { for (let column of this.optionsAdded.validity) { this.gridColumns.push(column); } } for (let column of this.selectionColumn) { this.gridColumns.push(column); } for (let column of this.optionsAdded.columns) { if (!column.field) this.gridColumns.push(column); else { column.title = this.translateService.instant(column.titleKey); this.gridColumns.push(column); } } for (let column of this.actionsHeader) { this.gridColumns.push(column); } this.addCommandsBeforeDelete(); this.addCommandsAfterDelete(); this.gridColumns.push(this.actionSigns); } addCommandsBeforeDelete() { if (this.optionsAdded.commandsBeforeDelete && this.optionsAdded.commandsBeforeDelete.length > 0) { for (let command of this.optionsAdded.commandsBeforeDelete) { this.actionsCommands.push(command); } } this.actionsCommands.push(this.deleteAction); } addCommandsAfterDelete() { if (this.optionsAdded.commandsAfterDelete && this.optionsAdded.commandsAfterDelete.length > 0) { for (let command of this.optionsAdded.commandsAfterDelete) { this.actionsCommands.push(command); } } } refreshDataSourceGrid(grid: any, objectRemoteRestUrl: string) { this.httpService.readAll(objectRemoteRestUrl, (response) => { grid.dataSource.data(grid.dataSource.options.schema.parse(response.data)); }); } //********************************End of Public Functions***********************************// homeGridOptions = () => { let gridOptions = { height: '600', groupable: { messages: this.gridMessages.get("groupingMessages") }, filterable: { mode: "row", operators: this.gridMessages.get("filterOperators") }, columns: this.gridColumns, dataSource: this.dataSource, pageable: { buttonCount: 20, pageSizes: true, messages: { empty: this.gridMessages.get("pagerEmptyMessage"), display: this.gridMessages.get("pagerDisplayMessage") }, change: (e) => { $('li > span.k-state-selected').css("background-color", "#7cb342"); $('li > span.k-state-selected').css("border", 0); } }, editable: "popup", sortable: { mode: "single", allowUnsort: false }, dataBound: () => { $(".k-grid table tbody tr").css("background-color", "white"); $(".k-grid table td ").css("border-bottom", "inset"); $(".k-grid table td ").css("border-right-style", "none"); $(".k-grid table td ").css("border-right", "none"); this.checkboxCounter = 0; var generalGrid = $('.k-grid').data('kendoGrid'); //////////////////////////////////Start Of Footer Customization//////////////////////////////////////////// this.selectedItemsCount = 0; $("#selectedItemsSpan").remove(); var selectedItemsCountElement = "" + this.gridMessages.get("selectedItemsMessage").selectedItems + "  "; $('.k-pager-sizes').after(selectedItemsCountElement); //////////////////////////////////End of Footer Customization//////////////////////////////////////////// //////////////////////////////////Start Of DataBound Functions//////////////////////////////////////////// var rowData; var sizeOfSelectedItems = this.selectedItems.length; var finalSelectedItems = []; $.extend(true, finalSelectedItems, this.selectedItems) var counter = 0; for (var _i = 0; _i < finalSelectedItems.length; _i++) { rowData = finalSelectedItems[_i]; var dataItem = generalGrid.dataSource.get(rowData.id), rowTemplate; if (dataItem) { rowTemplate = generalGrid.tbody.find("tr[data-uid='" + dataItem.uid + "']"); var checkBox = $("#checkBox_" + rowData.id); checkBox.prop('checked', true); rowTemplate.addClass("k-state-selected"); rowTemplate.css("background-color", "#F6F2F1"); rowTemplate.css("color", "black"); } else { this.selectedItems.splice(_i - counter, 1); counter++; } } this.selectedItemsCount = this.selectedItems.length; $("#selected-item-count-btn").text(this.selectedItems.length); //////////////////////////////////End of DataBound Functions//////////////////////////////////////////// //////////////////////////////////Start Of Select All//////////////////////////////////////////// var checkall = $("#selectAllCheckbox"); checkall.unbind("click"); checkall.on('click', (e) => { this.selectedItemsCount = 0; var allRows = $(".k-grid-content").find('.rowCheckbox'), selectAllChecked = $(e.currentTarget).is(':checked'); var component = this; this.selectedItems = []; allRows.each((index, elem) => { $(allRows).prop('checked', selectAllChecked).change(); if (selectAllChecked) { this.selectRow($(elem), component); } else { this.deselectRow($(elem), component); } }); }); //////////////////////////////////End of Select All//////////////////////////////////////////// //////////////////////////////////Start Of Select Row//////////////////////////////////////////// var checkRow = $(".rowCheckbox"); //checkRow.prop('checked', false).change(); checkRow.on('click', (e) => { var rowChecked = $(e.currentTarget).is(':checked'); if (rowChecked) { this.selectRow($(e.currentTarget), this); } else { this.deselectRow($(e.currentTarget), this); } }); //////////////////////////////////End of Select Row//////////////////////////////////////////// //////////////////////////////////Start Of Filtering and Grouping//////////////////////////////////////////// let grid; setTimeout(() => { grid = this.gridRef.ProtoType; }) var kendoFilterButton = $("#kendoFilterButton"); var kendoRefreshButton = $("#kendoRefreshButton"); var kendoGroupingButton = $("#kendoGroupingButton"); kendoFilterButton.unbind("click"); kendoRefreshButton.unbind("click"); kendoGroupingButton.unbind("click"); //get filter options messages var filterOperators = this.gridMessages.get("filterOperators"); var filterMenuMessages = this.gridMessages.get("filterMenuMessages"); kendoFilterButton.click(function () { var filterSettings = grid.getOptions().filterable; /** * in case of filter enabled ( opened ) get options messgaes from grid messgae map * to prevent go back to default language */ if (filterSettings) { grid.setOptions({ filterable: false }); } else { grid.setOptions({ filterable: { operators: filterOperators, messages: filterMenuMessages, mode: 'row' } }); } }); kendoRefreshButton.on('click', () => { this.refreshDataSourceGrid(grid, this.optionsAdded.objectRemoteRestUrl); }); //get grouping messages var groupingMessages = this.gridMessages.get("groupingMessages"); kendoGroupingButton.click(function () { /** * in case of groupable enabled ( opened ) get options messgaes from grid messgae map * to prevent go back to default language */ var isGrouping = grid.getOptions().groupable; grid.setOptions({ groupable: !isGrouping }); if (isGrouping) { grid.setOptions({ groupable: false }); } else { grid.setOptions({ groupable: { messages: groupingMessages } }); } }); if ($("#closeFilterRow").length == 0) { var spanElement = document.createElement("span"); spanElement.setAttribute("class", "k-icon k-i-close"); var closeFilterRowButton = document.createElement("button"); closeFilterRowButton.setAttribute("type", "button"); closeFilterRowButton.setAttribute("class", "k-button transparent-icon"); closeFilterRowButton.setAttribute("id", "closeFilterRow"); closeFilterRowButton.appendChild(spanElement); $("tr[class=k-filter-row] th:last").append(closeFilterRowButton); } var kendoFilterCloseButton = $("#closeFilterRow"); kendoFilterCloseButton.click(function () { grid.setOptions({ filterable: false }); }); setTimeout(function () { if ($("#closeGroupingRow").length == 0) { var spanCloseElement = document.createElement("span"); spanCloseElement.setAttribute("class", "k-icon k-i-close"); var closeGroupingRowButton = document.createElement("button"); closeGroupingRowButton.setAttribute("type", "button"); closeGroupingRowButton.setAttribute("class", "k-button pull-right transparent-icon"); closeGroupingRowButton.setAttribute("id", "closeGroupingRow"); closeGroupingRowButton.appendChild(spanCloseElement); $("div[class=k-grouping-header]").append(closeGroupingRowButton); } var kendoGroupCloseButton = $("#closeGroupingRow"); kendoGroupCloseButton.click(function () { grid.setOptions({ groupable: false }); }); }); this.optionsAdded.onDataBound(); //////////////////////////////////End of Filtering and Grouping//////////////////////////////////////////// //if any class uses general-grid-component and needs to append dataBound functions, implememt onDataBound in this class and call it in ngAfterViewInit. //onDataBound(); }, }; if (this.optionsAdded.detailTemplate && this.optionsAdded.detailInit) { (gridOptions).detailTemplate = kendo.template(this.optionsAdded.detailTemplate); (gridOptions).detailInit = this.optionsAdded.detailInit; } return gridOptions; }; get selectedItems(): any[] { return this._selectedItems; } set selectedItems(selectedItems: any[]) { this._selectedItems = selectedItems; } selectRow(selectedRow, component) { this.selectedItemsCount++; $("#selected-item-count-btn").text(this.selectedItemsCount); var row = selectedRow.closest("tr"); var generalGrid = $('.k-grid').data('kendoGrid'); var selectedItem = generalGrid.dataItem(row); component.selectedItems.push(selectedItem); row.addClass("k-state-selected"); row.css("background-color", "#F6F2F1"); row.css("color", "black"); } deselectRow(deselectedRow, component) { if (this.selectedItemsCount > 0) { this.selectedItemsCount--; } $("#selected-item-count-btn").text(this.selectedItemsCount); var row = deselectedRow.closest("tr"); var generalGrid = $('.k-grid').data('kendoGrid'); var deselectedItem = generalGrid.dataItem(row); for (let index in component.selectedItems) { if (component.selectedItems[index].id == deselectedItem.get('id')) { component.selectedItems.splice(index, 1); break; } } row.removeClass("k-state-selected"); row.css("background-color", "white"); deselectedItem.set("actionFlag", false); } ngOnDestroy() { Mediator.unsubscribe(CoreMediatorChannels.CHANGE_SYSTEM_LANGUAGE, this.systemLangListener); } }