PDA

View Full Version : [CLOSED] GridPanel Batch Update does not send data



chrish
Jan 21, 2013, 5:27 PM
I am using Ext.NET 2.1.1.18233 with Visual Studio 2010 and ASP.NET MVC 4. I am attempting to submit batch changes from a grid panel using a simple button. I have tried various examples and cannot get the grid panel to submit changed records to an MVC controller method. The POST data indicates that an empty JSON object is submitted. The relevant code samples including my model and grid panel are shown below. I have used the following example, and a forum thread for guidance:

http://mvc.ext.net/#/GridPanel_Update/Batch/

Much code is omitted for brevity. The grid panel view is complete.

I have ensured that each model instance passed to the view has a unique ID. The GridPanel is populating with the correct records. I can edit the records using the row editing plugin without a problem. The problem is that when I click a save button, the page submits a request to the server, but the request has an empty encoded JSON object for the data parameter. Nothing is passed to the server that can be parsed or interpreted to determine the number and content of changed, updated, or deleted record(s).

Model


[Model(Name="ProfileStepModel", ClientIdProperty="PhantomId")]
[JsonWriter(Encode=true, Root="data")]
public class StationProfileStepModel
{

[ModelField(IDProperty = true, UseNull=true)]
[Field(Ignore=true)]
public int? ID { get; set; }

[ModelField(Ignore=true)]
public string PhantomId { get; set; }

public string Type { get; set; }

public int Time { get; set; }

public int Channel1PID { get; set; }

public int Channel2PID { get; set; }

public double Channel1SetPoint { get; set; }

public double Channel2SetPoint { get; set; }

public bool Channel1GuaranteedSoak { get; set; }

public bool Channel2GuaranteedSoak { get; set; }

public int LoopFrom { get; set; }

public int LoopTo { get; set; }

public int LoopRepeatCount { get; set; }

}

Controller
NOTE: The controller method is called; however, handler indicates there are no updated, changed, or deleted records.


[HttpPost]
public ActionResult Steps(int? profileId, StoreDataHandler handler)
{
if (handler.IsBatch)
{
ChangeRecords<StationProfileStepModel> steps =
handler.BatchObjectData<StationProfileStepModel>();
var store = this.GetCmp<Store>("ProfileStepStore");
}
}


View
NOTE: I am passing a collection of model items in the view's controller function as a parameter to the View function


@model IEnumerable<StationProfileStepModel>

@(Html.X().GridPanel()
.ID("ProfileEditorSteps")
.Title("Profile Steps")
.Height(500)
.ColumnWidth(0.80)
.TopBar(Html.X().Toolbar()
.Items(

Html.X().Button()
.Text("Insert Step")
.IconAlign(IconAlign.Top)
.Icon(Icon.ChartLineAdd),

Html.X().Button()
.Text("Remove Step")
.IconAlign(IconAlign.Top)
.Icon(Icon.ChartLineDelete),

Html.X().Button()
.Text("Clear Profile")
.IconAlign(IconAlign.Top)
.Icon(Icon.Bin)
.OnClientClick("Editor.onClearProfileSteps"),

Html.X().Button()
.Text("Validate")
.IconAlign(IconAlign.Top)
.Icon(Icon.Tick)

)
)
.Plugins(
Html.X().RowEditing()
.AutoCancel(false)
.ClicksToMoveEditor(1)

)
.Store(Html.X().StoreForModel()
.ID("ProfileStepStore")
)
.ColumnModel(

Html.X().RowNumbererColumn()
.Width(35),

Html.X().Column().Text("Type")
.DataIndex("Type")
.Editor(
Html.X().ComboBox()
.Items(
Html.X().ListItem().Text("Ramp/Soak"),
Html.X().ListItem().Text("Loop"),
Html.X().ListItem().Text("End")
)
),

Html.X().Column().Text("Time")
.DataIndex("Time")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(false)
.AllowDecimals(true)
),

Html.X().Column().Text("CH 1 SP")
.DataIndex("Channel1SetPoint")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(true)
),

