I have tried a pagination in LWC - lwc

I have tried a pagination to display my accounts. The issue I found with the below code is when i click on 2, the list is iterating and display one more array list. At first, it looks 1 2 3 4 5 when i click on any number it displays as 1 2 3 4 2 3 4 5 and on another click 1 2 3 4 2 3 4 2 3 4 5. Basically, it displays the arraylist one more to the original one.
html:
<template>
<lightning-card title="Pagination on Account">
<div class="slds-var-m-around_medium">
<template if:true={showAccounts}>
<template for:each={showAccounts} for:item="a">
<p key={a.Id}>{a.Name}</p>
</template>
</template>
</div>
<lightning-layout>
<lightning-layout-item padding="around-small" flexibility="auto">
<div class="slds-grid slds-wrap">
<lightning-button icon-name="utility:chevronleft" icon-position="left" onclick={prev}></lightning-button>
<span class="slds-p-horizontal_x-small" title="Display">
<a onclick={processMe} name="1"
class={displayPageNumber}>1</a>
</span>
<template for:each={pageList} for:item="item">
<div key={item.Id}>
<span class="slds-p-horizontal_x-small" title="DisplayMore">
<a onclick={processMe} name={item}
class={displaymore}>{item}</a>
</span>
</div>
</template>
<span class="slds-p-horizontal_x-small" title="Display">
<a onclick={processMe} name={totalPage}
class={displayTotalPage}>{totalPage}</a>
</span>
<lightning-button icon-name="utility:chevronright" icon-position="right" onclick={next}></lightning-button>
</div>
</lightning-layout-item>
</lightning-layout>
</lightning-card>
</template>
.js
import { LightningElement,wire,track } from 'lwc';
import getAccounts from '#salesforce/apex/PaginationonAccounts.getAccounts';
export default class PaginationonAccounts extends LightningElement {
totalAccounts;
currentPageNumber = 1;
showAccounts;
pageSize = 10;
pageList = [];
item;
totalPage = 0;
#wire(getAccounts)
wiredAccounts({data,error}) {
if(data)
{
this.totalAccounts = data;
console.log('Total Accounts',this.totalAccounts);
this.totalPage = Math.ceil(data.length/this.pageSize);
this.currentPageNumber = 1;
this.buildData();
}
}
prev(event)
{
if(this.currentPageNumber > 1)
{
console.log('Previous');
this.currentPageNumber = this.currentPageNumber-1;
this.buildData();
}
}
processMe(event)
{
console.log('Process me');
this.currentPageNumber = parseInt(event.target.name);
console.log('Process me Page Number',this.currentPageNumber);
this.buildData();
}
next(event)
{
if(this.currentPageNumber < this.totalPage)
{
this.currentPageNumber = this.currentPageNumber+1;
this.buildData();
}
}
//to display pageNumbers
get displayPageNumber()
{
if(this.currentPageNumber == 1)
{
return 'selected';
}
else
{
return '';
}
}
//to display more pageNumbers
get displaymore()
{
if(this.currentPageNumber === this.item)
{
return 'selected';
}
else
{
return '';
}
}
//to display totalPage
get displayTotalPage()
{
if(this.currentPageNumber == this.totalPage)
{
return 'selected';
}
else
{
return '';
}
}
buildData()
{
console.log('Build data');
var data = [];
var pageNumber = this.currentPageNumber;
var pageSize = this.pageSize;
var totalAccounts = this.totalAccounts;
var x = (pageNumber-1)*pageSize;
for(; x<=(pageNumber)*pageSize; x++)
{
if(totalAccounts[x])
{
data.push(totalAccounts[x]);
}
}
this.showAccounts = data;
this.generatePageList(pageNumber);
}
generatePageList(pageNumber)
{
pageNumber= parseInt(pageNumber);
console.log('Page Number',pageNumber);
//this.pageList = [];
if(this.totalPage > 1)
{
if(this.totalPage <= 10)
{
var counter = 2;
for(; counter < (this.totalPage); counter++)
{
this.pageList.push(counter);
}
}
else
{
if(pageNumber < 5)
{
this.pageList.push(2,3,4,5,6);
}
else
{
if(pageNumber>(this.totalPage-5)){
this.pageList.push(this.totalPage-5, this.totalPage-4,
this.totalPage-3, this.totalPage-2, this.totalPage-1);
} else{
this.pageList.push(pageNumber-2, pageNumber-1, pageNumber,
pageNumber+1, pageNumber+2);
}
}
}
}
}
}
css
.THIS .selected{
color:orange;
}

