We are finaly migrating from Telerik MVC Extensions to Kendo and I am having a problem trying to apply a static pre filter to a kendo grid.
I am trying to filter out the rows that contain the word "Archived" in the status column.
How do I do this using Kendo?
Below is the Telerik MVC extensions method that I am trying to convert
#(Html.Telerik().Grid<MyViewModel>()
.Columns(columns =>
{
columns.Bound(m => m.Id);
columns.Bound(m => m.Status);
...
})
.DataBinding(......)
.Filterable(filtering => filtering.Filters(filters =>
{
filters.Add(m => m.Status).IsNotEqualTo("Archived");
}))
)
Here is one way of doing it from the clientside after getting back the initial dataSource demo showing client side filtering
With this example which is the the javaScript version we leverage the DataBound event and when the grid is rebound to the dataSource we run this function:
function onDataBound(e){
var grid = $('#grid').data('kendoGrid');
if(initialFilter)
{
grid.dataSource.filter( { field: "ShipName",
operator: "contains",
value: "Han" });
initialFilter = false;
}
}
initialFilter is a global variable which is a bool that will allow us to control this function and run it once. Otherwise this will keep going in a loop.
then applying the filter to the dataSource we have three parts to it.
{{fieldName},{operator},{value}}
So in this example I am looking at the ShipName, filtering where the value Han is contained in the shipName.
to attach this via the mvc version just add it to the events option
i.e.
.Events(event => event.DataBound("onDataBound"))
another way of doing this is to apply the filter during initialization of the grid and that way the data is filtered without having to go through the issues presented by the first version. filter at initialization
With this version I am merely changing the dataSource and applying the same filter as part of the dataSource setup like so:
dataSource: {
type: "odata",
transport: {
read: "//demos.telerik.com/kendo-ui/service/Northwind.svc/Orders"
},
schema: {
model: {
fields: {
OrderID: {
type: "number"
},
Freight: {
type: "number"
},
ShipName: {
type: "string"
},
OrderDate: {
type: "date"
},
ShipCity: {
type: "string"
}
}
}
},
pageSize: 20,
serverPaging: true,
serverFiltering: true,
filter: {
field: "ShipName",
operator: "contains",
value: "Han"
}
},
So in your datasource configuration you would add something like this:
.Read(read => read.Action("",""))
.Model(model => {model.Id("ShipId");})
.Filter(filter =>
{
filter.Add(f => f.ShipName).Contains("Han");
})
Hopefully this gives you a good starting point but if you need any more info let me know and I will expand the answer for you.
Related
I have used ng2-smart table in my angular 6 app. One of its columns has to display access_type, I'm getting it from source using valuePrepareFunction. Example. access_id=1,access_type=Type1. So when listing this data in table it is showing access_type correctly but when I'm editing that row using the edit button ng2-smart table provides it is showing access_id and not access_type. Do I need to make any changes to display the same data in edit mode as a display list? Following is my code for that column-
access_id: {
title: 'Access Type',
editable: false,
filter: {
type: 'list',
config: {
list: [],
},
},
valuePrepareFunction: (cell, row) => {
return row.access_type;
},
}
Thanks in advance.
Yes, you need a separate list for editor as you do for filtering.
If you use a dropdown box to edit, that would be ideal as it can use the access_type as the title, and the access_id as the value.
I can only assume this will help you based upon guesses of what your data structure looks like. Can you give me a sample of what one of the array items looks like? Do we have a nested object?
Here is a little code to help:
type: {
title: 'Type',
valuePrepareFunction: type => {
return type.abbr;
},
filter: {
type: 'list',
config: {
selectText: 'ALL',
list: this.typeList
}
},
editor: {
type: 'list',
config: {
selectText: 'Select ...',
// list: [{value: 'access_idvalue', title: 'access_type'}]
// use the line above to hard code your list, or the line below
// if you are loading the list dynamically
list: this.typeList
}
},
filterFunction(type?: any, search?: string): boolean {
if (type._id === search) {
return true;
} else {
return false;
}
}
},
I have 2 applications that use the free version of jqgrid.
The one that works has a Json array as follows;
Notice the value of data is [...]
For the application where the data does not get rendered;
Notice the value of data is NOT [...]. So what do I need to do to the data to get it in the correct format so that it will render?
EDIT
I think the data issue I raised originally was mistaken.
I have a jsFiddle of what I want and it works, see
https://jsfiddle.net/arame/cxh7zh3a/
But my code in my .Net MVC application does not. The grid is displayed with headers, but the data rows are not rendered.
var populateGrid = function (data) {
var grid = $("#grid");
grid.jqGrid({
data: data,
colNames: ["Contract No", "Title", ""],
colModel: [
{ name: "FullContractNo", label: "FullContractNo", width: 80, align: "center" },
{ name: "ContractTitle", label: "ContractTitle", width: 400, searchoptions: { sopt: ["cn"] } },
{ name: "Link", label: "Link", search: false, align: "center" }
],
cmTemplate: { width: 100, autoResizable: true },
rowNum: 20,
pager: "#pager",
shrinkToFit: false,
rownumbers: true,
sortname: "FullContractNo",
viewrecords: true
});
grid.jqGrid("filterToolbar", {
beforeSearch: function () {
return false; // allow filtering
}
}).jqGrid("gridResize");
$("#divLoading").hide();
}
var getGrid = function () {
var url = GetHiddenField("sir-get-selected-contract-list");
var callback = populateGrid;
dataService.getList(url, callback);
}
getGrid();
The code is a little different to the JsFiddle as the data is extracted from a Web API.
The data is correct however, as I put a breakpoint in and check it.
See
I have found the answer! I feel daft posting this, but for some reason I cannot fathom I had an old version of the jqGrid library. I had version 4.7 and the current version is 4.14.
With the right version it is now working.
I'm trying to save an nested object inside a sails.js model.
This is how it looks like:
module.exports = {
schema: true,
attributes: {
label: {
type: 'string',
required: true,
},
consumption: [{
timestamp: {
type: 'string',
required: true,
},
value: {
type: 'float',
required: true,
},
}],
}
};
To include the values inside the array I'm doing the following (inside the controller):
if(!plug.consumption)
plug.consumption = [];
plug.consumption.push({
timestamp: req.param('timestamp'), /* Format: '2016-04-14T16:18:24.972Z' */
value: req.param('value'), /* Format: '6.5' */
});
plug.save(function (err){
if(err){
res.send("Error");
return next(err);
}
});
But when the plug.save is executed, sails breaks and says Error: Unknown rule: 0
I've searched how to store arrays of objects on sails.js but didn't find anything that would work.
Can anyone help?
Thanks
You syntax used in consumption is wrong or at least not documented. Waterline supports attribute types json and array as documented but you can't define a schema for them. To define a schema you have to use a One-to-Many relationship between your model and a consumption model.
I'm using a geojson extracted from naturalearthdata which looks like that :
All I want is to catch the NAME of each feature in order to display them in a grid (live search grid.. BTW is it efficient for 2000 names?)
But I can't access to all the name with root property. I tried to loop into all the features
Ext.define('myApp.store.Places', {
extend: 'Ext.data.Store',
alias: 'store.places',
requires : ['myApp.model.PlacesModel',
'myApp.view.main.MainModel'],
id: 'Places',
model: 'myApp.model.PlacesModel',
autoLoad: true,
proxy: {
type: 'ajax',
url : '/resources/data/coord.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
for(var i = 0; i < data.features.length -1; i++){
names_places.push(data.features[i].properties.NAME);
}
debugger;
return names_places;
},
scope: this
}
}
}
});
But the debugger sent me that result which I don't understand :
Especially when the array looks good :
What is the good way to catch only the NAME? Does the return has to look to a json?
You can use the mapping attribute on the fields array in your model definition to map the correct attribute in the json to a field.
You set the rootProperty to features for the reader.
Then in your fields array something similar to this
fields: [
{ name: 'myCustomField', mapping: 'properties.NAME' }
]
I'm using a kendo ui grid, and I want to bind the columns headers to a json file, instead of specifying it directly in the controller.
I created a function that successfully retrieves the array from the json file, and populate the scope:
function returnColumns(){
$http.get('app/data/headers.json')
.then(function(res){
$scope.myHeaders = res.data;
});
}
returnColumns();
And in the grid's options I'm referring the columns to that variable in the scope:
$scope.options = {
dataSource: {
type: "json",
transport: {
read: "app/data/myData.json"
},
pageSize: 10,
schema : {
data: "mySchema"
}
},
sortable: true,
pageable: true,
resizable: true,
columns:$scope.myHeaders
....
....
But the binding doesn't kick in, the headers are not updated.
Thanks!
Assuming you're only loading the headers once and it's okay to hide the table until the headers load, throw an ng-if="myHeaders" onto the kendo-ui grid element, remove columns from $scope.options and use k-columns on the element instead.
So:
<div kendo-grid k-options="options"></div>
becomes:
<div kendo-grid k-options="options" k-columns="myHeaders" ng-if="myHeaders"></div>