Html.X().Column().Text("CH 2 SP")
.DataIndex("Channel2SetPoint")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(true)
),

Html.X().CheckColumn().Text("CH 1 G. Soak")
.DataIndex("Channel1GuaranteedSoak")
.Editable(true),

Html.X().CheckColumn().Text("CH 2 G. Soak")
.DataIndex("Channel2GuaranteedSoak")
.Editable(true),

Html.X().Column().Text("CH 1. PID")
.DataIndex("Channel1PID")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("CH 2. PID")
.DataIndex("Channel2PID")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Loop From")
.DataIndex("LoopFrom")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Loop To")
.DataIndex("LoopTo")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Repeat")
.DataIndex("LoopRepeatCount")
.Renderer("Editor.onRenderStep")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
)

)

)


Save Button


Html.X().Button()
.IconAlign(IconAlign.Top)
.Icon(Icon.Disk)
.Text("Save")
.DirectEvents(e => {
e.Click.Url = Url.Action("Steps");
e.Click.ExtraParams.Add(new Parameter
{
Name = "data",
Mode = ParameterMode.Raw,
Encode = true,
Value = "Ext.getCmp('ProfileEditorSteps').store.getChangedD ata({skipIdForNewRecords: false})"
});
})

Vladimir
Jan 21, 2013, 5:53 PM
I cannot run your sample, you did not provide renderers and bound model data
Please post view and controller code are not required any changes from our side

chrish
Jan 21, 2013, 6:08 PM
Here is a more complete example; hopefully this is enough. The renderers were not relevant to the code sample. I forgot to remove them. In my actual code I am returning an ExtPartialViewResult and loading through a ComponentLoader; however, it does not matter if I populate the view with either that method or the method below. I cannot post or attach my actual code due to project confidentiality concerns, but I can provide as many samples as needed to help resolve this issue.

Controllers/ProfilesController.cs


public class ProfilesController : Controller
{

public ActionResult Edit()
{
var records = new List<StationProfileStepModel>();
for (int i = 0; i < 10; i++)
records.Add(new StationProfileStepModel { ID = i, Time = 30 });

return View(records);
}

[HttpPost]
public ActionResult Steps(int? profileId, StoreDataHandler handler)
{
if (handler.IsBatch)
{
ChangeRecords<StationProfileStepModel> steps =
handler.BatchObjectData<StationProfileStepModel>();
var store = this.GetCmp<Store>("ProfileStepStore");
// NOTE: As explained in the original thread, the handler
// instance exists, along with steps; however, steps contains
// no changed, updated, or deleted records.
}
}

}


Views/Profiles/Edit.aspx


@model IEnumerable<StationProfileStepModel>

@(Html.X().GridPanel()
.ID("ProfileEditorSteps")
.Title("Profile Steps")
.Height(500)
.ColumnWidth(0.80)
.TopBar(Html.X().Toolbar()
.Items(

Html.X().Button()
.IconAlign(IconAlign.Top)
.Icon(Icon.Disk)
.Text("Save")
.DirectEvents(e => {
e.Click.Url = Url.Action("Steps");
e.Click.ExtraParams.Add(new Parameter
{
Name = "data",
Mode = ParameterMode.Raw,
Encode = true,
Value = "Ext.getCmp('ProfileEditorSteps').store.getChangedD ata({skipIdForNewRecords: false})"
});
})

)
)
.Plugins(
Html.X().RowEditing()
.AutoCancel(false)
.ClicksToMoveEditor(1)

)
.Store(Html.X().StoreForModel()
.ID("ProfileStepStore")
)
.ColumnModel(

Html.X().RowNumbererColumn()
.Width(35),

Html.X().Column().Text("Type")
.DataIndex("Type")
.Editor(
Html.X().ComboBox()
.Items(
Html.X().ListItem().Text("Ramp/Soak"),
Html.X().ListItem().Text("Loop"),
Html.X().ListItem().Text("End")
)
),

Html.X().Column().Text("Time")
.DataIndex("Time")
.Editor(
Html.X().NumberField()
.AllowBlank(false)
.AllowDecimals(true)
),

Html.X().Column().Text("CH 1 SP")
.DataIndex("Channel1SetPoint")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(true)
),

Html.X().Column().Text("CH 2 SP")
.DataIndex("Channel2SetPoint")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(true)
),