Related

MVC app does not show selected values on a form reedition

I am building a Framework7 MVC app and found myself in a dead end alley. I have a form which I need to evaluate. This form contains selects. I am using localStorage to store the form values and everything works OK in that sense, I mean everything is stored correctly. ¿What is the issue? When I fill the form I answer some questions on textareas inputs, select inputs and inputs. everything goes fine until I try to reedit the form, then everything is display correctly on the form, including the score i got from my previous answers, but, the selects appears as if I have never touch them. Their previously selected value is stored but not display on the form. I have found that the issue is caused by the fact that I have set numerical values to the options values but what the form show is "yes" or "no". If I change the option values to "yes" or "no" then the form displays correctly but I need to set "5" or "0" because I need to evaluate the user's answers.
This is my code
The form
<li style="margin-top:-10px;">
<input style="visibility:hidden;height:1px;" value="0" name="choice" onchange="checkTotal()"/>
<input style="visibility:hidden;height:1px;" value="1" type="checkbox" name="choice" onchange="checkTotal()" checked="on">
</li>
<li><div class="item-content">1. ¿Sueles quejarte de sentirte mal?</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<select name="pr1" id="pr1" onchange="checkTotal()">
<option class="item-inner" value="5">No</option>
<option class="item-inner" value="0">Si</option>
</select>
</div>
</div>
</div>
<div class="item-content">En tal caso,</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<textarea class="resizable" id="pr1notes" placeholder="¿cuál es la causa?">{{model.pr1notes}}</textarea>
</div>
</div>
</div>
</li>
The functions on the editController
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
and the model
Protection.prototype.setValues = function(inputValues, extras) {
for (var i = 0, len = inputValues.length; i < len; i++) {
var item = inputValues[i];
if (item.type === 'checkbox') {
this[item.id] = item.checked;
}
else {
this[item.id] = item.value;
}
}
for (var i = 0, len = extras[0].length; i < len; i++) {
var item = extras[0][i];
if((item.id).localeCompare("pr1notes")==0) {this[item.id] = item.value;}
}
console.log('starting loop for extras 3...');
for (var i = 0, len = extras[2].length; i < len; i++) {
var item = extras[2][i];
this[item.name] = item.value;
}
};
Protection.prototype.validate = function() {
var result = true;
if (_.isEmpty(this.prdate)
) {result = false;}
return result;
};
Protection.prototype.getSelectFields = function() {
return ['pr1'];
}
What should I change in order to keep my "5" or "0" values on the select options while the form options still show "yes" or "no" to the user just like this: <select name="pr1" id="pr1" onchange="checkTotal()"><option class="item-inner" value="5">No</option><option class="item-inner" value="0">Si</option></select>?
need anything else to help you understand the issue?
The simplest solution
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].value).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
Just changed this line
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
and changed .label for .value.

AgGrid tree grid does not show identical leaf name items on the same group level

