Smart-Table - Select first row displayed (angularjs) - smart-table

Is it possible to automatically select the first row when using smart-table. I have added the class st-selected conditionally using ng-class which highlights the row, but when I then select another row it does not deselect the first row.
I would be grateful of any help.
Thanks

I have just had a similar problem, but wanted to have a specified default selection, I solved the issue with allot of swearing and a directive.
(function(undefined) {
'use strict';
angular
.module('mymodule')
.directive('stDefaultSelection', function() {
return {
require: 'stTable',
restrict: 'A',
scope: {
selection: '=stDefaultSelection',
},
link: function link(scope, element, attrs, controller) {
scope.$watch('selection', function(newValue, oldValue) {
var selectionMode = 'single';
if (angular.isArray(newValue) && newValue.length > 1) {
selectionMode = 'multi';
}
if (angular.isArray(newValue)) {
newValue.forEach(function (row, index, array) {
controller.select(row, selectionMode);
});
} else {
controller.select(newValue, selectionMode);
}
});
}
};
});
})();
Then in your html:
<table st-table="myCtrl.data.records" st-safe-src="myCtrl.data.safeRecords" st-default-selection="myCtrl.defaultRecord">
Once the data has been set then set your default record and that may solve your problem.

You can use $watch operator and $filter operator to do the needful.
//fired when table rows are selected
$scope.$watch('displayedCollection', function (row) {
//get selected row
row.filter(function (r) {
if (r.isSelected) {
$scope.selectedId = r.id;
//getInfo(r.id);
}
else if (!$scope.rowCollection[0].isSelected) {
$scope.rowCollection[0].isSelected = true;
$scope.selectedId = $scope.rowCollection[0].id;
//getInfo($scope.rowCollection[0].id);
}
})
}, true);
This will select the selected row, and if no row is selected, it will by default select the row with index 0. (First Row)
You need to pass to attributes to your smart table:
<tr ng-repeat="row in rowCollection" st-select-row="row" st-select-mode="single">
You can make a css class to highlight the row:
.st-selected {
background-color: #ffd800;
}

Related

kendo pivotgrid Rows and Columns expand is always false

I am trying to save PivotGrid state for future load. I have two problems
1: the expand property of row items is not changed at run time. Test here https://dojo.telerik.com/#Mzand/obIkEdAY : When the user expands an item at runtime the expand property of the returned row by dataSource.rows() is the same as what it was at initialization.
2: I can't find a way to save/load the selected feilds (slices) using the "Fields to Include" menu along side with rows,columns and measures.
I'm working in React but you should be able to do something similar.
This is a bug, to work around it you can listen to expandMember and collapseMember events to manually track the axis and path of expanded rows/columns. see code below.
If you mean the Configurator, just set its dataSource to that of the pivot grid after you create it. See below in createGrid().
Bonus, see the end of createGrid to auto expand the items in the Configurator.
createGrid = () => {
$(`#pivot-grid`).kendoPivotGrid({
dataSource: {
data: data,
schema: schema,
columns: this.state.columns,
rows: this.state.rows,
measures: this.state.measures,
filter: this.state.filter
},
expandMember: this.onExpand,
collapseMember: this.onCollapse
});
let grid = $(`#pivot-grid`).data('kendoPivotGrid');
if (grid) {
if (this.state.expands) {
this.state.expands.forEach(expand => {
if (expand.axis === 'rows') {
grid.dataSource.expandRow(expand.path);
} else {
grid.dataSource.expandColumn(expand.path);
}
});
}
$(`#pivot-config`).kendoPivotConfigurator({
dataSource: grid.dataSource,
filterable: true
});
}
// Expand the items in the configurator fields.
let tree = $('.k-treeview').data('kendoTreeView');
if (tree) {
tree.expand('.k-item');
}
};
onExpand = e => {
this.setState({
expands: [...this.state.expands, {
axis: e.axis,
path: e.path
}]
});
};
onCollapse = e => {
this.setState({
expands: this.state.expands.filter(ex => ex.axis !== e.axis && JSON.stringify(ex.path) !== JSON.stringify(e.path))
});
};
Here is my try on this
what i like is, that it actually updates the data source as you would expect
function onExpandOrCollapseMember(e, expand) {
var pivot = e.sender;
var axisToUpdate = '_' + e.axis;
var field = _.find(pivot.dataSource[axisToUpdate], f => JSON.stringify(f.name) === JSON.stringify(e.path));
field.expand = expand;
}
And on the pivot options i pass in
expandMember: e => onExpandOrCollapseMember(e,true),
collapseMember: e => onExpandOrCollapseMember(e, false),

