How to display indirect data in Jqgrid
Asked Answered
H

2

7

I am implementing Jqgrid in my ASP.net MVC web application. I have data some thing like this:

 SID SNAME CITY
  1   ABC   11
  2   XYZ   12
  3   ACX   13
  4   KHG   14
  5   ADF   15
  6   KKR   16

and another table

 CID   CNAME

  11   Chennai   
  12   Mumbai
  13   Delhi   like this

but, in the grid i would like to display like this:

  SID SNAME  City
  1   ABC   Chennai
  2   XYZ   Mumbai
  3   ACX   Delhi
  4   KHG   Banglore
  5   ADF   Hyderabad
  6   KKR   Kolkatta

I was not able to use join because the class structure is like this:

 Class Student

{
   long sid,
   string sname,
   long city
}

So, when i am reading from the data base i am getting the city id not city name.

But, i would like to display city name instead of City ID in the grid data to end user

i need some thing like a lookup function so that before binding data to the jQgrid,the city id will be mapped with city name and displays it instead of displaying ID

I didnt find a way to get this done.

Please help..

The controller method i am using is as follows:


public JsonResult Students()
    {
        List<Students> liStudents = new  List<Students>();
        SortedList<long, string> slLocations = new SortedList<long, string>();
        slLocations = Students.LoadLocations();
        liStudents = Students.GetStudents();
        return Json(liStudents,JsonRequestBehavior.AllowGet);
    }

How to modify the return statement to throw slLocations too in the json response

Heptamerous answered 17/10, 2013 at 7:10 Comment(0)
M
6

I answered already on the closed question before (see here). Nevertheless I decide to answer on your question in detail because the problem which you describe is really very common.

I start with reminding that jqGrid provides formatter: "select" which uses formatoptions.value or editoptions.value to decode ids to texts. The formatter: "select" uses value and optional separator, delimiter and defaultValue properties, but it can't uses editoptions.dataUrl to get required data from the server instead of usage static value. The problem is very easy: processing dataUrl works asynchronous, but during formatting of the column of grid body one don't support delayed filling. So to use formatter: "select" one have to set formatoptions.value or editoptions.value before the server response will be processed by jqGrid.

In the old answer I suggested to extend JSON response returned from the server with additional data for editoptions.value of the columns having formatter: "select". I suggest to set the beforeProcessing. For example one can generate the server response in the following format:

{
    "cityMap": {"11": "Chennai", "12": "Mumbai", "13": "Delhi"},
    "rows": [
        { "SID": "1",  "SNAME": "ABC", "CITY": "11" },
        { "SID": "2",  "SNAME": "XYZ", "CITY": "12" },
        { "SID": "3",  "SNAME": "ACX", "CITY": "13" },
        { "SID": "4",  "SNAME": "KHG", "CITY": "13" },
        { "SID": "5",  "SNAME": "ADF", "CITY": "12" },
        { "SID": "6",  "SNAME": "KKR", "CITY": "11" }
    ]
}

and uses the following jqGrid options

colModel: [
    {name: "SNAME", width: 250},
    {name: "CITY", width: 180, align: "center"}
],
beforeProcessing: function (response) {
    var $self = $(this);
    $self.jqGrid("setColProp", "CITY", {
        formatter: "select",
        edittype: "select",
        editoptions: {
            value: $.isPlainObject(response.cityMap) ? response.cityMap : []
        }
    });
},
jsonReader: { id: "SID"}

The demo demonstrates the approach. It displays

enter image description here

One can use the same approach to set any column options dynamically. For example one can use

{
    "colModelOptions": {
        "CITY": {
            "formatter": "select",
            "edittype": "select",
            "editoptions": {
                "value": "11:Chennai;13:Delhi;12:Mumbai"
            },
            "stype": "select",
            "searchoptions": {
                "sopt": [ "eq", "ne" ],
                "value": ":Any;11:Chennai;13:Delhi;12:Mumbai"
            }
        }
    },
    "rows": [
        { "SID": "1",  "SNAME": "ABC", "CITY": "11" },
        { "SID": "2",  "SNAME": "XYZ", "CITY": "12" },
        { "SID": "3",  "SNAME": "ACX", "CITY": "13" },
        { "SID": "4",  "SNAME": "KHG", "CITY": "13" },
        { "SID": "5",  "SNAME": "ADF", "CITY": "12" },
        { "SID": "6",  "SNAME": "KKR", "CITY": "11" }
    ]
}

