In KendoUI, I have a grid with filters on. I am more interested in knowing all the filters used by user for saving purpose so that next time user comes in, they can be auto-fill. How do I get all the filters used?
Not sure how your code looks but you should be able to get the Grid's datasource object and call the method filter() to get the currently applied datasource filters. Take a look at the example below taken from here:
<script>
var dataSource = new kendo.data.DataSource({
data: [
{ name: "Jane Doe" },
{ name: "John Doe" }
],
filter: { field: "name", operator: "startswith", value: "Jane" }
});
var filter = dataSource.filter();
console.log(filter.logic); // displays "and"
console.log(filter.filters[0]); // displays '{field: "name", operator: "startswith", value: "Jane"}'
</script>
Just to add to the answers above - if you want to do it purely on the front end without even targeting the actual data source - your can use the following...
var myGrid = $("#gridname").data("kendoGrid");
myGrid.dataSource.filter().filters[0];
You can than break this up into different parameters ...
myGrid.dataSource.filter().filters[0].field
myGrid.dataSource.filter().filters[0].operator
myGrid.dataSource.filter().filters[0].value
Hope this helps - cheers
My configuration is MVC with the data being fetched server-side. What I mean is that the grid calls this method to get its data:
public ActionResult Documents_Read([DataSourceRequest] DataSourceRequest request,
int documentType = (int)ApiGlobals.TrxTypes.חשבונית)
What I do is simple:
I capture the request object in a Session variable and then use the session variable whenever I need it. In the following example I use the filter to print only the documents filtered in the grid:
public ActionResult Documents_Read([DataSourceRequest] DataSourceRequest request,
int documentType = (int)ApiGlobals.TrxTypes.חשבונית)
{
Session["DocumentListFilter"] = request;
...
}
public ActionResult PrintListKendo(int documentType)
{
DataSourceRequest request = (DataSourceRequest)Session["DocumentListFilter"];
if (request == null)
{
request = new DataSourceRequest();
}
request.Page = 1;
request.PageSize = int.MaxValue;
IQueryable<Document> data = _db.GetDocuments()
.Where(d => d.TrxTypeId == (int)documentType);
DataSourceResult filteredData = data.ToDataSourceResult<Document, DocumentListSingleDocumentViewModel>(request,
d => ViewModelFactory.Create(d));
//... call the reporting package with the data, etc.
}
You can save the request object (=serialize it, or save it properties) to the database and reload it when the user opens the relevant page and the grid fetched its data,
Related
Using Kendo DropdownList for MVC, trying to identify why the DropdownList will not accept this data.
#(Html.Kendo().DropDownList()
.Name("CompanyList") //The name of the DropDownList is mandatory. It specifies the "id" attribute of the widget.
.DataTextField("Table")
.DataValueField("COM_NAME")
.DataSource(source =>
{
source.Custom() // Read(read =>
.Type("json")
.Transport(transport =>
{
transport.Read("GetallCompanies", "Home");
})
.ServerFiltering(true); //If true, the DataSource will not filter the data on the client.
})
.SelectedIndex(0) //Select the first item.
)
The raw data from the SQL action has this format:
"{\"Table\":[{\"ORG_ID\":265498,\"COMPORGID\":239597,\"COM_NAME\":\"ABC Rentals \"},{\"ORG_ID\":164929,\"COMPORGID\":239698,\"COM_NAME\":\"Asbury Machine Shop \"}]}"
Have referenced the Kendo docs and other SO examples. Put the JSON into a validator tool, says its correctly formatted.
In the page, the drop down has a left curly brace, { as the top item, and when clicking there are dozens of: Undefined.
The DataTextField was called "Table" because of the "Table" in the JSON array, but it was set to COM_NAME. The Controller Method,
[HttpGet]
public JsonResult GetallCompanies()
{
var ddx = CompInfo.GetAllCompanies(); //returns dataset
string thedata = JsonConvert.SerializeObject(ddx);
return Json(thedata, JsonRequestBehavior.AllowGet);
}
I don't think you need to use SerializeObject on ddx aswell as the Json method before returning to the client. Can you try changing GetAllCompanies to:
[HttpGet]
public JsonResult GetallCompanies()
{
var ddx = CompInfo.GetAllCompanies(); //returns dataset
//string thedata = JsonConvert.SerializeObject(ddx);
return Json(ddx);
}
Summary of the Json method:
Creates a Microsoft.AspNetCore.Mvc.JsonResult object that serializes the specified data object to JSON.
Try this:
Server-side: Leave the JsonConvert.SerializeObject line commented out.
Client-side: Add the following to the DropDownList configuration (e.g. after .SelectedIndex(0)):
.Schema(schema => schema.Data("Table"))
I'm using knockout with the mapping plugin so that I can write code like this:
function ContactViewModel() {
//other properties...
this.emails = ko.observableArray();
}
function ContactEmailViewModel() {
//other properties...
this.address = ko.observable();
}
var koContactMap = {
'emails': {
create: function (options) {
return new ContactEmailViewModel(options.data);
}
}
};
var model = new ContactViewModel();
ko.mapping.fromJS([JSON data from web service], koContactMap, model);
In English, I have contacts and emails, and a contact has emails.
This works perfectly, and I can load the contact and have the data and emails populated, and the emails are of type ContactEmailViewModel, as I want.
But the thing I'm confused about is: why does the map create method return a singular email object instead of a collection of email objects. The emails property is a collection, but seems to be populated by returning a single object, and is called multiple times, once for each member.
This correctly populates the emails property. But now I want to change emails from an array to an EmailsList object, so that I can give it methods, and I can't see how to do this, since the create method returns individual emails, not the whole emails property.
For that behaviour you can add ignore on the emails propery and let the mapping plugin serperate map the emails into a standar array that you feed the EmailsList constructor with.
var emailMapping = {
create: function(opt) {
return new Email(opt.data);
}
};
this.emails = new EmailList(ko.mapping.fromJS(arr, emailMapping));
Hmm, you could also extend a custom class with a observableArray I think (havent tested) that ko.mapping will then just add emails to your EmailList like
this.emails = new EmailList(); //This is is a ko.observableArray the mapping plugin will populate it with emails
ko.mapping.fromJS(data, mappingInfo, this);
https://github.com/knockout/knockout/blob/master/src/subscribables/observableArray.js
update: I just confirmed that solution two worked, so I would say thats a good way of doing it
http://jsfiddle.net/xop2go2z/
//stolen from ko source
function setPrototypeOf(obj, proto) {
obj.__proto__ = proto;
return obj;
}
ko.MyList = function(arr) {
var result = ko.observableArray(arr);
return setPrototypeOf(result, ko.MyList.fn);
}
ko.MyList.fn = {
pushMyThingy: function(obj) {
this.push(obj);
}
};
I have the following JavaScript code that gets the Id property (Guid) from every user row in a Kendo UI grid. Now I am wondering how best to compose these Id's and the owner roleId into a JSON object that I can pass to an MVC3 action method. Versus my silly string concat.
$("#command-add-selected").click(function () {
var json = "roleId: '51FC554E-353C-4D55-BE52-1B4BF9D2F17F', users: [";
var avail = $("#availableUsersGrid").data().kendoGrid._data;
for (var i = 0; i < avail.length; i++) {
json += "{ Id: '" + avail[i].Id + "'},";
}
json = json.slice(0, -1);
json += "]";
alert(json);
return false;
});
The action method can be GET or POST and need not return any value (this is another puzzle here, no returned view). All it does is domain updates that are fetched by other ajax code subsequent to the above code.
How can I pass the above type JSON to an action method essentially of void return type?
EDIT: This question answered the minor part of my question nicely, with how to dynamically add items to an array with push.
1.first of all u dont need to create the full json ur self use JSON.Stringify() method to change the javascript object to JSON string.
2.after u have created the JSON string u can GET or POST it to any normal method in any MVC Controller of visibility public.
even if the signature of the action method is like public ActionResult MehodName(string jsonString) u can always return null.
3. u can use built in JavaScriptSerializer class in System.Web.Script.Serialization namespace to deserialize the json string u recieve in the action to create an object with the same propertiese
Edit:-
make a javascript array names users then inside the for loop use .push() function of javascript to insert the objects like this
var users = [];
for(something)
{
var user = {"Id":"YOUR ID VALUE"};
users.push(user)
}
var objectToSerialize = {"roleId":"YOUR ROLE GUID","Users":users};
var jsonString = JSON.stringify(objectToSerialize);
Edit 2:-
so going by your previous comments u dont want that u need to deseralize the whole JSON object. going by your object architecture even if ur action method has a signature like this
public ActionResult GetUsersByRole(Users users)
{
//some code
}
and Users class like this one
class Users
{
public string RoleId{get; set;}
public User[]{get; set;}
}
and User class like this
class User
{
string Id{get; set;}
}
it would automatically bind property with your complex users object
In conjunction with Parv Sharma's solution:
function User(id) { this.Id=id; }
$("#command-add-selected").click(function () {
var avail = $("#availableUsersGrid").data().kendoGrid._data;
var userArray = array();
for (var i = 0; i < avail.length; i++) {
userArray.push(new User(avail[i].Id));
}
var obj = {roleId:'51FC554E-353C-4D55-BE52-1B4BF9D2F17F',users:userArray};
alert(JSON.stringify(obj));
return false;
});
Should just be able to use Url.Action("NameofAction","nameofcontroller", json);
You may have to add an AcceptVerbs attribute to the action method as well, depending on if you want it to be a GET or a POST.
As far as the building part goes, I would suggest not using strings at all. Jsons are objects, not strings, so I would go ahead and build a "users" object with your foreach loop and then throw that object into your json return object.
edit: forgot to mention stringify. Yeah. Use that.
Given the following code how can I select a list item in my view to get the name via an id? I just want to get the name value from the list via a local #id variable that maps to the lists id range.
This really has nothing to do with dropdowns...perhaps selectlist is the wrong container for associative look up dictionaries?
-- Controller
ViewBag.TypeId = new SelectList(db.TypeIds, "TypeId", "Name");
-- View
#* ??? Get the name by a local #id *#
<div>ViewBag.TypeId.SelectItemNameById(#id)</div> #* Bad psuedo code here... *#
I will use Jquery with an ajax call on the onChange of your dropdownlist.
$(document).ready(function () {
$("#MyDrop").change(function () { GetValue("#MyDrop"); });
});
function GetValue(objSource) {
var url = '/Home/Index/GetValue/';
$.getJSON(url, { id: $(objSource).val() }, function (data) {
//with data returned fill your fields
});
});
}
From the controller
public ActionResult GetValue(string id)
{
int intId = 0;
int.TryParse(id, out intId);
var myData = //Get the value from Id
return Json(myData, JsonRequestBehavior.AllowGet);
}
Remeber to use AllowGet if you don't do a Post call from your ajax (like in my example)
UPDATE to reflect the comments
To achive what you need use a Dictionary passed via ViewBag.
Then from your view you access the (Dictionary)ViewBag.MyDictionary.
Or whatever collection you prefer.
I have validated the JSON response from my C# Webmethod, so I don't believe that's the problem.
Am trying to parse the result using simple jQuery $.ajax, but for whatever reason I can't get the method to correctly fire and parse the result, also incidentally can't seem to get the function to fire the result. Are their any limits on the size of the JSON object that can be returned.
I also removed this code from inside a "Site.Master" page because it would always refresh when I hit the simple button. Do tags work correctly with jQuery elements like the button input I'm grabbing from the DOM?
function ajax() {
//var myData = { qtype: "ProductName", query: "xbox" };
var myData = { "request": { qtype: "ProductName", query: "xbox"} };
$.ajax({
type: "POST",
url: "/webservice/WebService.asmx/updateProductsList",
data: {InputData:$.toJSON(myData)},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// var msg = {__type: "Testportal.outputData", id: "li1234", message: "it's work!", myInt:101}
alert("message=" + msg.d.ProductName + ", id=" + msg.d.Brand);
},
error: function (res, status) {
if (status === "error") {
// errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
var errorMessage = $.parseJSON(res.responseText);
alert(errorMessage.Message);
}
}
});
}
And the page:
<asp:Button ID="Button1" runat="server" OnClientClick="ajax();" Text="Button" />
And the Serverside Webmethod:
public class WebService : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData updateProductsList(InputData request)
{
OutputData result = new OutputData();
var db = new App_Data.eCostDataContext();
var q = from c in db.eCosts
select c;
if (!string.IsNullOrEmpty(request.qtype) && !string.IsNullOrEmpty(request.query))
{
q = q.Like(request.qtype, request.query);
}
//q = q.Skip((page - 1) * rp).Take(rp);
result.products = q.ToList();
searchObject search = new searchObject();
foreach (App_Data.eCost product in result.products)
{
/* create new item list */
searchResult elements = new searchResult()
{
id = product.ProductID,
elements = GetPropertyList(product)
};
search.items.Add(elements);
}
return result;
}
And helper classes:
public class OutputData
{
public string id { get; set; }
public List<App_Data.eCost> products { get; set; }
}
public class InputData
{
public string qtype { get; set; }
public string query { get; set; }
}
One problem you may be having is that you aren't doing anything to prevent the button from submitting the form and executing a full postback/reload at the same time you're starting your $.ajax() callback.
I'd suggest wiring this up unobtrusively instead of using the OnClientClick property, like this:
$(document).ready(function() {
// May need to use $('<%= Button1.ClientID %>') if your Button is
// inside a naming container, such as a master page.
$('#Button1').click(function(evt) {
// This stops the form submission.
evt.preventDefault();
$.ajax({
// Your $.ajax() code here.
});
});
});
I also agree with Oleg that you should use json2.js for your JSON stringifying and parsing. In newer browsers, that will fall back to the browsers' native implementations of those methods, which is much faster and makes the parsing safer.
Update:
To answer your question about the data, no that doesn't look quite right.
What you want to ultimately send to the server is this (sans formatting):
{"request":{"gtype":"ProductName","query":"xbox"}}
To accomplish that, you want something like this:
var req = { request : { qtype: "ProductName", query: "xbox" }};
$.ajax({
data: JSON.stringify(req),
// Remaining $.ajax() parameters
});
Keep in mind that request, qtype, and query must match your server-side structure with case-sensitive accuracy.
You can also be more verbose in defining the request object (which I prefer, personally, to keep things clear and readable):
var req = { };
req.request = { };
req.request.qtype = "ProductName";
req.request.query = "xbox";
I've written a bit more about this here, if you're interested: http://encosia.com/2009/04/07/using-complex-types-to-make-calling-services-less-complex/
What does your server side code method look like? Set a break point. Is it even being hit?
It should look something like:
[WebMethod, ScriptMethod]
public string updateProductsList(string qtype, string query)
{ // stuff
}
Also, your javascript data params do not look formatted correctly.
It seems to me that your problem is that you try to use manual JSON serialization. There are more direct way. You should just declare [ScriptMethod (ResponseFormat = ResponseFormat.Json)] or [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] and return return direct an object instead of the string from the web method. On the client side (in JavaScript) I strictly recommend you to use JSON.stringify (from json2.js which can be downloaded from http://www.json.org/js.html) for the constructing of the data parameter of jQuery.ajax.
Look at Can I return JSON from an .asmx Web Service if the ContentType is not JSON? and How do I build a JSON object to send to an AJAX WebService? probably also in JQuery ajax call to httpget webmethod (c#) not working you have have an interest for more experiments.