Html.X().CheckColumn().Text("CH 1 G. Soak")
.DataIndex("Channel1GuaranteedSoak")
.Editable(true),

Html.X().CheckColumn().Text("CH 2 G. Soak")
.DataIndex("Channel2GuaranteedSoak")
.Editable(true),

Html.X().Column().Text("CH 1. PID")
.DataIndex("Channel1PID")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("CH 2. PID")
.DataIndex("Channel2PID")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Loop From")
.DataIndex("LoopFrom")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Loop To")
.DataIndex("LoopTo")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
),

Html.X().Column().Text("Repeat")
.DataIndex("LoopRepeatCount")
.Editor(
Html.X().NumberField()
.AllowBlank(true)
.AllowDecimals(false)
)

))

Vladimir
Jan 21, 2013, 7:29 PM
I tested with latest version (http://svn.ext.net/premium/trunk) and all works fine for me (i see updated records in StoreDataHandler)
Just one minor issue that 'skipIdForNewRecords' must be replaced by 'skipIdForPhantomRecords'

What version do you use? Can you update from trunk and retest?

chrish
Jan 21, 2013, 7:47 PM
According to Visual Studio the assembly version is 2.1.1.18233. I will retrieve, compile, and link the version in the repository as soon as I get access. For whatever reason my credentials do not work.

EDIT: I have e-mailed support with a credential reset request as of 4:00 PM EST.

Daniil
Jan 22, 2013, 5:22 AM
We have emailed the SVN credentials. Please check.

chrish
Jan 22, 2013, 2:16 PM
The issue is now resolved after retrieving the current trunk version from the repository, modifying it to compile using ASP.NET MVC 4, and then linking it into my project. The StoreDataHandler now shows updated records in the ChangeRecords instance. Thank you for the assistance!

Daniil
Jan 22, 2013, 2:21 PM
Thank you for confirmation!

shaileshsakaria
Feb 17, 2013, 8:14 AM
Thank you for confirmation!

I am also facing same problem.
but I am not using MVC.

Here is my sample example

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

<%@ Import Namespace="System.Collections.Generic" %>

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

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
}

public class CustomStone
{
public int? Pcs { get; set; }
public decimal? Cts { get; set; }
public long StoneID { get; set; }

public CustomStone()
{
Pcs = 0; Cts = 0; StoneID = 0;
}
}

public class DirectCustomClass
{
public CustomStone cStone { get; set; }
public string DisplayStoneID { get; set; }
public string DoNotUse { get; set; }
}


protected void btnRefersh_Click(object sender, EventArgs e)
{

List<DirectCustomClass> lstStone = new List<DirectCustomClass>();
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x1", cStone = new CustomStone() { StoneID = 1, Pcs = 1, Cts = 2 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x2", cStone = new CustomStone() { StoneID = 2, Pcs = 1, Cts = 9 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x3", cStone = new CustomStone() { StoneID = 3, Pcs = 1, Cts = 8 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x4", cStone = new CustomStone() { StoneID = 4, Pcs = 1, Cts = 7 } });
StoreStone.DataSource = lstStone.ToList();
StoreStone.DataBind();
}

protected void btnSave_Click(object sender, DirectEventArgs e)
{
ChangeRecords<DirectCustomClass> stoneTransferDet = new StoreDataHandler(e.ExtraParams["Stone"]).BatchObjectData<DirectCustomClass>();
foreach (DirectCustomClass dcc in stoneTransferDet.Updated)
{
new MessageBox().Show(new MessageBoxConfig()
{
Title = "Pcs Value",
Message = "New Pcs=" + dcc.cStone.Pcs.Value.ToString(),
Icon = MessageBox.Icon.INFO,
Closable = true,
Buttons = MessageBox.Button.OK
});
//base.ShowMessage(dcc.cStone.Pcs.Value.ToString(), MessageBox.Icon.INFO);
}
}