and the following JavaScript code

var filterToolbarOptions = {defaultSearch: "cn", stringResult: true, searchOperators: true},
    removeAnyOption = function ($form) {
        var $self = $(this), $selects = $form.find("select.input-elm");
        $selects.each(function () {
            $(this).find("option[value='']").remove();
        });
        return true; // for beforeShowSearch only
    },
    $grid = $("#list");

$.extend($.jgrid.search, {
    closeAfterSearch: true,
    closeAfterReset: true,
    overlay: 0,
    recreateForm: true,
    closeOnEscape: true,
    afterChange: removeAnyOption,
    beforeShowSearch: removeAnyOption
});

$grid.jqGrid({
    colModel: [
        {name: "SNAME", width: 250},
        {name: "CITY", width: 180, align: "center"}
    ],
    beforeProcessing: function (response) {
        var $self = $(this), options = response.colModelOptions, p,
            needRecreateSearchingToolbar = false;
        if (options != null) {
            for (p in options) {
                if (options.hasOwnProperty(p)) {
                    $self.jqGrid("setColProp", p, options[p]);
                    if (this.ftoolbar) { // filter toolbar exist
                        needRecreateSearchingToolbar = true;
                    }
                }
            }
            if (needRecreateSearchingToolbar) {
                $self.jqGrid("destroyFilterToolbar");
                $self.jqGrid("filterToolbar", filterToolbarOptions);
            }
        }
    },
    jsonReader: { id: "SID"}
});
$grid.jqGrid("navGrid", "#pager", {add: false, edit: false, del: false})
$grid.jqGrid("filterToolbar", filterToolbarOptions);

The demo uses the above code.

We recreate the searching filter if any option are changed dynamically. The way allows implement more flexible solutions. For example the server can detect the language preferences of the client (of the web browser) and return formatting options for numbers, dates and so on based on the options. I'm sure that everyone can suggest other interesting scenarios.

One more remark. If you have too many items in select in (searchoptions.value and editoptions.value) I would recommend you don't use strings instead of objects as the value of searchoptions.value and editoptions.value. It allows you to specify the order of items in the select element.

If you will have too many items in select (for example all cities of your country) then you can consider to use select2 plugin which usage I demonstrate in the answer. It simplify selection of options because it convert select in element which is very close to jQuery UI Autocomplete.

The next demo demonstrate the usage of select2 plugin. If one click on the dropdown arrow of "select" element of the searching toolbar or the searching dialog one get additional input filed which can be used for quick searching. If one starts to type some text in the input box (for example "e" on an example on the picture below) the list of options will be reduced to the options having the typed text as substring:

enter image description here

I personally find such "select-searching" control very practical.

By the way I described in the another answer how to set colNames dynamically. In can be used to manage more information from the server side.

UPDATED: The corresponding controller action Students can be about the following