I'm using AgGrid with tree data. https://www.ag-grid.com/javascript-grid-tree-data/
The problem is that I need to have 2 leaf node on the tree with the same name, because they share the name but not it's properties.
I thought this was specified by getRowNodeId GridOption. Example of usage in Option 1: https://www.ag-grid.com/javascript-grid-rxjs/.
But it doesn't.
He is my code of that property:
...
getRowNodeId: (data: any) => any = (data) => {
return (data.parent !== undefined ? data.parent * 1000 : 0) + data.properties.id;
},
...
As you can see, I want to add 2 nodes with the same name but only 1 renders. What can I do?
UPDATE: Code added
My AgGrid component:
import { Component, ViewChild, ElementRef, OnDestroy, Input, Output, EventEmitter } from '#angular/core';
import { Events, ToastController, AlertController } from 'ionic-angular';
import * as _ from 'lodash';
import 'ag-grid-enterprise';
import { Http } from '#angular/http';
import { GridApi, TemplateService, GridOptions, ColDef } from 'ag-grid';
import { TemplateServiceProvider } from '../../providers/services';
import { NgModel } from '#angular/forms';
import { Toast } from '../../classes/classes';
import { EventSubscriber } from '../../classes/eventSubscriber/eventSubscriber';
#Component({
selector: 'page-datatableWithGroups',
templateUrl: 'datatableWithGroups.html'
})
export class DatatableWithGroupsPage extends EventSubscriber implements OnDestroy {
#ViewChild('quickFilterInput') quickFilterInput: ElementRef;
#Input() rowData: any[] = [];
#Input() columnDefs = [];
#Input() title: string;
#Output() onLoadRow: EventEmitter<any> = new EventEmitter();
#Output() onAddRow: EventEmitter<any> = new EventEmitter();
#Output() onDeleteRow: EventEmitter<any> = new EventEmitter();
#Output() onDuplicateRow: EventEmitter<any> = new EventEmitter();
#Output() onSelectedRow: EventEmitter<any> = new EventEmitter();
public gridApi: GridApi;
public gridColumnApi;
public printPending: boolean = true;
public showColumnTools: boolean;
public showColumnVisibilityTools: boolean;
public showFilterTools: boolean = true;
private groupDefaultExpanded;
private hoverNode = null;
private isControlPressed: boolean;
private newGroupsCounter: number = 0;
private autoGroupColumnDef: ColDef = {
rowDrag: true,
headerName: "Group",
width: 250,
suppressMovable: true,
cellRendererParams: {
suppressCount: true,
},
valueFormatter: (params) => {
if (!params.data.properties.checkpointList) return params.value;
return params.value + ' (' + (params.data.subGroups ? params.data.subGroups.length : 0) + ')'
+ '(' + (params.data.properties.checkpointList ? params.data.properties.checkpointList.length : 0) + ') ';
},
cellClassRules: {
"hover-over": (params) => {
return params.node === this.hoverNode;
},
"checkpointGroup-title": (params) => {
return this.isCheckpointGroup(params.node.data);
}
}
};
addRowFunction: () => void;
isCheckpointGroup: (nodeData) => boolean = (nodeData) => {
return nodeData && nodeData.properties.checkpointList;
}
getDataPath: (data: any) => any = (data) => {
return data.properties.orgHierarchy;
};
getRowNodeId: (data: any) => any = (data) => {
return (data.properties.parent !== undefined ? data.properties.parent * 1000 : 0) + data.properties.id + (data.properties.component !== undefined ? data.properties.component.id * 100000 : 0);
}
getRowNodeWithUpdatedId: (data: any) => any = (data) => {
return (data.properties.parentId !== undefined ? data.properties.parentId * 1000 : (data.properties.parent !== undefined ? data.properties.parent * 1000 : 0)) + data.properties.id + (data.properties.component !== undefined ? data.properties.component.id * 100000 : 0);
}
public gridOptions: GridOptions = {
enableFilter: this.showFilterTools,
enableColResize: true,
animateRows: true,
cacheQuickFilter: this.showFilterTools,
treeData: true,
quickFilterText: this.quickFilterInput ? this.quickFilterInput.nativeElement.value : '',
colResizeDefault: 'shift',
groupDefaultExpanded: this.groupDefaultExpanded,
rowSelection: 'single',
rowDeselection: true,
defaultColDef: {
filter: "agTextColumnFilter"
},
// components: this.components,
getDataPath: this.getDataPath,
getRowNodeId: this.getRowNodeId,
autoGroupColumnDef: this.autoGroupColumnDef,
deltaRowDataMode: true,
onModelUpdated: () => {
if (this.gridApi && this.columnDefs) {
this.gridColumnApi.autoSizeColumn('ag-Grid-AutoColumn');
this.adjustColumnsToFitWindow();
}
},
onSelectionChanged: (event) => {
let selectedRows = event.api.getSelectedNodes();
let selectedRow = selectedRows && selectedRows.length > 0 ? selectedRows[0] : undefined;
if (selectedRow && this.isCheckpointGroup(selectedRow.data)) {
this.onSelectedRow.emit(selectedRow);
} else {
this.onSelectedRow.emit(undefined);
}
},
};
constructor(
events: Events,
public http: Http,
public templateService: TemplateServiceProvider,
public toastController: ToastController,
public alertCtrl: AlertController,
) {
super(events, [
{ eventName: 'datatable:updateList', callbackFunction: () => this.onLoadRow.emit() },
{ eventName: 'datatable:resizeTable', callbackFunction: () => this.gridApi.sizeColumnsToFit() }
])
this.groupDefaultExpanded = -1;
}
ngOnInit() {
super.subscribeEvents();
this.subscribeEvents();
}
subscribeEvents() {
this.addRowFunction = () => { this.onAddRow.emit() };
window.onresize = () => this.adjustColumnsToFitWindow();
document.addEventListener('keydown', (evt: any) => {
evt = evt || window.event;
if ((evt.keyCode && evt.keyCode === 17) || (evt.which && evt.which === 17)) this.isControlPressed = !this.isControlPressed;
});
}
updateRowData(rowData) {
this.gridApi.setRowData(rowData);
this.gridApi.clearFocusedCell();
this.reAssignSortProperty();
}
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.adjustColumnsToFitWindow();
if (!this.rowData || this.rowData.length === 0) this.gridApi.hideOverlay()
}
onRowDragMove(event) {
this.setHoverNode(event);
}
onRowDragLeave() {
this.setHoverNode(undefined);
}
setHoverNode(event) {
let overNode = event ? event.overNode : undefined;
if (this.hoverNode === overNode) return;
var rowsToRefresh = [];
if (this.hoverNode) {
rowsToRefresh.push(this.hoverNode);
}
if (overNode) {
rowsToRefresh.push(overNode);
}
this.hoverNode = overNode;
this.refreshRows(rowsToRefresh);
}
refreshRows(rowsToRefresh) {
var params = {
rowNodes: rowsToRefresh,
force: true
};
this.gridApi.refreshCells(params);
}
onRowDragEnd(event) {
let toIndex;
let overNode = event.overNode;
let movingNode = event.node;
let movingData = movingNode.data;
if (overNode === movingNode) return;
if (!overNode) {
if (this.isCheckpointGroup(movingData)) {
overNode = (<any>this.gridApi.getModel()).rootNode;
toIndex = this.rowData.length;
} else {
return;
}
}
let overData = overNode.data;
let fromIndex = this.rowData.indexOf(movingData);
toIndex = toIndex ? toIndex : this.rowData.indexOf(overData) + 1;
let newParentNode = (!overNode.data || this.isCheckpointGroup(overNode.data)) ? overNode : overNode.parent;
if (overData && (overData.properties.parentId === 0 || (!overData.properties.parentId && overData.properties.parent === 0)) && this.isCheckpointGroup(movingData) && this.isControlPressed) {
overNode = (<any>this.gridApi.getModel()).rootNode;
newParentNode = (!overNode.data || this.isCheckpointGroup(overNode.data)) ? overNode : overNode.parent;
} else if (overData && this.isControlPressed) {
newParentNode = overNode.parent;
}
if (toIndex > fromIndex) toIndex--;
let oldParentNode = movingNode.parent;
let newParentPath = (newParentNode.data && this.isCheckpointGroup(newParentNode.data)) ? newParentNode.data.properties.orgHierarchy : [];
let needToChangeParent = !this.arePathsEqual(newParentPath, movingData.properties.orgHierarchy);
if (fromIndex === toIndex && !needToChangeParent) return;
if (this.isInvalidMoveTo(movingNode, newParentNode)) {
new Toast(this.toastController).showToast('Invalid Move');
return;
}
if (needToChangeParent) {
if (this.checkNodeExistsInParent(movingData, newParentNode)) return;
let updatedRows = [];
this.moveToPath(newParentPath, movingNode, updatedRows, oldParentNode.data, newParentNode.data || { properties: { id: 0 } });
this.gridApi.updateRowData({ update: updatedRows });
this.refreshRows(this.rowData);
}
let newStore = this.rowData.slice();
this.moveInArray(newStore, fromIndex, toIndex);
this.gridApi.setRowData(newStore);
this.rowData = newStore;
this.setHoverNode(undefined);
}
checkNodeExistsInParent(newRow, newParentNode) {
let cloneRow = _.cloneDeep(newRow);
cloneRow.properties.parentId = newParentNode && newParentNode.data ? newParentNode.data.properties.id : 0;
if (this.isCheckpointGroup(cloneRow) && this.existsInParent(cloneRow)) {
new Toast(this.toastController).showToast('"' + cloneRow.properties.name + '" already exists on "' + (newParentNode.data ? newParentNode.data.properties.name : 'root') + '"');
return true;
}
return false
}
checkNodeExistsInTemplate(newRow) {
if (!this.isCheckpointGroup(newRow) && this.existsInTemplate(newRow)) {
new Toast(this.toastController).showToast('"' + newRow.properties.name + '" already exists on the template');
return true;
}
return false
}
existsInParent(newRow) {
return this.rowData.find(row => this.getRowNodeWithUpdatedId(row) === this.getRowNodeWithUpdatedId(newRow));
}
existsInTemplate(newRow) {
return this.rowData.find(row => row.properties.id === newRow.properties.id);
}
moveInArray(arr, old_index, new_index) {
if (new_index >= arr.length) {
var k = new_index - arr.length + 1;
while (k--) {
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
};
moveToPath(newParentPath, node, allUpdatedNodes, oldParentData?, newParentData?) {
var newChildPath = this.updateNodePath(node.data, newParentPath);
if (newParentData) this.updateParents(node.data, oldParentData, newParentData);
allUpdatedNodes.push(node.data);
if (oldParentData) allUpdatedNodes.push(oldParentData);
if (newParentData) allUpdatedNodes.push(newParentData);
if (node.childrenAfterGroup) this.moveChildrenPaths(node.childrenAfterGroup, newChildPath, allUpdatedNodes);
}
updateNodePath(nodeData, newParentPath) {
var oldPath = nodeData.properties.orgHierarchy;
var fileName = oldPath[oldPath.length - 1];
var newChildPath = newParentPath.slice();
newChildPath.push(fileName);
nodeData.properties.orgHierarchy = newChildPath;
return newChildPath;
}
updateParents(nodeData, oldParentData, newParentData) {
nodeData.properties.parentId = newParentData.properties.id;
if (this.isCheckpointGroup(nodeData)) {
if (oldParentData) oldParentData.subGroups = oldParentData.subGroups.filter(subGroup => subGroup.properties.id !== nodeData.properties.id);
if (newParentData && newParentData.subGroups !== undefined) newParentData.subGroups.push(nodeData);
} else {
if (oldParentData) oldParentData.properties.checkpointList = oldParentData.properties.checkpointList.filter(checkpoint => checkpoint.properties.id !== nodeData.properties.id);
if (newParentData && newParentData.properties.checkpointList) newParentData.properties.checkpointList.push(nodeData);
}
}
moveChildrenPaths(children, newChildPath, allUpdatedNodes) {
children.forEach((child) => {
this.moveToPath(newChildPath, child, allUpdatedNodes);
});
}
isInvalidMoveTo(selectedNode, targetNode) {
let isInvalid = false;
if (targetNode.parent && targetNode.parent.data) {
isInvalid = this.isInvalidMoveTo(selectedNode, targetNode.parent);
if (this.getRowNodeWithUpdatedId(targetNode.parent.data) === this.getRowNodeWithUpdatedId(selectedNode.data)) isInvalid = true;
}
if (targetNode && targetNode.data && this.getRowNodeWithUpdatedId(targetNode.data) === this.getRowNodeWithUpdatedId(selectedNode.data)) isInvalid = true;
return isInvalid;
}
arePathsEqual(path1, path2) {
let newPathLength = path1.length + 1;
let oldPathLength = path2.length;
if (this.isControlPressed && newPathLength === 2 && oldPathLength === 1) return true;
if (newPathLength !== oldPathLength) return false;
var equal = true;
path1.forEach(function (item, index) {
if (path2[index] !== item) {
equal = false;
}
});
return equal;
}
reAssignSortProperty() {
this.gridApi.forEachNode((node) => {
node.data.properties.sort = node.childIndex + 1
})
};
addRows(data) {
let selectedGroupNode = data.selectedGroup;
let groupIndex = selectedGroupNode ? this.rowData.indexOf(selectedGroupNode.data) + 1 : this.rowData.length;
data.selectedRows.forEach((selectedRow, index) => {
let newRowData = _.cloneDeep(selectedRow.data);
newRowData.orgHierarchy = selectedGroupNode ? _.cloneDeep(selectedGroupNode.data.properties.orgHierarchy) : [];
newRowData.orgHierarchy.push(newRowData.name);
newRowData = { properties: newRowData };
newRowData.properties.parent = selectedGroupNode ? selectedGroupNode.data.properties.id : 0;
if (this.isCheckpointGroup(newRowData)) {
if (!this.checkNodeExistsInParent(newRowData, selectedGroupNode)) {
this.newGroupsCounter--;
newRowData.properties.checkpointGroupId = newRowData.properties.id;
newRowData.properties.id = this.newGroupsCounter;
newRowData.subGroups = [];
if (selectedGroupNode && selectedGroupNode.data) selectedGroupNode.data.subGroups.push(newRowData);
this.rowData.splice(groupIndex + index + (selectedGroupNode ? selectedGroupNode.allChildrenCount : 0), 0, newRowData)
}
} else {
if (!this.checkNodeExistsInTemplate(newRowData)) {
newRowData.properties.templateCheckpointGroupCheckpointId = -1;
if (selectedGroupNode && selectedGroupNode.data) selectedGroupNode.data.properties.checkpointList.push(newRowData);
this.rowData.splice(groupIndex + index + (selectedGroupNode ? selectedGroupNode.allChildrenCount : 0), 0, newRowData)
}
}
});
if (selectedGroupNode) data.selectedGroup.expanded = true;
this.updateRowData(this.rowData);
}
deleteRow(row) {
if (row.properties.checkpointList && row.properties.checkpointList.length > 0) {
row.properties.checkpointList.forEach(checkpoint => {
this.deleteRow(checkpoint);
});
}
if (row.subGroups && row.subGroups.length > 0) {
row.subGroups.forEach(subGroup => {
this.deleteRow(subGroup);
});
}
this.deleteByUpdatedParentId(row);
this.updateRowData(this.rowData);
}
deleteByUpdatedParentId(row) {
this.rowData = this.rowData.filter(existingRow => this.getRowNodeWithUpdatedId(existingRow) !== this.getRowNodeWithUpdatedId(row));
}
adjustColumnsToFitWindow() {
if (this.gridApi) this.gridApi.sizeColumnsToFit();
}
onFilterTextBoxChanged() {
this.gridApi.setQuickFilter(this.quickFilterInput.nativeElement.value);
}
exportCsv() {
let params = {
fileName: 'Rows',
sheetName: 'Rows',
columnSeparator: ';'
};
this.gridApi.exportDataAsCsv(params);
}
print() {
this.setPrinterFriendly();
this.printPending = true;
// if (this.gridApi.isAnimationFrameQueueEmpty()) {
this.onAnimationQueueEmpty({ api: this.gridApi });
// }
}
onAnimationQueueEmpty(event) {
if (this.printPending) {
this.printPending = false;
this.printTable();
}
}
printTable() {
// let rest = <any>document.querySelector("ion-content :not(#grid)");
// rest.style.display = 'none';
print();
}
setPrinterFriendly() {
let eGridDiv = <any>document.getElementById("grid");
let preferredWidth = this.gridApi.getPreferredWidth();
preferredWidth += 2;
eGridDiv.style.width = preferredWidth + "px";
eGridDiv.style.height = "";
this.gridApi.setGridAutoHeight(true);
}
}
The html:
<ion-content padding>
<ion-item class="generic-tools-wrapper">
<div>
<input type="text" #quickFilterInput placeholder="Filter..." (input)="onFilterTextBoxChanged()" />
<button ion-button small type="button" icon-only (click)="exportCsv()">
<ion-icon name="list-box"></ion-icon>
</button>
<button ion-button small type="button" icon-only (click)="print()">
<ion-icon name="print"></ion-icon>
</button>
<button ion-button small [color]="isControlPressed ? 'danger': 'primary'" type="button" icon-only (click)="isControlPressed = !isControlPressed">
<ion-icon name="return-right"></ion-icon>
</button>
</div>
</ion-item>
<ion-label> <strong>Attention!</strong> The grouping option is <strong>{{isControlPressed ? 'deactivated':
'activated'}}</strong>,
elements
dragged over a group will be put <strong>{{isControlPressed ? 'next to': 'inside'}} that group</strong>. Press
<strong>Control</strong> to switch this option. </ion-label>
<div style="height: 90%;box-sizing: border-box; ">
<ag-grid-angular id="grid" style="width: 100%; height: 100%;" class="ag-theme-material" [rowData]="rowData"
[columnDefs]="columnDefs" [gridOptions]="gridOptions" (gridReady)="onGridReady($event)" (rowDragMove)="onRowDragMove($event)"
(rowDragEnd)="onRowDragEnd($event)" (rowDragLeave)="onRowDragLeave($event)" (viewportChanged)="adjustColumnsToFitWindow()">
</ag-grid-angular>
</div>
</ion-content>

Extending Dynamic-forms from angular2 cookbook to be able to have arrays

I have tried to extend the Dynamic-Forms app from angular 2 cookbook so I can have an array of multiple fields. I have been able to show the fields, but when I'm filling the form, I'm getting just the last element of the array filled.
Hier is my plunker with that state of the app:
//question-array.ts
import { QuestionBase } from './question-base';
export class ArrayQuestion extends QuestionBase<string> {
controlType = 'array';
options:{childe:FormElement<string>}[] = [];
constructor(options:{} = {}){
super(options);
this.options = options['options'] || [];
}
}
//question-control.service.ts
...
toFormGroup(formelements: QuestionBase<any>[] ) {
let group:any = {};
formelements.forEach(element => {
console.log("+element",element);
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = new FormControl(e.value || '');
});
arr.push(new FormGroup(locobj))
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
//dynamic-form-question.component.html
...
<div *ngSwitchCase="'array'" [formArrayName]="question.key">
<div *ngFor="let item of question.options; let i=index" [formGroupName]="i" >
<div *ngFor="let element of item.element">
<div *ngIf="element.controlType === 'textbox'" >
<label>{{element.label}}</label>
<input [formControlName]="element.key" [id]="element.key" [type]="element.type" />
</div>
<div *ngIf="element.controlType === 'dropdown'" >
<label>{{item.label}}</label>
<select [id]="element.key" [formControlName]="element.key">
<option *ngFor="let opt of element.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
</div>
</div>
</div>
...
http://plnkr.co/edit/DZ05fO
Best regard,
Shefki
I found the bug, the problem was that I was passing the same reference in the form group her is what i changed:
//question-control.service.ts
toFormGroup(formelements: QuestionBase[] ) {
let group:any = {};
formelements.forEach(element => {
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = e.value || '';
});
arr.push(new FormGroup(this.getFormControlObject(locobj)));
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
private getFormControlObject(keys){
let retobj = {};
Object.keys(keys).forEach(function(key) {
retobj[key] = new FormControl(keys[key]);
});
return retobj;
}
Hier is a working plunker
http://plnkr.co/edit/4IMKdLKE51n41jzYY8sU

Cant see why this JavaScript-code won't run

I'm new to JavaScript and have written this code. It worked before, but now it just don't, and I don't understand why. The text on the button doesn't even change to "PAUSE". When I try it in the browser it says after a while that "localhost is not responding due to a long-running script."
<div>
<div id="tabataBox">
<p id="PauseGoText"></p>
<p id="stopwatch">CLICK TO START WORKOUT</p>
<button id="tabataButton" onclick="startPause()">START</button>
</div>
<span class="circle" id="el-1"></span>
<span class="circle" id="el-2"></span>
<span class="circle" id="el-2"></span>
<span class="circle" id="el-3"></span>
<span class="circle" id="el-4"></span>
<span class="circle" id="el-5"></span>
<span class="circle" id="el-6"></span>
<span class="circle" id="el-7"></span>
<span class="circle" id="el-8"></span>
</div>
</div>
var time = 0;
var running = 0;
var everySecond = true;
var max = 20;
var numberOfTimes = 1;
function startPause() {
if (running == 0) {
running = 1;
document.getElementById("tabataButton").innerHTML = "PAUSE";
increment();
}
else {
running = 0;
document.getElementById("tabataButton").innerHTML = "START";
}
}
function reset() {
time = 1;
document.getElementById("stopwatch").innerHTML = "0";
if (everySecond == true)
{
everySecond = false;
max = 20;
document.getElementById("tabataBox").style.backgroundColor = "green";
document.getElementById('el-'+numberOfTimes).style.backgroundColor = "green";
numberOfTimes++;
document.getElementById("PauseGoText").innerHTML = "REST";
}
else {
everySecond = true;
max = 10;
document.getElementById("tabataBox").style.backgroundColor = "red";
document.getElementById("PauseGoText").innerHTML = "GO!";
}
}
function increment() {
if (running == 1) {
setTimeout(function () {
time++;
if (time > max) {
reset();
}
document.getElementById("stopwatch").innerHTML = time;
increment();
}, 1000)
}
}

Select rows with checkbox in SlickGrid

I need to make a column where you can select grid rows with input:checkbox. Grids like ones used by Yahoo, Google etc have something like that.
I made something but I have some problems and I think that is not a good aproach also.
It's posible to have checkboxes in rows and click on them directly, not like in example4-model ?
My idea was :
< div id="inlineFilterPanel" class="slick-header-column" style="padding: 3px 0; color:black;">
<input type="checkbox" name="selectAll" id="selectAll" value="true" / >
< input type="text" id="txtSearch2" value="Desktops" />
</div>
d["check"] = '< INPUT type=checkbox value='true' name='selectedRows[]' id='sel_id_<?php echo $i; ?>' class='editor-checkbox' hideFocus />';
grid.onSelectedRowsChanged = function() {
selectedRowIds = [];
$('#myGrid' + ' :checkbox').attr('checked', '');
var rows = grid.getSelectedRows();
for (var i = 0, l = rows.length; i < l; i++) {
var item = dataView.rows[rows[i]];
if (item) {
selectedRowIds.push(item.id);
$('#sel_' + item.id).attr('checked', 'checked');
}
}
};
function selectAllRows(bool) {
var rows = [];
selectedRowIds = [];
for (var i = 0; i < dataView.rows.length; i++) {
rows.push(i);
if (bool) {
selectedRowIds.push(dataView.rows[i].id);
$('#sel_' + dataView.rows[i].id).attr('checked', 'checked');
} else {
rows = [];
$('#sel_' + dataView.rows[i].id).attr('checked', '');
}
}
grid.setSelectedRows(rows);
}
grid.onKeyDown = function(e) {
// select all rows on ctrl-a
if (e.which != 65 || !e.ctrlKey)
return false;
selectAllRows(true);
return true;
};
$("#selectAll").click(function(e) {
Slick.GlobalEditorLock.cancelCurrentEdit();
if ($('#selectAll').attr('checked'))
selectAllRows(true);
else
selectAllRows(false);
return true;
});
Thanks!
I've added a sample implementation of a checkbox select column to http://mleibman.github.com/SlickGrid/examples/example-checkbox-row-select.html
This is part of the upcoming 2.0 release.