How to make Angular ui grid expand rows initially based on data? - javascript

I am using ui-grid to show a list of data and on display of the grid I am trying to expand some of the rows depending on the data.
I am trying to do this in the onRegisterApi event:
scope.GridOptions = {
data: properties,
columnDefs:
[
{ name: "Full Address", field: "FullAddress" },
{ name: "Suburb", field: "Suburb" },
{ name: "Property Type", field: "PropertyType" },
{ name: "Price", field: "Price", cellFilter: 'currency'},
{ name: "Status", field: "Status" },
{ name: "Sale Type", field: "SaleType" },
{ name: "Date Created", field: "CreateDate", cellFilter: "date:'dd/MM/yyyy HH:mma'"}
],
expandableRowTemplate: 'template.html',
expandableRowHeight: 200,
onRegisterApi: (gridApi) =>
{
gridApi.expandable.expandAllRows();
}
};
The problem is gridApi.expandable.expandAllRows() expands all of the grouped sections. I see there is a expandRow function, but I am not sure how to use it in place of the expandAllRows function. I really would like to expand the group that has the column Status set to a particular value. Can someone help me figure this out?

Here is a way to handle expanding of selective rows. I have created a Plunker link (http://plnkr.co/edit/CSaROQqKxYnkoxm2Tl6b?p=preview) where I am expanding all the even rows. In a similar way, you can iterate over the array and expand the required rows.
Include:
"$timeout" dependency in the controller
To expand first row:
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
var entity = (rows.length && rows[0]) ? rows[0].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
});

May be I am late to answer.
But it may help others.
I have taken the same plunker example as SaiGiridhar posted, but modified
$timeout(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});
to
$scope.$$postDigest(function() {
var rows = $scope.gridApi.grid.rows;
for(var i=0; i < rows.length; i++){
if(i%2 === 0){
var entity = (rows.length && rows[i]) ? rows[i].entity : null;
$scope.gridApi.expandable.toggleRowExpansion(entity);
}
}
});

Related

How to select all child nodes on selecting parent in kendo TreeList? javascript