</script>

<!DOCTYPE html>

<html>
<head id="Head1" runat="server">
<title>Ext.NET Examples</title>

<script>

</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />

<ext:GridPanel ID="GridStone" runat="server" IDMode="Static" Title="Testing Grid" Height="300">
<Store>
<ext:Store ID="StoreStone" runat="server" IDMode="Static">
<Model>
<ext:Model ID="ModelStone" runat="server" IDMode="Static" IDProperty="StoneID" ClientIdProperty="DoNotUse">
<Fields>
<ext:ModelField Name="DisplayStoneID" />
<ext:ModelField Name="cStone" IsComplex="true">
</ext:ModelField>
<ext:ModelField Name="StoneID" ServerMapping="cStone.StoneID" />
<ext:ModelField Name="Pcs" ServerMapping="cStone.Pcs" />
<ext:ModelField Name="Cts" ServerMapping="cStone.Cts" />
<ext:ModelField Name="DoNotUse" />
</Fields>
</ext:Model>
</Model>

</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ID="Column1" DataIndex="StoneID" runat="server" Text="Stone ID">
<Editor>
<ext:TextField ID="txtStoneID" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
<ext:Column ID="Column2" runat="server" Text="Display Stone ID" DataIndex="DisplayStoneID">
<Editor>
<ext:TextField ID="txtDisplayStoneID" runat="server" IDMode="Static" />
</Editor>

</ext:Column>
<ext:Column ID="Column3" DataIndex="Pcs" runat="server" Text="Pcs">
<Editor>
<ext:NumberField ID="txtPCS" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
<ext:Column ID="Column4" DataIndex="Cts" runat="server" Text="Cts">
<Editor>
<ext:NumberField ID="txtCTS" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
</Columns>
</ColumnModel>
<Plugins>
<ext:CellEditing ID="cell1" runat="server" IDMode="Static" />
</Plugins>
</ext:GridPanel>
<ext:Component Width="20" ID="com1" runat="server" />
<ext:Button ID="btnRefersh" Icon="ArrowRefresh" runat="server" IDMode="Static" Text="Refresh">
<DirectEvents>
<Click OnEvent="btnRefersh_Click" />
</DirectEvents>
</ext:Button>
<ext:Button ID="Button2" Icon="DatabaseSave" runat="server" IDMode="Static" Text="Save">
<DirectEvents>
<Click OnEvent="btnSave_Click">
<ExtraParams>
<ext:Parameter Name="Stone" Value="#{StoreStone}.getChangedData({skipIdForNewRecords : true})" Mode="Raw" Encode="true" />
</ExtraParams>
</Click>
</DirectEvents>
</ext:Button>

</form>
</body>
</html>

Daniil
Feb 17, 2013, 12:25 PM
Hi @shaileshsakaria,

Please wrap the code in [CODE] tags, see how to do that here in #3:
More Information Required (http://forums.ext.net/showthread.php?10205)

shaileshsakaria
Feb 18, 2013, 3:07 AM
Here I am not able to get updated data while using IsComplex=true and #{StoreStone}.getChangedData({skipIdForNewRecords : true}) method used.


Runnable Example

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

<%@ Import Namespace="System.Collections.Generic" %>

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

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
}

public class CustomStone
{
public int? Pcs { get; set; }
public decimal? Cts { get; set; }
public long StoneID { get; set; }

public CustomStone()
{
Pcs = 0; Cts = 0; StoneID = 0;
}
}

public class DirectCustomClass
{
public CustomStone cStone { get; set; }
public string DisplayStoneID { get; set; }
public string DoNotUse { get; set; }
}