Kendo Grid filter using checkboxes and mutliple selections

I am using custom multi-select code to filter a column. Currently I can get it to filter based on one selection, but am unable to filter based on multiple values. I need the logic to read, if any of the selected checkboxes are checked, then show the selections in the grid. The way I have it written right now, its filtering each one, but if one of the selections is false, it deletes it from the grid even if one of the other selections are true.
var filter = dataSource.filter() || { logic: "or", filters: [] };
var fieldFilters = $.map(element.find(":checkbox:checked"), function (input) {
return {
field: field,
operator: "eq",
value: input.value
};
});
if (fieldFilters.length) {
removeFiltersForField(filter, field);
filter.filters.push({
logic: "or",
filters: fieldFilters
});
var filterType = filter.filters[0].filters;
if (filter.filters[0].filters.length > 1) {
var filterLogic = { logic: "or", filters: filter.filters };
dataSource.filter(filterLogic.filters[0]);
} else {
dataSource.filter(filterType); // This works, but its only one selection
}
}
I need it to return if any selections are true and ignore the ones that are false. Currently, it goes in order, so if the first selection is true, it shows it in the grid, but if the next one is false, then it removes it from the grid.
OK I was able to make it work doing this. If someone has a more efficient way to do it, add it here. For now, this works:
var multipleFilters = [];
if (filterType.length > 1) {
$(filterType).each(function (i, value) {
var simpleFilter = { field: value.field, operator: value.operator, value: value.value };
multipleFilters.push(simpleFilter);
})
if (multipleFilters == 2) {
dataSource.filter(multipleFilters[0] || multipleFilters[1]);
} else if (multipleFilters == 3) {
dataSource.filter(multipleFilters[0] || multipleFilters[1] || multipleFilters[2]);
} else {
dataSource.filter(multipleFilters[1] || multipleFilters[2] || multipleFilters[3]);
}
} else {
dataSource.filter(filterType);
}

is there a way to auto adjust widths in ng-grid?