I'm trying to select child nodes on parent node clicked. I couldn't find any example for select api. Should i use checkbox instead?
<button id="btn">Highlight third row</button>
<div id="treeList"></div>
<script>
$("#treeList").kendoTreeList({
columns: [
{ field: "id" },
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22, expanded: true },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 }
],
selectable: "multiple row"
});
</script>
I am trying to do that if select "1" (top parent), select 2,3 (child nodes). Hope there is native solution for javascript implementation. Thanks in advice!
The selection state is maintained by TreeList in the data items row rendering<tr k-state-selected>, and that state is not reflected in the TreeList dataSource. Also, the data source is the only place the child relationship is discoverable. So there is a bit of back and forth to deal with selections and children.
Also TreeList does not have a select event like TreeView so out of the box you do not know which nodes were selected or deselected.
The change event fires when one action causes one or more rows (like shift-click can do) are caused to be selected or deselected. Within your change handler you can only know the current state of all selected rows using the select() method.
Thus, within change, you need to track prior selection state and current selection state to find which rows changed selection state, which would merit their children to be selected or deselected according to your requirement.
See this Dojo for an example. It's not perfect because in the change event you can only determine selected nodes and not know if a 'reselection' occurred (i.e. clicked on a selected row again). Anyway, the descent down the hierarchy of the TreeList is performed recursively and relies on the dataSource data item property .hasChildren and dataSource method .childNodes()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TreeList select (change)</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.219/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.219/js/kendo.all.min.js"></script></head>
<body>
<p><a target="_blank" href="https://docs.telerik.com/kendo-ui/api/javascript/ui/treelist">TreeList docs</a></p>
<div id="treeList"></div>
<script>
selected_uids = []; // track selected uids
autoselecting = false;
$("#treeList").kendoTreeList({
columns: [
{ field: "id" },
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ id: 1, parentId: null, name: "Jane Doe", age: 22, expanded: false },
{ id: 2, parentId: 1, name: "John Doe", age: 24 },
{ id: 3, parentId: 1, name: "Jenny Doe", age: 3 },
{ id: 4, parentId: null, name: "Jane Mack", age: 22, expanded: false },
{ id: 5, parentId: 4, name: "John Mack", age: 24 },
{ id: 6, parentId: 4, name: "Jenny Mack", age: 3 }
],
selectable: "multiple row",
change: function(e) {
if (autoselecting) {
e.preventDefault();
return;
}
debugger;
autoselecting = true;
var selected_rows = this.select();
console.log ('desel',selected_rows, selected_uids);
// check for new deselections
for (var index = 0; index < selected_uids.length; index++) {
var selected_uid = selected_uids[index];
if (selected_uid) {
var row = $("tr[data-uid='" + selected_uid + "'].k-state-selected");
if (row.length == 0) {
// no such selected row for one that was previously tracked as selected
deselectChildren(this, selected_uid);
selected_uids[index] = null; // untrack
}
}
}
var selected_rows = this.select();
console.log ('sel',selected_rows,selected_uids);
// check for new selections
for (var index = 0; index < selected_rows.length; index++) {
var data = this.dataItem(selected_rows[index]);
console.log('data',data);
if (jQuery.inArray(data.uid, selected_uids) == -1) {
// new selection
selected_uids.push(data.uid);
selectChildren(this, data);
}
}
for (var i=0, j=0; i < selected_uids.length; i++) {
if (selected_uids[i] != null) {
if (i > j) {
selected_uids[j] = selected_uids[i];
}
j++;
}
}
selected_uids.length = j;
autoselecting = false;
},
});
function selectChildren(treeList, data) {
if (!data.hasChildren) return;
var children = treeList.dataSource.childNodes(data);
for (var index = 0; index < children.length; index++) {
var child = children[index];
if (jQuery.inArray(child.uid, selected_uids) == -1) {
selected_uids.push(child.uid);
treeList.select($("tr[data-uid='" + child.uid + "']"));
selectChildren(treeList,child);
}
}
}
function deselectChildren(treeList, uid) {
var data = treeList.dataSource.getByUid(uid);
if (!(data && data.hasChildren)) return;
var children = treeList.dataSource.childNodes(data);
for (var index = 0; index < children.length; index++) {
var child = children[index];
var row = $("tr[data-uid='" + child.uid + "'].k-state-selected");
if (row.length == 1) {
var at = selected_uids.indexOf(child.uid);
if (at >= 0) selected_uids[at] = null;
row.removeClass('k-state-selected');
}
deselectChildren(treeList,child.uid);
}
}
$("#treeList").data("kendoTreeList").select($("#treeList tbody>tr:nth(0)"));
</script>
</body>
</html>

delete array field in a mongodb database