public class Student {
   public long SID { get; set; }
   public string SNAME { get; set; }
   public long CITY { get; set; }
}
public class City {
    public long CID { get; set; }
    public string CNAME { get; set; }
}
...
public class HomeController : Controller {
    ...
    public JsonResult Students () {
        var students = new List<Student> {
                new Student { SID = 1, SNAME = "ABC", CITY = 11 },
                new Student { SID = 2, SNAME = "ABC", CITY = 12 },
                new Student { SID = 3, SNAME = "ABC", CITY = 13 },
                new Student { SID = 4, SNAME = "ABC", CITY = 13 },
                new Student { SID = 5, SNAME = "ABC", CITY = 12 },
                new Student { SID = 6, SNAME = "ABC", CITY = 11 }
            };
        var locations = new List<City> {
                new City { CID = 11, CNAME = "Chennai"},
                new City { CID = 12, CNAME = "Mumbai"},
                new City { CID = 13, CNAME = "Delhi"}
            };
        // sort and concatinate location corresponds to jqGrid editoptions.value format
        var sortedLocations = locations.OrderBy(location => location.CNAME);
        var sbLocations = new StringBuilder();
        foreach (var sortedLocation in sortedLocations) {
            sbLocations.Append(sortedLocation.CID);
            sbLocations.Append(':');
            sbLocations.Append(sortedLocation.CNAME);
            sbLocations.Append(';');
        }
        if (sbLocations.Length > 0)
            sbLocations.Length -= 1; // remove last ';'
        return Json(new {
                   colModelOptions = new {
                       CITY = new {
                           formatter = "select",
                           edittype = "select",
                           editoptions = new {
                               value = sbLocations.ToString()
                           },
                           stype = "select",
                           searchoptions = new {
                               sopt = new[] { "eq", "ne" },
                               value = ":Any;" + sbLocations
                           }
                       }
                   },
                   rows = students    
               },
               JsonRequestBehavior.AllowGet);
    }
}
Maeganmaelstrom answered 17/10, 2013 at 13:0 Comment(15)
@Oleg..How to return two multiple result sets from same controller action.Heptamerous
@oleg..how to get the extended JSON response from Controller method..lease help on this.Heptamerous
@Oleg..It was working very good.i was able to map id's to names. You are always the best..and your way of answering is simply amazing :)Heptamerous
@Avinash: You are welcome! I posted in UPDATED part an example how controller action can look like.Maeganmaelstrom
@Avinash: My problem is that if I read some interesting question then I think permanently about the problem. So I have to solve the problem and describe the solution. Only after that my brain can be free. :-)Maeganmaelstrom
@Oleg..yes..you always tries for the best solutions.The help you are doing to me is invaluble.I certainly have learnt lot of things since a week from you..i will continue to do the same..:) :)Heptamerous
@Oleg..Sorry..i forgot to mark it as answer..i have noticed it just now.Heptamerous
@Oleg.when you are free..can you please help me on this:#19443742Heptamerous
@Oleg..I need your advice on this.#19491075Heptamerous
@oleg..i am confused about using Sessions in MVC Application for maintaining logged in user data.can you please help me on this?Heptamerous
@Avinash: In any way you should describe which web server you use and how you configured Session State settings for the virtual directory (where the session state you need save). Do you use cluster of web servers? Why you need to support session state in your case? Do you want to have some optimization? Which version of ASP.NET MVC and .NET you use?Maeganmaelstrom
@Oleg..i am not much aware of these things. I wanted to implement windows authentication in MVC 2.0 application. How can i check whether the user has a valid session or not. The process i am doing is , i am taking the logged in user id from the windows active directory and sending that value to database ro verify whether that user is valid user or not. If the user is valid then i am storing as Session["Validuser"]="yes" and if not valid user Session["Validuser"]="no". In each page, i am comparing this value and authenticating.my doubt is can we use session state in MVC or not?Heptamerous
@Avinash: I wrote that I have no time now. I suggest that you modify the text of your question so that other people of community probably could help you. The implementation of Windows Authentication in MVC 2.0 is very easy: you need just have <authentication mode="Windows"/> under <system.web> section of web.config. It's important which web server you use. See "Web" part of Project Properties which different from Visual Studio which you use. On IIS for example you have to enable "Windows Authentication" and disable Anonymous Authentication.Maeganmaelstrom
@Oleg..only when you are free..please help on this..#19517592Heptamerous
@Maeganmaelstrom how do I format a select dropdownlist's text to align left, like your image above, in the City column's search select? Using Free jQgrid 4.15, I want just the select list's text to align left. I want the column's cells to align center, and already know how to do that. Thank you!Halpin
F
0

@Avinash, You can do some trick like this. But still it's not a better solution. It may help you get some idea. What my suggestion is you need to find out better way from your server(ASP.Net) itself. I used grid complete function to modify your data,

gridComplete: function () {
    var rowIDs = jQuery("#list5").getDataIDs(); 
for (var i=0;i<rowIDs.length;i=i+1){ 
  rowData=jQuery("#list5").getRowData(rowIDs[i]);
   if (rowData.city == "11") { 
       $("#list5").find('td').eq('5').html('chennai');
   }else if (rowData.city == "12") { 
       $("#list5").find('td').eq('8').html('mumbai');
  }
 }
}

Hope this helps.

Felix answered 17/10, 2013 at 11:30 Comment(4)
@Vinoth..i will have lot of records like nearly 200. i think it is not possible to write that many things.Heptamerous
@Avinash Which database you are working? Have you tried natural joins? Like this Select t1.SID, t1.SNAME, t2.city From t1, t2 Where t1.city = t2.cName. This worked fine in mysql.Felix
@Vinoth..But if you see my object i dont have any property called Cityname its only CityID , so even if i fetch the value from DB, i would not be able to use it beacuse i am using List<object> to store the result which do not contain that columnHeptamerous
@Avinash I don't have much idea in ASP.Net, May be you need to reconstruct your DB structure/ you need to save the city name in table1 instead of ID.Felix

© 2022 - 2024 — McMap. All rights reserved.