I'm having trouble with widths of my columns. I don't know what width they will be beforehand, nor do I want to specify each column's width. Is there an attribute that I can use that auto adjusts all the column widths based on the content (including the column header)?
Woot! I came up with a pretty cool answer! Setting the width to "auto" was really not working for me. Maybe it is because I'm using an ng-view? Not sure. So I created 2 new functions you can put in your controller.js. Using them like this will give you computed column widths! Read the code comments; there are some caveats.
Example usage, controllers.js:
var colDefs = makeColDefs(rows[0]);
colDefs = autoColWidth(colDefs, rows[0]);
$scope.phones = rows;
$scope.gridOptions = {
data : 'phones',
showFilter : true,
enableColumnResize : true,
columnDefs : colDefs
};
The code, controllers.js:
/**
* Create a colDefs array for use with ng-grid "gridOptions". Pass in an object
* which is a single row of your data!
*/
function makeColDefs(row) {
var colDefs = [];
for ( var colName in row) {
colDefs.push({
'field' : colName
});
}
return colDefs;
}
/**
* Return a colDefs array for use with ng-grid "gridOptions". Work around for
* "auto" width not working in ng-grid. colDefs array will have percentage
* widths added. Pass in an object which is a single row of your data! This
* function does not do typeface width! Use a fixed width font. Pass in an
* existing colDefs array and widths will be added!
*/
function autoColWidth(colDefs, row) {
var totalChars = 0;
for ( var colName in row) {
// Convert numbers to strings here so length will work.
totalChars += (new String(row[colName])).length;
}
colDefs.forEach(function(colDef) {
var numChars = (new String(row[colDef.field])).length;
colDef.width = (numChars / totalChars * 100) + "%";
});
return colDefs;
}
Jasmine test, controllerSpec.js:
'use strict';
var ROW = {
'col1' : 'a',
'col2' : 2,
'col3' : 'cat'
};
var COLUMN_DEF = [ {
field : 'col1'
}, {
field : 'col2'
}, {
field : 'col3'
} ];
var COLUMN_DEF2 = [ {
field : 'col1',
width : '20%'
}, {
field : 'col2',
width : '20%'
}, {
field : 'col3',
width : '60%'
} ];
/* jasmine specs for controllers go here */
describe('controllers', function() {
beforeEach(module('myApp.controllers'));
it('should make an ng-grid columnDef array from a row of data.',
function() {
expect(makeColDefs(ROW)).toEqual(COLUMN_DEF);
});
it('should return an ng-grid columnDef array with widths!', function() {
var colDefs = makeColDefs(ROW);
expect(autoColWidth(colDefs, ROW)).toEqual(COLUMN_DEF2);
});
});
Use ui-grid, is must better: http://ui-grid.info/docs/#/tutorial/204_column_resizing
but https://github.com/angular-ui/ng-grid/wiki/Configuration-Options
This works:
$scope.gridOptions = {
init: function (gridCtrl, gridScope) {
gridScope.$on('ngGridEventData', function () {
$timeout(function () {
angular.forEach(gridScope.columns, function (col) {
gridCtrl.resizeOnData(col);
});
});
});
},
data: 'scopeDataField',
columnDefs: [
{
field: 'property1',
displayName: 'property1title',
width: '100px' // a random fixed size, doesn't work without this
},
{
field: 'property2',
displayName: 'property2title',
width: '100px'
}
],
enableColumnResize : true
};
See answer at https://stackoverflow.com/a/32605748/1688306
Column width calculated by column name or datum, whichever is longer.
Yes! In your columndefs you can set the width to auto and this will automatically size the columns based on the width of the data and/or header.
Reference: Defining Columns
I am using ui-grid. The following code is working for me. You can try this.
First you need to add a module dependency 'ui.grid.autoResize' in your main module.
Then add css class something like this
.grid {
width : 400px !important;
max-width : 400px !important;
height : 600px !important;
}
And finally add the ui-grid directive in your html file like this. Keep in mind don't forgot to add the 'ui-grid-auto-resize' in your grid directive.
<div id="grid1" ui-grid="gridOptions" class="grid" ui-grid-auto-resize></div>

In kendo ui How to Collapsing Graph could expand table but expanding graph then bring both the graph and table to be visible too

collapsing Graph could expand table but expanding graph immediately shall bring both the graph and table to be visible too,Vice versa.
You need to implement a collapse and expand function handlers.
$("#panelbar").kendoPanelBar({
expandMode: "single",
expand: function (e) {
...
},
collapse: function (e) {
...
}
});
On these handlers you check which item is being collapsed (or expanded) and decide which ones to expand and collapse according to your algorithm.
For knowing which item is being collapse / expanded you should use inside the handler:
var itemId = $("span", e.item).attr("id");
The very last thing is remember that if you want more than one bars opened you should switch you expandMode to multiple.
EDIT: As first approach to what you need:
$("#panelbar").kendoPanelBar({
expandMode: "multiple",
expand : function (e) {
var itemId = $("span", e.item).attr("id");
if (itemId === "Span1") {
this.expand($("#Span2").closest("li"));
} else {
this.collapse($("Span1").closest("li"));
}
},
collapse : function (e) {
var itemId = $("span", e.item).attr("id");
if (itemId === "Span1") {
this.expand($("#Span2").closest("li"));
} else {
this.collapse($("Span1").closest("li"));
}
}
});

How to default p element to "Normal" style in CKEditor

If I add a paragraph style to the CKEdtior
eg:
format_p: { element : 'p', attributes : { 'style' : 'FONT-SIZE:16px;color:#000000;FONT-STYLE:normal;FONT-FAMILY:Arial, Helvetica, sans-serif;font-weight:normal;' } }
The default style when pressing the enter key is blank. However, if I set the style to "Normal" the style is applied and subsequent p's created by clicking the enter key include the style above.
What I want is for all paragraphs (tag 'p') to use the "Normal" style by default. Is there a way to achieve this?
I think you have use 'contentsCss', have you try 'dataProcessor' like this :
CKEDITOR.on('pluginsLoaded', function (event) {
event.editor.dataProcessor.dataFilter.addRules({
elements: {
p: function (element) {
// element.attributes
}
}
});
event.editor.dataProcessor.htmlFilter.addRules ({
elements: {
p: function (element) {
// element.attributes ...
}
}
});
});

Resources