I am using mongoDB and my JSON (table name is "student") looks like
[{
name : "John",
subjects:["English", "Maths"]
},
{
name : "Winsel",
subjects : ["Maths"]
}]
here "subjects" is some other table and associated with student, I able to get data by using find query,
student.find({}).populate('subjects').then(function(studentData){console.log(studentData)})
by using this query i can get Data as
[{
name : "John",
subjects:["English", "Maths"]
},
{
name : "Winsel",
subjects : ["Maths"]
}]
after that i need to delete the field "subjects" which length is less than 2, I am using
if(studentData.subjects.length < 2){
delete studentData.subjects
}
but it doesn't delete the field, it shows the same result when i not using the if condition.
my expected JSON is
[{
name : "John",
subjects:["English", "Maths"]
},
{
name : "Winsel"
}]
Can any one guide me, Thanks in advance
Try this
var studentsList = [{
name : "John",
subjects:["English", "Maths"]
},
{
name : "Winsel",
subjects : ["Maths"]
}];
var newStudentList = _.map(studentsList , function(eachStudentData){
if(eachStudentData.subjects <2){
return _.pick(eachStudentData, 'name');
} else {
return eachStudentData;
}
});
You can use the newly formed students list newStudentList for your code
To remove the fields in your json response, you can use delete inside the callback function of your query function.
student.find({}).populate('subjects').then(function(studentData){
var newData = studentData;
newData.map(item => {
if(item.subjects.length < 2) {
delete item.subjects;
}
return item;
})
// you can use the newData here;
})
This works to me. I don't know if you are working with a JSON object and you need to transform it to javascript object (students.toObject()).
var students = studentsJSON.toObject();
var newStudents = students.map(studentData => {
if(studentData.subjects.length < 2) {
delete studentData.subjects;
}
return studentData;
});
try this code
var data = [{
name: "John",
subjects: ["English", "Maths"]
},
{
name: "Winsel",
subjects: ["Maths"]
}
];
console.log(data);
for (var i = 0; i < data.length; i++) {
if (data[i].subjects.length < 2) {
delete data[i].subjects;
}
}
console.log(data);
I don't know what are you trying to achieve here but populate works on application level . you can directly use aggregation pipeline for this using $project(or similar $addFields) and $lookup
db.students.aggregate(
[
{
$addFields: {
subjects:{
$cond:[{$gte:[{$size:"$subjects"},2]},"$subjects",null]
}
}
},
{
$lookup: {
"from" : "subjects",
"localField" : "subjects",
"foreignField" : "name",
"as" : "subjects"
}
},
]
);
from mongodb 3.6 you can use "$$REMOVE" instead of null in addFields stage
and also after $lookup you can use $project again to remove empty array

How to map model to table when the structure is array based?

I have my data as following:
{
meta: {
format: "csv",
info: "desc",
columns: [
{
id: "Name",
type: "Text",
length: 32
},
{
id: "Text",
type: "Text",
length: 128
}]
},
rows: [
["John","xxxx"],
["Alpha","yyyy"],
["Beta","wwww"],
["Gamma","zzzz"]]
}
Now, I am struggling to map the records to a Table control as Columns and Rows. Column seems straight forward, straight map, but the rows since lacks a mapping to column I wonder what could be the simplest way.
Approach Steps:
Make a keys[] from column.id of each columns record.
Traverse the rows[]
Each loop, while keys.length create an object as {keys[j]:row[k]}
Push to an array
Recreate the original JSON but replace Rows arrays with Objects
I am really struggling to translate this into code specially at the rows[] parsing and creating Objects. Is there, I am sure there must be, an efficient way to achieve this.
Here is what you could do. using Array.map and forEach.
var input = {
meta: {
format: "csv",
info: "desc",
columns: [{
id: "Name",
type: "Text",
length: 32
}, {
id: "Text",
type: "Text",
length: 128
}]
},
rows: [
["John", "xxxx"],
["Alpha", "yyyy"],
["Beta", "wwww"],
["Gamma", "zzzz"]
]
};
var columns = input.meta.columns.map((column) => {
return column.id
});
var rows = input.rows.map((row) => {
var obj = {};
row.forEach((column, idx) => {
obj[columns[idx]] = column;
});
return obj;
});
input.rows = rows;
console.log(input);

KendoUI grouped filters

