PDA

View Full Version : [CLOSED] Razor- Grid Panel Editor Combobox



OriCoder
Jan 17, 2013, 1:33 PM
When I am trying to add a parameter to a store, to get back data I just get an error, is this me or is it a bug ... code is below




.Editor(
Html.X().ComboBox()
.ValueField("SettlementAccountId")
.DisplayField("Name")
.Store(
Html.X().Store()
.ID("StoreSettlementAccountList")
.AutoLoad(true)
.Model(Html.X().Model()
.Fields(
new ModelField("SettlementAccountId", ModelFieldType.Int),
new ModelField("Name", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("GetSettlementAccountList"))
.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)

)
.Parameters( para = >
{
para.add(new Parameter("id", "record.get('OrderLinkId')", ParameterMode.Raw));
}
)



P.S... Still no answer from any of the ext support team, I should be getting premium support. 3 mails no answer.

Vladimir
Jan 17, 2013, 8:16 PM
Hi,

If you want to get answer then please always include runable test case

About your parameter value


record.get('OrderLinkId')


There is no 'record' reference when a store initiate load request. What 'record' do you mean?

OriCoder
Jan 17, 2013, 8:32 PM
Hi Vladimir

Thanks for replying, first can you get someone to sort my premium access, I've emailed now About 3 times and no answer. Now back to the code.

This example is runnable if you add the code to a column model on a grid panel you should then see that i'am getting an error on the .parameter the msg in visual studio is about it not being a lambda delegate? I have taken this example of usage from another forum answer so assume it is the correct usage? But razor example a far fewer than web forms.

I cannot post the full code from the application but the .editor block should be self contained.


Hi,

If you want to get answer then please always include runable test case

About your parameter value


record.get('OrderLinkId')


There is no 'record' reference when a store initiate load request. What 'record' do you mean?

Vladimir
Jan 17, 2013, 9:03 PM
I cannot post the full code from the application but the .editor block should be self contained.


We don't need full code, just create simple runable test case reproduces the issue. We cannot use just part of the code, it is better if we just run your ready sample

- need to use 'Add' method of 'para' collection instead 'add' (C# is case sensitive language)
- you have to use StoreParameter instead Parameter
- 'record' reference is absent, you will get javascript error

Vladimir
Jan 17, 2013, 9:04 PM
First can you get someone to sort my premium access, I've emailed now About 3 times and no answer.

I will notify our manager, if you purchased premium support then you should get email with SVN credentials. I will ask about you

OriCoder
Jan 17, 2013, 10:02 PM
Ok so I have got "Parameter" to work a few silly typo's.

But to the topic of this thread I am trying to pass a parameter from a cell on a row to a direct method and then using this in my SQL to return my dataset for the combobox.

I can do this fine on a click event on a row I tried using .ExtraParams on the AjaxProxy but found threads saying this way not the way to do it and to use .Parameters instead, which does not give the result I am looking for.

I am stuck, only want to pass a value from a cell on a selected row to get data for a combobox. For a test case code below to work with...



@Html.X().ResourceManager()
@(
Html.X().GridPanel()
.ColumnModel(
Html.X().Column()
.Text("companyId")
.Width(50)
.Flex(1)
.Editor(Html.X().NumberField()),
Html.X().Column()
.Text("SettlementAccount")
.Width(125)
.Flex(1)
.Editor(
Html.X().ComboBox()
.ValueField("SettlementAccountId")
.DisplayField("Name")
.Store(
Html.X().Store()
.ID("StoreSettlementAccountList")
.AutoLoad(true)
.Model(Html.X().Model()
.Fields(
new ModelField("SettlementAccountId", ModelFieldType.Int),
new ModelField("Name", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("GetSettlementAccountList"))
.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)

)
.Parameters( para =>
{
para.Add(new StoreParameter("id", "record.get('companyId')", ParameterMode.Raw));
}
)
)
)
)
)




We don't need full code, just create simple runable test case reproduces the issue. We cannot use just part of the code, it is better if we just run your ready sample

- need to use 'Add' method of 'para' collection instead 'add' (C# is case sensitive language)
- you have to use StoreParameter instead Parameter
- 'record' reference is absent, you will get javascript error

Daniil
Jan 18, 2013, 11:04 AM
Hi @OriCoder,

Do you need to load the ComboBox's Store remotely according the cell's value when a user click that cell to edit?

If yes, you need something like this.
http://examples2.ext.net/#/Form/ComboBox/Linked_Combos_In_Grid/

Here is a simplified Razor example.

Example

<!DOCTYPE html>

<html>
<head>
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
@Html.X().ResourceManager()

@(Html.X().GridPanel()
.Height(200)
.Store(Html.X().Store()
.Model(Html.X().Model()
.Fields(Html.X().ModelField().Name("test"))
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetDataForGridPanel"))
.Reader(Html.X().JsonReader().Root("data"))
)
)
.ColumnModel(Html.X().Column()
.Text("Test")
.DataIndex("test")
.Editor(Html.X().ComboBox()
.DisplayField("text")
.ValueField("value")
.Store(Html.X().Store()
.AutoLoad(false)
.Model(Html.X().Model()
.Fields("value", "text")
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetDataForComboBox"))
.Reader(Html.X().JsonReader().Root("data"))
)
)
)
)
.Plugins(Html.X().CellEditing()
.Listeners(events =>
{
events.BeforeEdit.Handler = @"var field = this.getEditor(e.record, e.column).field;
field.allQuery = e.value;";
})
)
)
</body>
</html>

Controller Actions

public ActionResult GetDataForCombobox(string query)
{
object[] data = new object[]
{
new
{
text = query + " 1",
value = "1"
},
new
{
text = query + " 2",
value = "2"
},
};

return this.Store(data);
}

public ActionResult GetDataForGridPanel()
{
List<object> data = new List<object>
{
new { test = "test1" },
new { test = "test2" },
new { test = "test3" }
};

return this.Store(data);
}

OriCoder
Jan 18, 2013, 12:41 PM
Hi Daniil

Kind of.. in context of the linkied combo example what I need to do is look at the value of the cell on the right and its value, would be used to get my list of options from a database.

Daniil
Jan 18, 2013, 1:42 PM
Seems my example demonstrates it, doesn't?

OriCoder
Jan 18, 2013, 2:31 PM
no that example shows picking a value on the left e.g. "state" and then this is passed to the options in the boxes to the right. I need start editing say "City" and it looks at the value of "state" which then uses this value to get the data from the database to give you combobox options. If I use



.Url(Url.Action("GetSettlementAccountList/81))


Then this will pull that account list from the db, just trying to make the "81" dynamic is where I am stuck.

Daniil
Jan 18, 2013, 3:27 PM
I would try like this.

Example View

<!DOCTYPE html>

<html>
<head>
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
@Html.X().ResourceManager()

@(Html.X().GridPanel()
.Height(200)
.Store(Html.X().Store()
.Model(Html.X().Model()
.Fields(Html.X().ModelField().Name("test"))
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetDataForGridPanel"))
.Reader(Html.X().JsonReader().Root("data"))
)
)
.ColumnModel(Html.X().Column()
.Text("Test")
.DataIndex("test")
.Editor(Html.X().ComboBox()
.DisplayField("text")
.ValueField("value")
.Store(Html.X().Store()
.AutoLoad(false)
.Model(Html.X().Model()
.Fields("value", "text")
)
.Proxy(Html.X().AjaxProxy()
.Reader(Html.X().JsonReader().Root("data"))
.CustomConfig(cc => cc.Add(new { rawUrl = Url.Action("GetDataForComboBox") }))
)
)
)
)
.Plugins(Html.X().CellEditing()
.Listeners(events =>
{
events.BeforeEdit.Handler = @"var field = this.getEditor(e.record, e.column).field;
proxy = field.getStore().proxy;

delete field.lastQuery;
proxy.url = proxy.rawUrl + '/' + e.value;";
})
)
)
</body>
</html>

OriCoder
Jan 18, 2013, 5:37 PM
Hi

I see what you are getting at but after intagrating this into my code the best is gives is the value of the current field not the one to the left. Also there are many comboboxes on the panel so this code would get in the way of them all which is not desired.

I looked back at one of my first posts and adjusting your code as follows gets me what I want with the listener. But now the listener gets in the way of my other drop downs. Is there a better way to get the value or at lest have it only effect one of the combos?




proxy.url = proxy.rawUrl + '/' + #{DetailPanel}.getRowsValues({selectedOnly:true})[0].CounterpartyId;";

Daniil
Jan 21, 2013, 5:07 AM
I see what you are getting at but after intagrating this into my code the best is gives is the value of the current field not the one to the left. Also there are many comboboxes on the panel so this code would get in the way of them all which is not desired.


If you need values of other record's fields, then you could use something like this

e.record.get("CounterpartyId")
instead of "e.value".



I looked back at one of my first posts and adjusting your code as follows gets me what I want with the listener. But now the listener gets in the way of my other drop downs. Is there a better way to get the value or at lest have it only effect one of the combos?




proxy.url = proxy.rawUrl + '/' + #{DetailPanel}.getRowsValues({selectedOnly:true})[0].CounterpartyId;";


The requirement is not clear for me. Could you, please, provide some runnable and simplified example which would demonstrate the problem/requirement?

There is also a possibility to just load ComboBox items within a BeforeEdit listener.

combo.getStore().load({ /*options */ });

OriCoder
Jan 21, 2013, 12:50 PM
Thanks Daniil, I wont get a look at the app till later tonight. really just need for the listener code to cut in on a specified combo box rather than them all. I'll see how far I get and post back an example

Daniil
Jan 21, 2013, 2:11 PM
Ok, will wait an example.

For a specified ComboBox... I think the ComboBox's BeforeQuery event might be helpful here.
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.form.field.ComboBox-event-beforequery

OriCoder
Jan 22, 2013, 10:08 PM
Still looking at this and the more I try before query etc, all seams to be getting very complex java script for what should be somthing very simple. Should I not be trying to do somthing like below.. simlar to the following post although I know that this is a direct event and I have these working.

http://forums.ext.net/showthread.php?18485-CLOSED-Razor-Parameter-passing-from-DirectEvents


I know i've said it before but how hard can it be just to pick up the value from the cell on the left and pass it as an extra param in the URL? Just seams to be getting very complicated


In the below example the only thing I can see that is not working is my value = "" if I set it to a static number is work, try and ref a App component and it don't I have also tried



this.up('grid').record.get('CounterpartyId')

and

record.get('CounterpartyId')



none of them work



@(
]<!DOCTYPE html>

<html>
<head>
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
@Html.X().ResourceManager()

@(Html.X().GridPanel()
.ID("DetailPanel")
.Height(200)
.Store(Html.X().Store()
.Model(Html.X().Model()
.Fields(Html.X().ModelField().Name("test"))
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetDataForGridPanel"))
.Reader(Html.X().JsonReader().Root("data"))
)
)
.ColumnModel(Html.X().Column()
.Text("Test")
.DataIndex("test")
.Editor(
Html.X().ComboBox()


.ValueField("SettlementAccountId")
.DisplayField("Name")
.Store(
Html.X().Store()
.ID("StoreSettlementAccountList")
.AutoLoad(false)
.Model(Html.X().Model()
.Fields(
new ModelField("SettlementAccountId", ModelFieldType.Int),
new ModelField("Name", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("GetSettlementAccountList"))
.ExtraParams(ep =>
{
ep.Add(new Parameter()
{
Name = "id",
Value = "App.DetailPanel.getRowsValues({selectedOnly:true})[0].CounterpartyId",
Mode = ParameterMode.Raw
}
);


}
)
.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)


)

)

)
)
.Plugins(Html.X().CellEditing()

)
)
</body>
</html>



)

Daniil
Jan 23, 2013, 4:25 AM
Well, a Proxy knows nothing about GridPanel, ComboBox, editing, etc.

So, yes, some JavaScript is required to get it working.

But the following doesn't look complicated for me. Hope this example helps.

Example View

<!DOCTYPE html>

<html>
<head>
<title>Ext.Net.MVC v2 Example</title>
</head>
<body>
@Html.X().ResourceManager()

@(Html.X().GridPanel()
.Height(200)
.Store(Html.X().Store()
.Model(Html.X().Model()
.Fields("someIdField", "test")
)
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("GetDataForGridPanel"))
.Reader(Html.X().JsonReader().Root("data"))
)
)
.ColumnModel(
Html.X().Column()
.Text("Some id field")
.DataIndex("someIdField"),
Html.X().Column()
.Text("Test")
.DataIndex("test")
.Editor(Html.X().ComboBox()
.QueryMode(DataLoadMode.Local)
.DisplayField("text")
.ValueField("value")
.Store(Html.X().Store()
.AutoLoad(false)
.Model(Html.X().Model()
.Fields("value", "text")
)
.ServerProxy(Html.X().AjaxProxy()
.Reader(Html.X().JsonReader().Root("data"))
.Url(Url.Action("GetDataForComboBox"))
)
)
)
)
.Plugins(Html.X().CellEditing()
.Listeners(events =>
{
events.BeforeEdit.Handler = @"var store = this.getEditor(e.record, e.column).field.getStore();

store.reload({
params: {
someParam: e.record.get('someIdField')
}
});";
})
)
)
</body>
</html>

Example Actions

public ActionResult Index()
{
return View();
}

public ActionResult GetDataForCombobox(string someParam)
{
object[] data = new object[]
{
new
{
text = someParam + " 1",
value = "1"
},
new
{
text = someParam + " 2",
value = "2"
},
};

return this.Store(data);
}

public ActionResult GetDataForGridPanel()
{
List<object> data = new List<object>
{
new { someIdField = "id1", test = "test1" },
new { someIdField = "id2", test = "test2" },
new { someIdField = "id3", test = "test3" }
};

return this.Store(data);
}

OriCoder
Jan 23, 2013, 7:24 AM
Sorry Danill.

But again you are using the BeforeEdit on the GridPanel its self this then in turn effects all the comboboxes in the grid not just the one I want effected.

E.g. Combo1, Combo2, Combo3

Combo1 - Can be any value from a fixed list from db
Combo2 - need to look at the result of Combo1 to get a value to generate its list from the db
Combo 3 - looks at Combo2 to get the value to generate its list from the db

When using direct event it is simple just tell it get records. Even if the combo knows nothing about the grid panel surely I should be able to use a direct referance to the selected row and field and pass it as a value. e.g.


.ExtraParams(ep =>
{
ep.Add(new Parameter()
{
Name = "id",
Value = "App.DetailPanel.getRowsValues({selectedOnly:true})[0].CounterpartyId",
Mode = ParameterMode.Raw
}
);


When using toolbar buttons which I asume would also know nothing about the gridpanel since these are also out of context being in a toolbar.

this.up('grid') allows me to access the rows.

Just to be very clear.

I need to pass a different field depending on the combobox that is being editted and also some of them do NOT pass any field to get there lists.

Daniil
Jan 23, 2013, 9:23 AM
Apologize.

Please clarify where are all the ComboBoxes? In the same column or different ones?

Is there any chance for us to get a sample which would demonstrate the requirement?:) Just everything that you have already built and working (but simplified like my examples).

OriCoder
Jan 23, 2013, 10:11 AM
Hi

I it ok if I zip and PM you the solution file. That was you can see exactly what I am doing?

Regards

Daniil
Jan 23, 2013, 11:24 AM
We are trying to keep public on the forums as much as possible.

Could you clarify why you want to send a whole solution, but not post required things directly here?

OriCoder
Jan 23, 2013, 12:27 PM
Hi Danill

I just want to solve the issue as quick as possible and letting someone look at the whole solution is the quickist way so there is not more misunderstandings.

But your right the info should be as public as possible so it can help others, as I have found many threads very useful.

I will take the time tonight to strip out and build a full MVC example of the issue, hopfully we can find a quick solution once you see it.

Regards

Daniil
Jan 23, 2013, 12:56 PM
Thank you for understanding!

Yes, your scenario looks very interesting to keep it public.

OriCoder
Jan 24, 2013, 7:06 PM
Hi

Below is a full example of what I am trying to do, I know it doesnt fully work but thats point.

Just to recap cap the point is that first combo box, could be any plant, this would set the Zone ultimatly ...

the second looks at the Zone value set by the first, which determines the options for the second combo list.

third combo looks at the result of the second and uses this value, to get the list of option for this combo.

Hope this all helps as I really need to get this sorted.


Model:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
using Ext.Net.MVC;

namespace Ext.Net.MVC.Examples.Areas.GridPanel_Paging_and_So rting.Models
{

public class Soil
{
public int id { get; set; }
public int shadeId { get; set; }
public string value { get; set; }
}

public class Shade
{
public int id { get; set; }
public int zoneId { get; set; }
public string value { get; set; }
}

public class Plant
{
public int id
{
get;
set;
}
public string Common
{
get;
set;
}

public string Botanical
{
get;
set;
}

public int Zone
{
get;
set;
}

public string ColorCode
{
get;
set;
}

public string Light
{
get;
set;
}

public double Price
{
get;
set;
}

public DateTime Availability
{
get;
set;
}

public bool Indoor
{
get;
set;
}

public static Paging<Plant> PlantsPaging(StoreRequestParameters parameters)
{
return Plant.PlantsPaging(parameters.Start, parameters.Limit, parameters.SimpleSort, parameters.SimpleSortDirection, null);
}

public static Paging<Plant> PlantsPaging(int start, int limit, string sort, SortDirection dir, string filter)
{
List<Plant> plants = Plant.GetPlants();

if (!string.IsNullOrEmpty(filter) && filter != "*")
{
plants.RemoveAll(plant => !plant.Common.ToLower().StartsWith(filter.ToLower( )));
}

if (!string.IsNullOrEmpty(sort))
{
plants.Sort(delegate(Plant x, Plant y)
{
object a;
object b;

int direction = dir == SortDirection.DESC ? -1 : 1;

a = x.GetType().GetProperty(sort).GetValue(x, null);
b = y.GetType().GetProperty(sort).GetValue(y, null);

return CaseInsensitiveComparer.Default.Compare(a, b) * direction;
});
}

if ((start + limit) > plants.Count)
{
limit = plants.Count - start;
}

List<Plant> rangePlants = (start < 0 || limit < 0) ? plants : plants.GetRange(start, limit);

return new Paging<Plant>(rangePlants, plants.Count);
}

public static List<Shade> GetShade()
{
return new List<Shade>{
new Shade
{
id = 1,
zoneId = 1,
value = "Darkness"
}
,
new Shade
{
id = 1,
zoneId = 1,
value = "Mostly Shady"
}
,
new Shade
{
id = 2,
zoneId = 2,
value = "Sun or Shade"
}
,
new Shade
{
id = 3,
zoneId = 2,
value = "Mostly Sunny"
}
,
new Shade
{
id = 4,
zoneId = 3,
value = "Shade"
}
,
new Shade
{
id = 5,
zoneId = 3,
value = "Bright Sunlight"
}
};
}

public static List<Soil> GetSoil()
{
return new List<Soil>{
new Soil
{
id = 1,
shadeId = 1,
value = "Light Acid"
}
,
new Soil
{
id = 2,
shadeId = 1,
value = "Very Acid"
}
,
new Soil
{
id = 3,
shadeId = 2,
value = "Neutral"
}
,
new Soil
{
id = 4,
shadeId = 3,
value = "Very Alkiline"
}
,
new Soil
{
id = 4,
shadeId = 3,
value = "Light Alkiline"
}
};
}

public static List<Plant> GetPlants()
{
return new List<Plant> {
new Plant
{ id = 1,
Common = "Bloodroot",
Botanical = "Sanguinaria canadensis",
Zone = 2,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 2.44,
Availability = new DateTime(2006, 03, 15),
Indoor = true
},

new Plant
{ id = 2,
Common = "Columbine",
Botanical = "Aquilegia canadensis",
Zone = 2,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 9.37,
Availability = new DateTime(2006, 03, 06),
Indoor = true
},

new Plant
{ id = 3,
Common = "Marsh Marigold",
Botanical = "Caltha palustris",
Zone = 1,
ColorCode = "F5F5F5",
Light = "Mostly Sunny",
Price = 6.81,
Availability = new DateTime(2006, 05, 17),
Indoor = false
},

new Plant
{ id = 4,
Common = "Cowslip",
Botanical = "Caltha palustris",
Zone = 1,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 9.90,
Availability = new DateTime(2006, 03, 06),
Indoor = true
},

new Plant
{ id = 5,
Common = "Dutchman's-Breeches",
Botanical = "Dicentra cucullaria",
Zone = 3,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 6.44,
Availability = new DateTime(2006, 01, 20),
Indoor = true
},

new Plant
{ id = 6,
Common = "Ginger, Wild",
Botanical = "Asarum canadense",
Zone = 3,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 9.03,
Availability = new DateTime(2006, 04, 18),
Indoor = true
},

new Plant
{ id = 7,
Common = "Hepatica",
Botanical = "Hepatica americana",
Zone = 4,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 4.45,
Availability = new DateTime(2006, 01, 26),
Indoor = true
},

new Plant
{ id = 8,
Common = "Liverleaf",
Botanical = "Hepatica americana",
Zone = 1,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 3.99,
Availability = new DateTime(2006, 01, 02),
Indoor = true
},

new Plant
{ id = 9,
Common = "Jack-In-The-Pulpit",
Botanical = "Arisaema triphyllum",
Zone = 1,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 3.23,
Availability = new DateTime(2006, 02, 01),
Indoor = true
},

new Plant
{ id = 10,
Common = "Mayapple",
Botanical = "Podophyllum peltatum",
Zone = 3,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 2.98,
Availability = new DateTime(2006, 06, 05),
Indoor = true
},

new Plant
{ id = 11,
Common = "Phlox, Woodland",
Botanical = "Phlox divaricata",
Zone = 3,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 2.80,
Availability = new DateTime(2006, 01, 22),
Indoor = false
},

new Plant
{ id = 12,
Common = "Phlox, Blue",
Botanical = "Phlox divaricata",
Zone = 1,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 5.59,
Availability = new DateTime(2006, 02, 16),
Indoor = false
},

new Plant
{ id = 13,
Common = "Spring-Beauty",
Botanical = "Claytonia Virginica",
Zone = 1,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 6.59,
Availability = new DateTime(2006, 02, 01),
Indoor = true
},

new Plant
{ id = 14,
Common = "Trillium",
Botanical = "Trillium grandiflorum",
Zone = 2,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 3.90,
Availability = new DateTime(2006, 04, 29),
Indoor = false
},

new Plant
{ id = 15,
Common = "Wake Robin",
Botanical = "Trillium grandiflorum",
Zone = 2,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 3.20,
Availability = new DateTime(2006, 02, 21),
Indoor = false
},

new Plant
{ id = 16,
Common = "Violet, Dog-Tooth",
Botanical = "Erythronium americanum",
Zone = 1,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 9.04,
Availability = new DateTime(2006, 02, 01),
Indoor = true
},

new Plant
{ id = 17,
Common = "Trout Lily",
Botanical = "Erythronium americanum",
Zone = 3,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 6.94,
Availability = new DateTime(2006, 03, 24),
Indoor = true
},

new Plant
{ id = 18,
Common = "Adder's-Tongue",
Botanical = "Erythronium americanum",
Zone = 3,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 9.58,
Availability = new DateTime(2006, 04, 13),
Indoor = true
},

new Plant
{ id = 19,
Common = "Anemone",
Botanical = "Anemone blanda",
Zone = 4,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 8.86,
Availability = new DateTime(2006, 12, 26),
Indoor = true
},

new Plant
{ id = 20,
Common = "Grecian Windflower",
Botanical = "Anemone blanda",
Zone = 4,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 9.16,
Availability = new DateTime(2006, 07, 10),
Indoor = true
},

new Plant
{ id = 21,
Common = "Bee Balm",
Botanical = "Monarda didyma",
Zone = 1,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 4.59,
Availability = new DateTime(2006, 05, 03),
Indoor = true
},

new Plant
{ id = 22,
Common = "Bergamot",
Botanical = "Monarda didyma",
Zone = 2,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 7.16,
Availability = new DateTime(2006, 04, 27),
Indoor = true
},

new Plant
{ id = 23,
Common = "Black-Eyed Susan",
Botanical = "Rudbeckia hirta",
Zone = 3,
ColorCode = "FFFFFF",
Light = "Sunny",
Price = 9.80,
Availability = new DateTime(2006, 06, 18),
Indoor = false
},

new Plant
{ id = 24,
Common = "Buttercup",
Botanical = "Ranunculus",
Zone = 4,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 2.57,
Availability = new DateTime(2006, 06, 10),
Indoor = true
},

new Plant
{ id = 25,
Common = "Crowfoot",
Botanical = "Ranunculus",
Zone = 4,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 9.34,
Availability = new DateTime(2006, 04, 03),
Indoor = true
},

new Plant
{ id = 26,
Common = "Butterfly Weed",
Botanical = "Asclepias tuberosa",
Zone = 2,
ColorCode = "FFFFFF",
Light = "Sunny",
Price = 2.78,
Availability = new DateTime(2006, 06, 30),
Indoor = false
},

new Plant
{ id = 27,
Common = "Cinquefoil",
Botanical = "Potentilla",
Zone = 1,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 7.06,
Availability = new DateTime(2006, 05, 25),
Indoor = true
},

new Plant
{ id = 28,
Common = "Primrose",
Botanical = "Oenothera",
Zone = 2,
ColorCode = "FFFFFF",
Light = "Sunny",
Price = 6.56,
Availability = new DateTime(2006, 01, 30),
Indoor = false
},

new Plant
{ id = 29,
Common = "Gentian",
Botanical = "Gentiana",
Zone = 4,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 7.81,
Availability = new DateTime(2006, 05, 18),
Indoor = false
},

new Plant
{ id = 30,
Common = "Blue Gentian",
Botanical = "Gentiana",
Zone = 3,
ColorCode = "EEEEEE",
Light = "Sun or Shade",
Price = 8.56,
Availability = new DateTime(2006, 05, 02),
Indoor = false
},

new Plant
{ id = 31,
Common = "Jacob's Ladder",
Botanical = "Polemonium caeruleum",
Zone = 1,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 9.26,
Availability = new DateTime(2006, 02, 21),
Indoor = true
},

new Plant
{ id = 32,
Common = "Greek Valerian",
Botanical = "Polemonium caeruleum",
Zone = 1,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 4.36,
Availability = new DateTime(2006, 07, 14),
Indoor = true
},

new Plant
{ id = 33,
Common = "California Poppy",
Botanical = "Eschscholzia californica",
Zone = 2,
ColorCode = "FFFFFF",
Light = "Sunny",
Price = 7.89,
Availability = new DateTime(2006, 03, 27),
Indoor = false
},

new Plant
{ id = 34,
Common = "Shooting Star",
Botanical = "Dodecatheon",
Zone = 2,
ColorCode = "E7E7E7",
Light = "Mostly Shady",
Price = 8.60,
Availability = new DateTime(2006, 05, 13),
Indoor = true
},

new Plant
{ id = 35,
Common = "Snakeroot",
Botanical = "Cimicifuga",
Zone = 3,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 5.63,
Availability = new DateTime(2006, 07, 11),
Indoor = true
},

new Plant
{ id = 36,
Common = "Cardinal Flower",
Botanical = "Lobelia cardinalis",
Zone = 3,
ColorCode = "E1E1E1",
Light = "Shade",
Price = 3.02,
Availability = new DateTime(2006, 02, 22),
Indoor = true
}
};
}
}
}


Controller


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ext.Net.MVC.Examples.Areas.GridPanel_Paging_and_So rting.Models;

namespace Ext.Net.MVC.Examples.Areas.GridPanel_Paging_and_So rting.Controllers
{
public class RemoteController : Controller
{
public ActionResult Index()
{
return View();
}

public ActionResult Read(StoreRequestParameters parameters)
{
return this.Store(Plant.PlantsPaging(parameters));
}
public ActionResult Plants()
{
IEnumerable<Plant> Plants;
Plants = (from ofg in Plant.GetPlants()
select ofg);

return this.Direct(Plants);
}



public ActionResult Shade(int id)
{
IEnumerable<Shade> Shade;
Shade = (from ofg in Plant.GetShade()
where ((ofg.zoneId == id))
select ofg);

return this.Direct(Shade);
}

public ActionResult Soil(int id)
{
IEnumerable<Soil> Soil;
Soil = (from ofg in Plant.GetSoil()
where ((ofg.shadeId == id))
select ofg);

return this.Direct(Soil);
}

public DirectResult Edit(int id, string field, string oldValue, string newValue, object customer)
{
string message = "<b>Property:</b> {0}<br /><b>Field:</b> {1}<br /><b>Old Value:</b> {2}<br /><b>New Value:</b> {3}";

// Send Message...
X.Msg.Notify("Edit Record #" + id.ToString(), string.Format(message, id, field, oldValue, newValue)).Show();

X.GetCmp<Store>("Store1").GetById(id).Commit();
return this.Direct();
}
}
}



View:


@model Ext.Net.MVC.Examples.Areas.GridPanel_Paging_and_So rting.Models.Plant
<h1>Remote paging and sorting</h1>
<script>
var edit = function (editor, e) {
/*
"e" is an edit event with the following properties:

grid - The grid
record - The record that was edited
field - The field name that was edited
value - The value being set
originalValue - The original value for the field, before the edit.
row - The grid table row
column - The grid Column defining the column that was edited.
rowIdx - The row index that was edited
colIdx - The column index that was edited
*/

// Call DirectMethod
if (e.value !== e.originalValue) {
Ext.net.DirectMethod.request({
url: '@(Url.Action("Edit"))',
params: {
id: e.record.data.id,
field: e.field,
oldValue: e.originalValue,
newValue: e.value,
customer: e.record.data
}
});
}
};

</script>
@Html.X().ResourceManager()
@(

Html.X().GridPanel()
.ID("PlantGrid")
.Title("Plants")
.Frame(true)
.Height(300)
.Plugins(
Html.X().CellEditing().Listeners(ls =>
{
ls.Edit.Fn = "edit";

}
)
)
.Store(
Html.X().StoreForModel()
.ID("Store1")
.Proxy(Html.X().AjaxProxy()
.Url(Url.Action("Read"))
.Reader(Html.X().JsonReader().Root("data"))
)
.RemoteSort(true)
.PageSize(5)
.SorterFor(Model, m => m.Common, Ext.Net.SortDirection.ASC)
)
.ColumnModel(
Html.X().Column().DataIndex(Model, m => m.id).Text("id"),
Html.X().Column().DataIndex(Model, m => m.Common).Text("Common Name").Flex(1)
.Editor(
Html.X().ComboBox()
.ValueField("id")
.DisplayField("Common")
.Store(
Html.X().Store()
.ID("PlantsList")
.AutoLoad(false)
.Model(Html.X().Model()
.Fields(
new ModelField("id", ModelFieldType.Int),
new ModelField("Common", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("Plants"))

.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)


)

)

)
,
Html.X().Column().DataIndex(Model, m => m.Botanical).Text("Botanical").Width(230),
Html.X().Column().DataIndex(Model, m => m.Zone).Text("Zone").Width(50),
Html.X().Column().DataIndex(Model, m => m.Light).Text("Shade").Width(130)
.Editor(
Html.X().ComboBox()
.ValueField("id")
.DisplayField("value")
.Store(
Html.X().Store()
.ID("ShadeList")
.AutoLoad(false)
.Model(Html.X().Model()
.Fields(
new ModelField("id", ModelFieldType.Int),
new ModelField("value", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("Shade"))
.ExtraParams(ep =>
{
ep.Add(new Parameter()
{
Name = "id",
Value = "3",
Mode = ParameterMode.Raw
}
);


}
)
.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)


)

)

)
,
Html.X().Column().Text("Soil").Width(130)
.Editor(
Html.X().ComboBox()
.ValueField("id")
.DisplayField("value")
.Store(
Html.X().Store()
.ID("SoilList")
.AutoLoad(false)
.Model(Html.X().Model()
.Fields(
new ModelField("id", ModelFieldType.Int),
new ModelField("value", ModelFieldType.String)
)

)

.Proxy(
Html.X().AjaxProxy()
.Url(Url.Action("Soil"))
.ExtraParams(ep =>
{
ep.Add(new Parameter()
{
Name = "id",
Value = "3",
Mode = ParameterMode.Raw
}
);


}
)
.ActionMethods(actions =>
{

actions.Read = HttpMethod.POST;
}
)

.Reader(
Html.X().JsonReader().Root("result")
)


)

)

)
,
Html.X().Column().DataIndex(Model, m => m.Price).Text("Price").Width(70).Align(Alignment.Right),
Html.X().DateColumn().DataIndex(Model, m => m.Availability).Text("Available").Width(95).Format("yyyy-MM-dd"),
Html.X().Column().DataIndex(Model, m => m.Indoor).Text("Indoor?").Width(55)
)
.BottomBar(
Html.X().PagingToolbar()
.DisplayInfo(true)
.DisplayMsg("Displaying plants {0} - {1} of {2}")
.EmptyMsg("No plants to display")
)
)

Daniil
Jan 25, 2013, 4:00 AM
Thank you for the sample.

But there is a few problems.

1. I had to remove one comma in the View to get it compiled.

2. This code line:

return this.Store(Plant.PlantsPaging(parameters));
throws "...Plant() is a method which is not valid in the given context".

It is because of the controller has "Plant" method:

public ActionResult Plant()

I was able to avoid this error using the full namespace.

Ext.Net.MVC.Examples.Areas.GridPanel_Paging_and_So rting.Models.Plant

But a new error occurs.

3. There is no GetPlant method in the Model.

Plant = (from ofg in Plant.GetPlant()
select ofg);

These errors confuse.

Am I wrong to expect your sample to be runnable?

OriCoder
Jan 25, 2013, 6:32 AM
Sorry I added the plant combo outside of vs. I have found that the extrapram on thee combos stops it running, i don't know why. I have tried my best to show code that I think should from other thing I have done. I had it all compiled and tested before I added the combos .... but adding the combos is the whole point .

Daniil
Jan 25, 2013, 6:52 AM
So, will you correct the sample to get it runnable?

OriCoder
Jan 25, 2013, 10:03 AM
Hi

I have updated my post with the code. It is in a runable state with combos passing static id values, this is what needs to be made dynamic.

e.g.



.ExtraParams(ep =>
{
ep.Add(new Parameter()
{
Name = "id",
This needs to be dynamic ---> Value = "3",
Mode = ParameterMode.Raw
}
);


}
)

Daniil
Jan 25, 2013, 12:38 PM
Thank you.

Well, there are two approaches I can suggest.

1. You can separate the logic by columns in the beforeEdit event.

The base of solution is here.
http://forums.ext.net/showthread.php?23081&p=101073&viewfull=1#post101073

Just something like:

if (e.column.dataIndex === "field1") {
... e.record.get("fieldForParameter1");
} else if (e.column.dataIndex === "field2") {
... e.record.get("fieldForParameter2");
}

2. The Proxy's Parameters are not dynamic. They are built once at render time.

You can try to use the Store's Parameters.

.Parameters(p => p.Add(new StoreParameter()
{
Name = "id",
Value = "App.PlantGrid.editingPlugin.getActiveRecord().get( 'Common')",
Mode = ParameterMode.Raw
})
)

It is for the ComboBox of the Shade column.

You also might need to set up this listener for the ComboBox.

.Listeners(events =>
events.BeforeQuery.Handler = "delete this.lastQuery;"
)

To get the Store reload on each trigger click.

Hope this helps.

OriCoder
Jan 25, 2013, 2:13 PM
Hi Danill

We got there in the end using both of the following done the trick for me, I can now build my dynamic grid. No doubt I will have some more questions soon.

Gets me the cell value I need



.Parameters(p => p.Add(new StoreParameter()
{
Name = "id",
Value = "App.PlantGrid.editingPlugin.getActiveRecord().get( 'Common')",
Mode = ParameterMode.Raw
})
)



Makes sure it refreshes the combo on each row



.Listeners(events =>
events.BeforeQuery.Handler = "delete this.lastQuery;"
)


Thanks Again.

Daniil
Jan 25, 2013, 2:48 PM
Good. Can we mark the thread closed?

OriCoder
Jan 25, 2013, 2:52 PM
Yes, Close this one off anything else will be in a different issue and i'll open new threads