protected void btnRefersh_Click(object sender, EventArgs e)
{

List<DirectCustomClass> lstStone = new List<DirectCustomClass>();
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x1", cStone = new CustomStone() { StoneID = 1, Pcs = 1, Cts = 2 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x2", cStone = new CustomStone() { StoneID = 2, Pcs = 1, Cts = 9 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x3", cStone = new CustomStone() { StoneID = 3, Pcs = 1, Cts = 8 } });
lstStone.Add(new DirectCustomClass { DisplayStoneID = "x4", cStone = new CustomStone() { StoneID = 4, Pcs = 1, Cts = 7 } });
StoreStone.DataSource = lstStone.ToList();
StoreStone.DataBind();
}

protected void btnSave_Click(object sender, DirectEventArgs e)
{
ChangeRecords<DirectCustomClass> stoneTransferDet = new StoreDataHandler(e.ExtraParams["Stone"]).BatchObjectData<DirectCustomClass>();
foreach (DirectCustomClass dcc in stoneTransferDet.Updated)
{
new MessageBox().Show(new MessageBoxConfig()
{
Title = "Pcs Value",
Message = "New Pcs=" + dcc.cStone.Pcs.Value.ToString(),
Icon = MessageBox.Icon.INFO,
Closable = true,
Buttons = MessageBox.Button.OK
});
//base.ShowMessage(dcc.cStone.Pcs.Value.ToString(), MessageBox.Icon.INFO);
}
}

</script>

<!DOCTYPE html>

<html>
<head id="Head1" runat="server">
<title>Ext.NET Examples</title>

<script>

</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />

<ext:GridPanel ID="GridStone" runat="server" IDMode="Static" Title="Testing Grid" Height="300">
<Store>
<ext:Store ID="StoreStone" runat="server" IDMode="Static">
<Model>
<ext:Model ID="ModelStone" runat="server" IDMode="Static" IDProperty="StoneID" ClientIdProperty="DoNotUse">
<Fields>
<ext:ModelField Name="DisplayStoneID" />
<ext:ModelField Name="cStone" IsComplex="true">
</ext:ModelField>
<ext:ModelField Name="StoneID" ServerMapping="cStone.StoneID" />
<ext:ModelField Name="Pcs" ServerMapping="cStone.Pcs" />
<ext:ModelField Name="Cts" ServerMapping="cStone.Cts" />
<ext:ModelField Name="DoNotUse" />
</Fields>
</ext:Model>
</Model>

</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ID="Column1" DataIndex="StoneID" runat="server" Text="Stone ID">
<Editor>
<ext:TextField ID="txtStoneID" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
<ext:Column ID="Column2" runat="server" Text="Display Stone ID" DataIndex="DisplayStoneID">
<Editor>
<ext:TextField ID="txtDisplayStoneID" runat="server" IDMode="Static" />
</Editor>

</ext:Column>
<ext:Column ID="Column3" DataIndex="Pcs" runat="server" Text="Pcs">
<Editor>
<ext:NumberField ID="txtPCS" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
<ext:Column ID="Column4" DataIndex="Cts" runat="server" Text="Cts">
<Editor>
<ext:NumberField ID="txtCTS" runat="server" IDMode="Static" />
</Editor>
</ext:Column>
</Columns>
</ColumnModel>
<Plugins>
<ext:CellEditing ID="cell1" runat="server" IDMode="Static" />
</Plugins>
</ext:GridPanel>
<ext:Component Width="20" ID="com1" runat="server" />
<ext:Button ID="btnRefersh" Icon="ArrowRefresh" runat="server" IDMode="Static" Text="Refresh">
<DirectEvents>
<Click OnEvent="btnRefersh_Click" />
</DirectEvents>
</ext:Button>
<ext:Button ID="Button2" Icon="DatabaseSave" runat="server" IDMode="Static" Text="Save">
<DirectEvents>
<Click OnEvent="btnSave_Click">
<ExtraParams>
<ext:Parameter Name="Stone" Value="#{StoreStone}.getChangedData({skipIdForNewRecords : true})" Mode="Raw" Encode="true" />
</ExtraParams>
</Click>
</DirectEvents>
</ext:Button>

</form>
</body>
</html>

Daniil
Feb 18, 2013, 3:38 AM
The code sample is not wrapped. Also you should not create a new post.

Please read.


Hi @shaileshsakaria,

Please wrap the code in [CODE] tags, see how to do that here in #3:
More Information Required (http://forums.ext.net/showthread.php?10205)