I'm trying to make grouped filters for KendoUI grid. I have to create a text field that filters the grid by name and a kendo numeric field that filters grid by Units in stock.
How could I make grouped filters?
I tried the following but it's not working - bad request 404 error:
$('body').bind('keyup mouseup', '#UnitsInStock', function () {
var value = $('#UnitsInStock').val();
var val = $('#ProductName').val();
if (value) {
grid.data("kendoGrid").dataSource.filter(myFilters(val, value));
} else {
grid.data("kendoGrid").dataSource.filter();
}
});
function myFilters(name='', price='') {
var filters = {
logic: "or",
filters: [
{ field: "ProductName", operator: "startswith", value: name},
{ field: "UnitsInStock", operator: "gte", value: price}
]
}
return filters;
}
<div id="grid"></div>
<script type="text/x-kendo-template" id="template">
<div class="toolbar">
<label for="category">Search by Product Name:</label>
<input type="search" id="ProductName" />
<input id="UnitsInStock" type="number" />
</div>
</script>
Since you have fields to be filtered on of multiple types, make sure the types are preserved when creating the filter object. for example, you could predefined your filter fields as such..
var filterFields = [{ field: "Units", type: "number" }, { field: "Name", type: "string" }]
and get the user input
var searchString = // user input
and a method to generate the filters similar to this
var getFilter = function (filterFields, searchString) {
var filterInt = function (value) {
if (/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
return true;
return false;
}
var filters = [];
var i = 0;
for (var i = 0; i < filterFields.length; i++) {
if (filterFields[i].type === "string") {
filters.push({
field: filterFields[i].field,
operator: "startswith",
value: searchString.toString()
});
}
if (filterFields[i].type === "number") {
if (filterInt(searchString)) {
filters.push({
field: filterFields[i].field,
operator: "gte",
value: parseInt(searchString)
});
}
}
}
return {
logic: "or",
filters: filters
};
}
finally, filter your grid
grid.data("kendoGrid").dataSource.filter(getFilter(filterFields, searchString))
also, to be certain that your endpoint works, use a tool such as postman and do a GET (http://............./Units?$filter=Id eq 1 and Name eq 'name').

dynamic columnDef in ng-Grid

I want to assign ng-grid columns name dynamically after value returned from database, but issue is that it get initialized before data return from ajax, and i am not able to recall gridOption so it showing balnk, so please help me that how can we construct a column name by ajax return value.
$scope.gridOptions =
{
data: 'data.Values',
columnDefs:
[
{ field: "ID", displayName: "Record Id" },
{ field: "Value", displayName: $scope.ColumnName, cellFilter: cellfilterType },
],
};
where $scope.ColumnName coming from below line...
RecordService.getRecords().then(function (data) {
$scope.ColumnName= data.something;
}
Thanks
Thanks Max for your help, I have done this with of help columnDef as below:
Step 1:
$scope.colDef = [];
Step 2:
RecordService.getRecords().then(function (data){
$scope.colDef=["ColumnName":data.something]
}
Step 3:
$scope.gridOptions = {
data: 'data.UdiValues',
columnDefs:'colDef',
filterOptions: $scope.filterOptions
};
Try to set first "default" value and after change it with promise
$scope.gridOptions =
{
data: 'data.Values',
columnDefs:
[
{
field: "ID",
displayName: "Record Id"
},
{ field: "Value",
displayName: "default",
cellFilter: cellfilterType
},
]
};
And now:
RecordService.getRecords().then(function (data) {
$scope.gridOptions.columnDefs[1].displayName = data.something;
}
The Service RecordService returns promise therefore we create promise factory like:
.factory('RecordService', ['$resource','$q', function($resource, $q) {
var data = { something: "from service" } ;
var factory = {
getRecords: function (selectedSubject) {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
}]);
Demo Fiddle
Something like this
Return json, play around, use GET mapping to strings etc?
i have done something like this :-
self.gridOptions.columnDefs = columnDefs(colDef,displayNames);
columnDef is :-
var columnDefs = function(data,cd){
var colDef= [];
var mi = null;
var colByOrder = sortedByOrder(data);
for(var i=0 ; i < colByOrder.length ; i++){
colDef.push({
width: width,
field: String(colByOrder[i][1].position),
menuItems: menuItems(this),
displayName: cd[colByOrder[i][1].position],
enableSorting: false,
type: 'string',
});
}
return colDef;
};

Categories

Resources