PDA

View Full Version : [CLOSED] Conditionally Populate ComboBox items in a Grid Editor



barnali
Feb 13, 2015, 5:16 AM
Hi,

I need to conditionally populate the items in a Combobox of a Editable Grid based on a field value of the record. Can you please give me some direction to achieve the same.

Thanks,
-

fabricio.murta
Feb 13, 2015, 7:11 AM
Hello, Barnali!

I am sure you will be able to start to build your view with this example: Cell Editing Grid Example (http://examples.ext.net/#/GridPanel/Plugins/CellEditing/).

Try to build it as simpler as you can, yet make it present the data with the cell variation you are talking about.

Once you get this working, you'll just attach a renderer to the column you want with combo options depending on other column of that row, and you will be done.

As for the renderer, you might want to look some examples around this: Simple Array Grid (http://examples.ext.net/#/GridPanel/ArrayGrid/Simple/). The renderer makes the cell be painted a color depending on its value. It is also possible to reference the other cells of the same row in the renderer (as any cell in the table as well). You just need to hands on your browsers' javascript debugger.

With that, I believe you can come up with something. If you get stuck, share the code you were be able to make so far (please share a working code), and we'll help you sort it out.

barnali
Feb 13, 2015, 11:15 PM
Well i am not sure, how to change the Combo Editor options items form a column renderer. In the column renderer i get handle of only the record value right ?

Which is my cshtml -


@model org.ctrla.model.TestViewModel

@{
ViewBag.Title = "Test";
Layout = "~/Views/Shared/_BaseLayout.cshtml";
}

@section headtag
{
<script>
var renderer = function (value) {
return value;
};
</script>
}

@section bodytag
{

@(Html.X().GridPanel()
.Width(600)
.Height(300)
.Store(Html.X().Store()
.Model(Html.X().Model()
.IDProperty("CandidateID")
.Fields(
Html.X().ModelField().Name("CandidateID"),
Html.X().ModelField().Name("FirstName"),
Html.X().ModelField().Name("LastName"),
Html.X().ModelField().Name("BankId")
)
).DataSource(Model.ListData)
)
.ColumnModel(
Html.X().Column()
.Text("FirstName")
.DataIndex("FirstName")
.Width(100),
Html.X().Column()
.Text("LastName")
.DataIndex("LastName")
.Width(100),
Html.X().Column()
.Text("Bank")
.DataIndex("BankId")
.Width(130)
.Editor(
Html.X().ComboBox()
.Items(
"CS",
"JPMC",
"BA"
)
).Renderer("renderer")
)
.SelectionModel(
Html.X().CellSelectionModel()
)
.Plugins(
Html.X().CellEditing().ClicksToEdit(1)
)
)
}

My model -


using System;
using System.Collections;
using System.Collections.Generic;
using org.ctrla.domain;

namespace org.ctrla.model
{
public class TestViewModel
{
public List<ApplicationFee> ListData
{
get{
List<ApplicationFee> list = new List<ApplicationFee>();
list.Add(new ApplicationFee { FirstName = "ABC", LastName = "Last Name ABC", CandidateID=1 });
list.Add(new ApplicationFee { FirstName = "XYZ", LastName = "Last Name XYZ", CandidateID = 2 });
return list;
}
}
}
}

and finally my action method -


public ActionResult Test()
{
return View("Test", new TestViewModel());
}


What is want to implement is - if the CandidateID=1 then in the Bank combo only CS,JPMC will be option items. if the CandidateID=2 then in the Bank combo only CS,BA will be option items.

barnali
Feb 14, 2015, 12:34 AM
Ok. Figured it out.

Rendered along with not do. Need a AjaxProxy on the store to load the data based on my criteria (which is based on a record field).

test.cshtml


@model org.ctrla.model.TestViewModel

@{
ViewBag.Title = "Test";
Layout = "~/Views/Shared/_BaseLayout.cshtml";
}

@section headtag
{
<script>
var beforeEdit = function (ed, e) {
var field = this.getEditor(e.record, e.column).field;
field.allQuery = e.record.get('CandidateID');
};
var BankRenderer = function (value) {
var store = App.BankStore;
var returnVal = '';
store.each(function (record) {
if (record.get('BankID') == value) {
returnVal = record.get('BankName');
}
});
return returnVal;
}
</script>
}

@section bodytag
{
@(Html.X().Store()
.ID("BankStore")
.Model(Html.X().Model()
.Fields(
Html.X().ModelField().Name("BankID"),
Html.X().ModelField().Name("BankName")
)
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetConditionalBankList"))
.Reader(Html.X().JsonReader().Root("data"))
)
)

@(Html.X().GridPanel()
.Width(600)
.Height(300)
.Store(Html.X().Store()
.Model(Html.X().Model()
.IDProperty("CandidateID")
.Fields(
Html.X().ModelField().Name("CandidateID"),
Html.X().ModelField().Name("FirstName"),
Html.X().ModelField().Name("LastName"),
Html.X().ModelField().Name("BankId")
)
).DataSource(Model.ListData)
)
.ColumnModel(
Html.X().Column()
.Text("FirstName")
.DataIndex("FirstName")
.Width(100),
Html.X().Column()
.Text("LastName")
.DataIndex("LastName")
.Width(100),
Html.X().Column()
.Text("Bank")
.DataIndex("BankID")
.Width(130)
.Editor(
Html.X().ComboBox()
.QueryMode(DataLoadMode.Remote)
.TriggerAction(TriggerAction.All)
.StoreID("BankStore")
.ValueField("BankID")
.DisplayField("BankName")
.CustomConfig(cc => cc.Add(new ConfigItem { Name = "initQuery", Value = "Ext.emptyFn", Mode = ParameterMode.Raw }))
).Renderer("BankRenderer")
)
.SelectionModel(
Html.X().CellSelectionModel()
)
.Plugins(Html.X().CellEditing()
.Listeners(events => events.BeforeEdit.Fn = "beforeEdit")
)
)
}

Action method in Controller



public ActionResult Test()
{
return View("Test", new TestViewModel());
}
public ActionResult GetConditionalBankList(string query)
{
List<Bank> bankList = new List<Bank>();

bankList.Add(new Bank { BankID = 1, BankName="CS" });

if (String.IsNullOrEmpty(query) || "1".Equals(query))
bankList.Add(new Bank { BankID = 2, BankName = "JPMC" });

if (String.IsNullOrEmpty(query) || "2".Equals(query))
bankList.Add(new Bank { BankID = 3, BankName = "BA" });

return this.Store(bankList);
}


Well it solves my problem.

Just wandering, with this implementation i have server round trip every time BeforeEdit gets fired. I know the logic, which records to be removed from the store at the client side it self. it would be better i load the store with all Bank information and on BeforeEdit just remove the records which i don't want be appear as Combo item.

Any idea, suggestion ???

fabricio.murta
Feb 14, 2015, 12:50 AM
Hello, @barnali!

Great that you are progressing there!

Basing on many server queries, or leaving things to client size, might never have a general rule.

It depends very much on:
- is your server going to attend much customers all at once?
- is the server bandwidth very large?
- are the customers using modern computers and browsers?
- the customers will have a fast internet connection?

Roughly with these factors you can think better on where you lay your resources dependencies on.

For example, if you are going to have many many customers with modern and fast computers, it would be desirable to lift the load off the server by simplifying and reducing the queries amount, leaving for the client's script to do the data trimming.

But if the application is going to run on a company's intranet with gigabit connection, not so many clients from inside the company accessing it, but these clients use old and slow computers, that's a case where you might want to let the customers make resquests every interactions with the page and have them come as prepared as possible to reduce the client's overhead.

Other scenarios include screens that tons of informations are available but the customers are going to query just a small portion. There, for example, remote paging is a good alternative for grids. For other controls, renderers like you did, to pull data from the server as the user interacts, might improve very much the user experience (as the initial load time would be smaller).

So, I'd say nobody better than you to decide whether you want to concentrate the load on the server, or the client, or how are you going to balance it between the two sides.

While this does not exactly responds what you are asking, I hope this helps you decide the path you want to take to improve your screen.