PDA

View Full Version : [CLOSED] [Razor] Paging without Store Proxy



machinableed
May 25, 2012, 6:14 AM
I have a form panel which submits the form to a controller method via a direct event and loads the store for a grid panel


pn.Add(Html.X().FormPanel()
.Region(Region.North)
.Collapsible(true)
.Title("Enter Search Criteria")
.BodyPadding(4)
.Layout(LayoutType.Column)
.MaxHeight(600)
.ID("pnlSearchForm")
.Buttons(buttons =>
{
buttons.Add(Html.X().Button()
.DirectEvents(directEvents =>
{
directEvents.Click.ExtraParams.Add(new Parameter("start","0", ParameterMode.Raw));
directEvents.Click.ExtraParams.Add(new Parameter("limit", "30", ParameterMode.Raw));
directEvents.Click.Url = "/Services/Search";
directEvents.Click.Success = "#{store1}.loadData(result.extraParamsResponse.data ); #{pnlSearchForm}.collapse(true)";
})
.Text("Search"));
}


The controller method (/Services/Search) basically returns an AjaxResult as follows as I was told StoreResult would not work in this case:

AjaxResult r = new AjaxResult()
{
ExtraParamsResponse =
{
new Parameter()
{
Name = "data",
Value = JSON.Serialize(gridResults),
Mode = ParameterMode.Raw
}
}
};

return r;


My issue is that I now need to add paging to the gridpanel and when I add a paging toolbar to the gridpanel it doesn't appear. I suspect this is because the AjaxResult I'm returning and loading directly into the store has no idea what the total count is and/or there is other data that the store expects for paging that are not available? How can I go about paging in my case?

Daniil
May 25, 2012, 10:15 AM
Hi,

Paging appears to be working correctly with the loadData method.

Example

<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.NET v2 Example</title>

<script type="text/javascript">
var loadData = function () {
App.GridPanel1.getStore().loadData([
["test1"],
["test2"],
["test3"],
["test4"]
]);
};
</script>
</head>
<body>
<ext:ResourceManager runat="server" />
<ext:GridPanel ID="GridPanel1" runat="server" AutoHeight="true">
<Store>
<ext:Store runat="server" PageSize="3">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="test" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="Test" DataIndex="test" />
</Columns>
</ColumnModel>
<BottomBar>
<ext:PagingToolbar runat="server" />
</BottomBar>
</ext:GridPanel>

<ext:Button runat="server" Text="loadData">
<Listeners>
<Click Fn="loadData" />
</Listeners>
</ext:Button>
</body>
</html>


My issue is that I now need to add paging to the gridpanel and when I add a paging toolbar to the gridpanel it doesn't appear.

Please provide more details. A sample to reproduce would be best.

Vladimir
May 25, 2012, 11:36 AM
Please note that Proxy is required for remote paging only
Local paging can work without proxy

machinableed
May 26, 2012, 10:57 AM
Ideally I need a way to do remote paging but I can't get it to work at all at this stage. I'm assuming this is because I'm just returning the data itself to be loaded but the total count is not returned? How can I go about paging in this scenario?

Example code below:

View:



@{
ViewBag.Title = "Service Manager";
Layout = "";
}
<html>
<head>
<title>Service Manager</title>
<link rel="stylesheet" type="text/css" href="/resources/css/main.css" />
<link rel="stylesheet" type="text/css" href="/resources/css/customgrid.css" />
<script type="text/javascript" src="/resources/js/site.js"></script>
<style type="text/css">
.search-item {
font : normal 11px tahoma, arial, helvetica, sans-serif;
padding : 3px 10px 3px 10px;
border : 1px solid #fff;
border-bottom : 1px solid #eeeeee;
white-space : normal;
color : #555;
}

.search-item h3 {
display : block;
font : inherit;
font-weight : bold;
color : #222;
margin :0px;
}

.search-item h3 span {
float : right;
font-weight : normal;
margin : 0 0 5px 5px;
width : 100px;
display : block;
clear : none;
}

p { width: 650px; }

.ext-ie .x-form-text { position : static !important; }
</style>
<script type="text/javascript">
var getValues = function (tree) {
var msg = [],
selNodes = tree.getChecked();

Ext.each(selNodes, function (node) {
msg.push(node.data.id);
});

return msg.join(",");
};

var getText = function (tree) {
var msg = [],
selNodes = tree.getChecked();
msg.push("[");

Ext.each(selNodes, function (node) {
if (msg.length > 1) {
msg.push(",");
}

msg.push(node.data.text);
});

msg.push("]");
return msg.join("");
};

var syncValue = function (value) {
var tree = this.component;

var ids = value.split(",");
tree.setChecked({ ids: ids, silent: true });

tree.getSelectionModel().clearSelections();
Ext.each(ids, function (id) {
var node = tree.store.getNodeById(id);

if (node) {
tree.getSelectionModel().select(node, true);
}
}, this);
};



var onCommand = function (column, command, record, recordIndex, cellIndex) {
//Ext.Msg.alert('Command', 'Command = ' + command + '<br/>' + 'Column = ' + column.grid.columns[cellIndex].dataIndex);
//Ext.Msg.alert('Command', 'Command = ' + command + '<br/>' + 'Row = ' + record.data.ServiceId);

if (command == 'ViewParentProduct') {
parent.Nextgen.ServiceManager.addTab({ title: 'View Product Instance', url: '/Products/ViewProduct/' + record.data.ParentProductInstanceId });
}
else {
parent.Nextgen.ServiceManager.addTab({ title: 'Edit Service Details', url: '/Services/Details/' + record.data.ServiceId });
}
};
</script>
</head>
<body>
<div>
@using (Html.BeginForm("Search", "Services", FormMethod.Post, new { id = "form1" }))
{

@(Html.X().ResourceManager()
.Theme(Theme.Gray)
)


@(Html.X().Viewport()
.Layout(LayoutType.Fit)
.Items(pn =>
{
pn.Add(Html.X().FormPanel()
.Region(Region.North)
.Collapsible(true)
.Title("Enter Search Criteria")
.BodyPadding(4)
.Layout(LayoutType.Column)
.MaxHeight(100)
.ID("pnlSearchForm")
.Buttons(buttons =>
{
buttons.Add(Html.X().Button()
.DirectEvents(directEvents =>
{
//directEvents.Click.
directEvents.Click.Url = "/Services/Clear";
})
.Text("Clear"));

buttons.Add(Html.X().Button()
.DirectEvents(directEvents =>
{
directEvents.Click.ExtraParams.Add(new Parameter("start","0", ParameterMode.Raw));
directEvents.Click.ExtraParams.Add(new Parameter("limit", "30", ParameterMode.Raw));
directEvents.Click.Url = "/Examples/Search";
directEvents.Click.Success = "#{store1}.loadData(result.extraParamsResponse.data );";
})
.Text("Search"));

}));




pn.Add(Html.X().GridPanel()
.ID("gridPanel1")
.Region(Region.South)
.Margins("4 0 0 0")
.Cls("x-grid-custom")
//.AutoHeight(true)
.Title("Search Results")
.Scroll(ScrollMode.Both)
.View(vw => vw.Add(Html.X().GridView()
.StripeRows(true)
.TrackOver(true)))
.ColumnModel(columnModel =>
{
columnModel.Columns.Add(Html.X().Column()
.Text("Service Id")
.DataIndex("ServiceId")
.Width(70));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Reference")
.Width(200)
.DataIndex("ServiceReference"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Alias")
.Width(200)
.DataIndex("ServiceAlias"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Name")
.Width(200)
.DataIndex("ServiceName"));
columnModel.Columns.Add(Html.X().Column()
.Text("Customer Description")
.Width(220)
.DataIndex("CustomerDescription"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Status")
.Width(85)
.DataIndex("ServiceStatus"));
columnModel.Columns.Add(Html.X().Column()
.Text("Parent Id")
.Width(85)
.DataIndex("ParentProductInstanceId"));
columnModel.Columns.Add(Html.X().Column()
.Text("Ordered Date")
.Width(85)
.DataIndex("OrderedDate"));
columnModel.Columns.Add(Html.X().Column()
.Text("Implemented Date")
.Width(120)
.DataIndex("ImplementedDate"));
columnModel.Columns.Add(Html.X().Column()
.Text("Contract Expiry Date")
.DataIndex("ContractExpiryDate")
.Width(130));
columnModel.Columns.Add(Html.X().Column()
.Align(Alignment.Center)
.Width(30)
.Commands(commands =>
{
commands.Add(new ImageCommand()
{
Icon = Icon.NoteEdit,
CommandName = "Edit",
ToolTip =
{
Text = "View/Edit Service Details"
}
});

})
.Listeners(listeners =>
{
listeners.Command.Fn = "onCommand";
}));
columnModel.Columns.Add(Html.X().Column()
.Align(Alignment.Center)
.Width(30)
.Commands(commands =>
{
commands.Add(new ImageCommand()
{
Icon = Icon.Outline,
CommandName = "ViewParentProduct",
ToolTip =
{
Text = "View Product Instance"
}
});
})
.Listeners(listeners =>
{
listeners.Command.Fn = "onCommand";
}));
})
.Store(store => store.Add(Html.X().Store()
.ID("store1")
.PageSize(10)
.Model(model => model.Add(Html.X().Model()
.IDProperty("ServiceId")
.Fields(modelFields =>
{
modelFields.Add(Html.X().ModelField().Name("ServiceId"));
modelFields.Add(Html.X().ModelField().Name("ServiceReference"));
modelFields.Add(Html.X().ModelField().Name("ServiceAlias"));
modelFields.Add(Html.X().ModelField().Name("ServiceName"));
modelFields.Add(Html.X().ModelField().Name("CustomerDescription"));
modelFields.Add(Html.X().ModelField().Name("ServiceStatus"));
modelFields.Add(Html.X().ModelField().Name("ParentProductInstanceId"));
modelFields.Add(Html.X().ModelField().Name("OrderedDate"));
modelFields.Add(Html.X().ModelField().Name("ImplementedDate"));
modelFields.Add(Html.X().ModelField().Name("ContractExpiryDate"));

})
))
))
.BottomBar(bar => bar.Add(Html.X().PagingToolbar()
.DisplayInfo(true)
.DisplayMsg("Displaying services {0} - {1} of {2}")
))

);

})
)
}
</div>
</body>
</html>


Controller:


public class TestGridRowVO
{
public int ParentProductInstanceId { get; set; }
public string CustomerSignedDate { get; set; }
public string ImplementedDate { get; set; }
public string ContractExpiryDate { get; set; }
public int ServiceId { get; set; }
public string ServiceReference { get; set; }
public string ServiceAlias { get; set; }
public string ServiceName { get; set; }
public string CustomerDescription { get; set; }
public CommercialStatus CommercialStatus { get; set; }
public string CommercialStatusText { get; set; }
public string CommercialStatusValue { get; set; }
public ServiceStatus ServiceStatus { get; set; }
public string ServiceStatusText { get; set; }
public string ServiceStatusValue { get; set; }

public TestGridRowVO()
{

}
}
public AjaxResult Search(int start, int limit, string sort, string filter)
{
List<TestGridRowVO> gridResults = new List<TestGridRowVO>();
for (int i = 0; i < 20; i++)
{
TestGridRowVO rowVO = new TestGridRowVO();
rowVO.ServiceId = i;
rowVO.ServiceName = "Service Name " + i.ToString();
rowVO.ServiceAlias = "Service Alias " + i.ToString();
rowVO.ServiceReference = "Service Reference " + i.ToString();
rowVO.ServiceStatus = ServiceStatus.Operational;
rowVO.ParentProductInstanceId = i;
rowVO.ImplementedDate = DateTime.Now.ToString();
rowVO.CustomerSignedDate = DateTime.Now.ToString();
rowVO.ContractExpiryDate = DateTime.Now.ToString();
rowVO.CustomerDescription = "Customer DEsription " + i.ToString();

gridResults.Add(rowVO);

}

AjaxResult r = new AjaxResult()
{
ExtraParamsResponse =
{
new Parameter()
{
Name = "data",
Value = JSON.Serialize(gridResults),
Mode = ParameterMode.Raw
}
}
};


return r;
}

Daniil
May 28, 2012, 1:15 PM
Generally, remote paging without a Store Proxy is not supported.

You could try to update PagingToolbar manually, please see its updateInfo method.
http://docs.sencha.com/ext-js/4-1/source/Paging.html#Ext-toolbar-Paging

But it can be complicated and, actually, looks as a trick.

Why don't you want to implement it by a common way - configure the Store with AjaxProxy and make a load request with searching parameters?

machinableed
May 30, 2012, 3:03 AM
Why don't you want to implement it by a common way - configure the Store with AjaxProxy and make a load request with searching parameters?

Is there an example that covers this? My issue is that I have FormPanel which has to submit a range of filter values as per the example in this thread:
http://forums.ext.net/showthread.php?18158-CLOSED-How-to-access-reload-store-in-razor-views-controller

Daniil
May 30, 2012, 12:47 PM
Well, I would implement it like this.

FormPanel

<ext:FormPanel ID="FormPanel1" runat="server">
<Items>
<ext:TextField ID="TextField1" runat="server" Text="TextField1" />
<ext:TextField ID="TextField2" runat="server" Text="TextField2" />
</Items>
</ext:FormPanel>


Store

<ext:Store runat="server" PageSize="3">
<Model>
<ext:Model runat="server">
<Fields>
<ext:ModelField Name="test" />
</Fields>
</ext:Model>
</Model>
<Proxy>
<ext:AjaxProxy Url="/Test/GetDataForRemotePaging">
<Reader>
<ext:JsonReader Root="data" TotalProperty="total" />
</Reader>
</ext:AjaxProxy>
</Proxy>
<Parameters>
<ext:StoreParameter
Name="jsonFilters"
Value="#{FormPanel1}.getForm().getFieldValues()"
Mode="Raw"
Encode="true" />
</Parameters>
</ext:Store>

Controller Action

public ActionResult GetDataForRemotePaging(..., string jsonFilters)
{
Dictionary<string, string> filters = JSON.Deserialize<Dictionary<string, string>>(jsonFilters);
string filter1 = filters["TextField1"];
string filter2 = filters["TextField2"];
...
}

machinableed
Jun 04, 2012, 2:01 AM
I've managed to isolate the problem that I'm having - the grid with ajax proxy seems to load and display the paging toolbar as expected when using the following code:



@{
ViewBag.Title = "Service Manager";
Layout = "";
}
<html>
<head>
<title>Service Manager</title>
<link rel="stylesheet" type="text/css" href="/resources/css/main.css" />
<link rel="stylesheet" type="text/css" href="/resources/css/customgrid.css" />
<script type="text/javascript" src="/resources/js/site.js"></script>
<style type="text/css">
.search-item {
font : normal 11px tahoma, arial, helvetica, sans-serif;
padding : 3px 10px 3px 10px;
border : 1px solid #fff;
border-bottom : 1px solid #eeeeee;
white-space : normal;
color : #555;
}

.search-item h3 {
display : block;
font : inherit;
font-weight : bold;
color : #222;
margin :0px;
}

.search-item h3 span {
float : right;
font-weight : normal;
margin : 0 0 5px 5px;
width : 100px;
display : block;
clear : none;
}

p { width: 650px; }

.ext-ie .x-form-text { position : static !important; }
</style>
</head>
<body>
<div>
@using (Html.BeginForm("Search", "Services", FormMethod.Post, new { id = "form1" }))
{

@(Html.X().ResourceManager()
.Theme(Theme.Gray)
)


@(Html.X().Viewport()
.Layout(LayoutType.Fit)
.Items(pn =>
{
//pn.Add(Html.X().FormPanel()
// .Region(Region.North)
// .Collapsible(true)
// .Title("Enter Search Criteria")
// .BodyPadding(4)
// .Layout(LayoutType.Column)
// .MaxHeight(100)
// .ID("pnlSearchForm"));




pn.Add(Html.X().GridPanel()
.ID("gridPanel1")
.Region(Region.South)
.Margins("4 0 0 0")
.Cls("x-grid-custom")
//.AutoHeight(true)
.Title("Search Results")
.Scroll(ScrollMode.Both)
.View(vw => vw.Add(Html.X().GridView()
.StripeRows(true)
.TrackOver(true)))
.ColumnModel(columnModel =>
{
columnModel.Columns.Add(Html.X().Column()
.Text("Service Id")
.DataIndex("ServiceId")
.Width(70));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Reference")
.Width(200)
.DataIndex("ServiceReference"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Alias")
.Width(200)
.DataIndex("ServiceAlias"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Name")
.Width(200)
.DataIndex("ServiceName"));
columnModel.Columns.Add(Html.X().Column()
.Text("Customer Description")
.Width(220)
.DataIndex("CustomerDescription"));
columnModel.Columns.Add(Html.X().Column()
.Text("Service Status")
.Width(85)
.DataIndex("ServiceStatus"));
columnModel.Columns.Add(Html.X().Column()
.Text("Parent Id")
.Width(85)
.DataIndex("ParentProductInstanceId"));
columnModel.Columns.Add(Html.X().Column()
.Text("Ordered Date")
.Width(85)
.DataIndex("OrderedDate"));
columnModel.Columns.Add(Html.X().Column()
.Text("Implemented Date")
.Width(120)
.DataIndex("ImplementedDate"));
columnModel.Columns.Add(Html.X().Column()
.Text("Contract Expiry Date")
.DataIndex("ContractExpiryDate")
.Width(130));
columnModel.Columns.Add(Html.X().Column()
.Align(Alignment.Center)
.Width(30)
.Commands(commands =>
{
commands.Add(new ImageCommand()
{
Icon = Icon.NoteEdit,
CommandName = "Edit",
ToolTip =
{
Text = "View/Edit Service Details"
}
});

})
.Listeners(listeners =>
{
// listeners.Command.Fn = "onCommand";
}));
columnModel.Columns.Add(Html.X().Column()
.Align(Alignment.Center)
.Width(30)
.Commands(commands =>
{
commands.Add(new ImageCommand()
{
Icon = Icon.Outline,
CommandName = "ViewParentProduct",
ToolTip =
{
Text = "View Product Instance"
}
});
})
.Listeners(listeners =>
{
// listeners.Command.Fn = "onCommand";
}));
})
.Store(store => store.Add(Html.X().Store()
//.ID("store1")
.RemotePaging(true)
.PageSize(20)
.Proxy(proxy => proxy.Add(Html.X().AjaxProxy()
.Url("/Examples/Search/")
.Reader(reader => reader.Add(Html.X().JsonReader()
.Root("data")
.TotalProperty("total")
))
))
.Parameters(param => param.Add(Html.X().StoreParameter()
.Name("JSONFilters")
//.Value("#{pnlSearchForm}.getForm().getFieldValues()")
.Value("")
.Mode(ParameterMode.Raw)
.Encode(true)
))
.Model(model => model.Add(Html.X().Model()
.IDProperty("ServiceId")
.Fields(modelFields =>
{
modelFields.Add(Html.X().ModelField().Name("ServiceId"));
modelFields.Add(Html.X().ModelField().Name("ServiceReference"));
modelFields.Add(Html.X().ModelField().Name("ServiceAlias"));
modelFields.Add(Html.X().ModelField().Name("ServiceName"));
modelFields.Add(Html.X().ModelField().Name("CustomerDescription"));
modelFields.Add(Html.X().ModelField().Name("ServiceStatus"));
modelFields.Add(Html.X().ModelField().Name("ParentProductInstanceId"));
modelFields.Add(Html.X().ModelField().Name("OrderedDate"));
modelFields.Add(Html.X().ModelField().Name("ImplementedDate"));
modelFields.Add(Html.X().ModelField().Name("ContractExpiryDate"));

})
))
))
.BottomBar(bar => bar.Add(Html.X().PagingToolbar()
.DisplayInfo(true)
.DisplayMsg("Displaying services {0} - {1} of {2}")
))

);

})
)
}
</div>
</body>
</html>


with controller method:


public StoreResult Search(int start, int limit, string sort)
{
List<TestGridRowVO> gridResults = new List<TestGridRowVO>();
for (int i = 0; i < 20; i++)
{
TestGridRowVO rowVO = new TestGridRowVO();
rowVO.ServiceId = i;
rowVO.ServiceName = "Service Name " + i.ToString();
rowVO.ServiceAlias = "Service Alias " + i.ToString();
rowVO.ServiceReference = "Service Reference " + i.ToString();
rowVO.ServiceStatus = ServiceStatus.Operational;
rowVO.ParentProductInstanceId = i;
rowVO.ImplementedDate = DateTime.Now.ToString();
rowVO.CustomerSignedDate = DateTime.Now.ToString();
rowVO.ContractExpiryDate = DateTime.Now.ToString();
rowVO.CustomerDescription = "Customer DEsription " + i.ToString();

gridResults.Add(rowVO);

}

StoreResult r = new StoreResult();
{
r.Data = gridResults;
r.Total = 100;
};


return r;
}


The rest is the same as earlier in the thread. Now the problem is if I uncomment the FormPanel in the cshtml file, the paging toolbar disappears. I've got no idea why - as you can see the form panel is empty so I can't see how it could be breaking the paging on the grid panel?

machinableed
Jun 04, 2012, 2:52 AM
Apologies - you can close this thread.

It seems the problem was a layout one that was hiding the paging toolbar from view - changing the viewport to BorderLayout and a few other minor alterations and all is working as expected.