PDA

View Full Version : [CLOSED] GridPanel editing



bbros
Dec 23, 2020, 2:07 PM
Hi, could you please provide us an example with a GridPanel and edit plugin?
I would like to have a GridPanel with "inline" editing feature, and direct event.

The equivalent of this one
https://examples5.ext.net/#/GridPanel/Editable/Editor_with_DirectMethod/

Thank you!

fabricio.murta
Dec 23, 2020, 5:25 PM
Hello @bbros!

Thanks for pointing a v5 example that does what you wanted. We have ported it to Examples Explorer 7 and it will be eventually available live at https://examples.ext.net/.

For now, it is available at the public GitHub Ext.NET Examples 7 project (https://github.com/extnet/examples.ext.net). You can browse it now just to check the code or clone the project and build it locally. Could prove useful as a testbed to draw test cases for issues or questions you encounter!

- Page code (current state at the time of the writing of this response) (https://github.com/extnet/examples.ext.net/tree/55eeb8719981f67492425735b0eb8ef2a68d13a1/src/Pages/samples/gridpanel/editable/editor_with_directmethod).
- GitHub project (dev branch, where the page is now and new development comes first) (https://github.com/extnet/examples.ext.net/tree/dev)

Hope this helps!

bbros
Jan 03, 2021, 1:48 PM
Thank you very much, it helped me a lot.

My main target is to create a Custom Grid control; I was able to do it in WebForms with previous version using direct events.

I'm trying to create a GridPanel dynamically in codebehind.
I would add the 'edit' script as well.
...but in App.direct is null and I get:

Uncaught TypeError: fireFn.apply is not a function

How to fit in my shoes:

Start a new project using Ext.NET Razor template
Change _Layout.cshtml
Add a new empty Razor Page called GridPanelEditorInCodebehind

_Layout.cshtml (the body part)


<body>
<ext-viewport layout="Border">
<items>
<ext-partial name="_Header" />
<ext-partial name="_Sidebar" />
<ext-panel layout="Fit" region="Center" bodyPadding="18">
<items>
<ext-section name="Main" />
</items>
</ext-panel>
</items>
</ext-viewport>
@RenderBody()
</body>

GridPanelEditorInCodebehind.cshtml

@page
@model BBros.Samples.Pages.GridPanelEditorInCodebehindMod el
@{
}
<ext-section target="Main">
<ext-container id="MainContainer" region="Center" scrollable="true" paddingAsString="30 20 30 50" model="Model.MainContainer">
</ext-container>
</ext-section>

GridPanelEditorInCodebehind.cshtml.cs

using System;
using System.Collections.Generic;
using Ext.Net;
using Ext.Net.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace BBros.Samples.Pages
{
public class GridPanelEditorInCodebehindModel : PageModel
{
public GridPanel MainContainer { get; set; }

public void OnGet()
{
this.X().AddScript("var edit = function (editor, e) {if (!(e.value === e.originalValue || (Ext.isDate(e.value) && Ext.Date.isEqual(e.value, e.originalValue))))" +
"{App.direct.Edit(e.field, e.originalValue, e.value);}};");
MainContainer = GridInCodebehind();
}

private GridPanel GridInCodebehind()
{

var grd = new GridPanel()
{
Id = "GridInCodebehind",
Title = "my Super Grid",
Anchor = "100%"
};

var df = new List<DataField>();
df.Add(new DataField() { Name = "id", Type = DataFieldType.Int });
df.Add(new DataField() { Name = "name", Type = DataFieldType.String });

var m = new Model()
{
IdProperty = "GridDataModel",
Fields = df
};

var s = new Store
{
Id = "GridDataStore"
};
s.ModelValue = m;

s.Data = GridData();

grd.Store = s;

var c = new List<Column>();
c.Add(new Column() { DataIndex = "id", Text = "ID", ColumnWidth = 50 });
c.Add(new Column() { DataIndex = "name", Text = "Name", Flex = 1, Editor = new TextField() });
grd.Columns = c;

var toolbar = new Toolbar() { Dock = Dock.Top };
toolbar.Items.Add(new Button() { IconCls = "x-md md-icon-apps" });
grd.DockedItems = toolbar;

var p = new CellEditingPlugin();
p.Listeners.Edit.Fn = "edit";

var plugins = new List<AbstractPlugin>();
plugins.Add(p);
grd.Plugins = plugins;

return grd;
}

public List<object> GridData()
{
DateTime today = DateTime.Today;
return new List<object>
{
new { ID = 1, Name = "3m Co", Price = 71.72, Change = 0.02, PctChange = 0.03, LastChange = today },
new { ID = 2, Name = "Alcoa Inc", Price = 29.01, Change = 0.42, PctChange = 1.47, LastChange = today },
new { ID = 3, Name = "Altria Group Inc", Price = 83.81, Change = 0.28, PctChange = 0.34, LastChange = today },
new { ID = 4, Name = "American Express Company", Price = 52.55, Change = 0.01, PctChange = 0.02, LastChange = today },
new { ID = 5, Name = "American International Group, Inc.", Price = 64.13, Change = 0.31, PctChange = 0.49, LastChange = today },
new { ID = 6, Name = "AT&T Inc.", Price = 31.61, Change = -0.48, PctChange = -1.54, LastChange = today },
new { ID = 7, Name = "Boeing Co.", Price = 75.43, Change = 0.53, PctChange = 0.71, LastChange = today },
new { ID = 8, Name = "Caterpillar Inc.", Price = 67.27, Change = 0.92, PctChange = 1.39, LastChange = today },
new { ID = 9, Name = "Citigroup, Inc.", Price = 49.37, Change = 0.02, PctChange = 0.04, LastChange = today },
new { ID = 10, Name = "E.I. du Pont de Nemours and Company", Price = 40.48, Change = 0.51, PctChange = 1.28, LastChange = today },
new { ID = 11, Name = "Exxon Mobil Corp", Price = 68.1, Change = -0.43, PctChange = -0.64, LastChange = today },
new { ID = 12, Name = "General Electric Company", Price = 34.14, Change = -0.08, PctChange = -0.23, LastChange = today },
new { ID = 13, Name = "General Motors Corporation", Price = 30.27, Change = 1.09, PctChange = 3.74, LastChange = today },
new { ID = 14, Name = "Hewlett-Packard Co.", Price = 36.53, Change = -0.03, PctChange = -0.08, LastChange = today },
new { ID = 15, Name = "Honeywell Intl Inc", Price = 38.77, Change = 0.05, PctChange = 0.13, LastChange = today },
new { ID = 16, Name = "Intel Corporation", Price = 19.88, Change = 0.31, PctChange = 1.58, LastChange = today },
new { ID = 17, Name = "International Business Machines", Price = 81.41, Change = 0.44, PctChange = 0.54, LastChange = today },
new { ID = 18, Name = "Johnson & Johnson", Price = 64.72, Change = 0.06, PctChange = 0.09, LastChange = today },
new { ID = 19, Name = "JP Morgan & Chase & Co", Price = 45.73, Change = 0.07, PctChange = 0.15, LastChange = today },
new { ID = 20, Name = "McDonald\"s Corporation", Price = 36.76, Change = 0.86, PctChange = 2.40, LastChange = today },
new { ID = 21, Name = "Merck & Co., Inc.", Price = 40.96, Change = 0.41, PctChange = 1.01, LastChange = today },
new { ID = 22, Name = "Microsoft Corporation", Price = 25.84, Change = 0.14, PctChange = 0.54, LastChange = today },
new { ID = 23, Name = "Pfizer Inc", Price = 27.96, Change = 0.4, PctChange = 1.45, LastChange = today },
new { ID = 24, Name = "The Coca-Cola Company", Price = 45.07, Change = 0.26, PctChange = 0.58, LastChange = today },
new { ID = 25, Name = "The Home Depot, Inc.", Price = 34.64, Change = 0.35, PctChange = 1.02, LastChange = today },
new { ID = 26, Name = "The Procter & Gamble Company", Price = 61.91, Change = 0.01, PctChange = 0.02, LastChange = today },
new { ID = 27, Name = "United Technologies Corporation", Price = 63.26, Change = 0.55, PctChange = 0.88, LastChange = today },
new { ID = 28, Name = "Verizon Communications", Price = 35.57, Change = 0.39, PctChange = 1.11, LastChange = today },
new { ID = 29, Name = "Wal-Mart Stores, Inc.", Price = 45.45, Change = 0.73, PctChange = 1.63, LastChange = today }
};
}

[Direct]
public IActionResult OnPostEdit(string field, string oldValue, string newValue)
{
string message = "<h2>Edit Record</h2><hr/><b>Property:</b> {0}<br /><b>Field:</b> {1}<br /><b>Old Value:</b> {2}<br /><b>New Value:</b> {3}";

// Send Message...
this.X().Toast(string.Format(message, 1, field, oldValue, newValue));

this.X().AddScript("App.GridInCodebehind.getStore().commitChanges()");

return this.Direct();
}
}
}


Consider that I'm new to C# and MVC even if I worked for several years with vb, webforms and Ext.NET from v2 to v5.
Any suggestion is much appreciated.

Do you know where am I wrong?
Thank you very much!

fabricio.murta
Jan 05, 2021, 7:52 AM
Hello @bbros!


1. Start a new project using Ext.NET Razor template

I believe here you mean "Ext.NET Classic Web Application" template from the VSIX Extension, right? By the looks of the next steps it seems safe to assume so. You may be interested in looking these two articles to discern between Razor Pages and Razor Views:

- Introduction to Razor Pages (https://docs.microsoft.com/en-us/aspnet/core/razor-pages/)
- Part 3, adding a view to an ASP.NET Core MVC app (https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-view)

Basically we have two file hierarchies (.cshtm + .cshtml.cs under Pages/ root folder and .cshtml under Views/ plus .cs under Controllers/ folders) and two file syntaxes (Tag Helpers with <ext-component /> syntax and HTML Helpers with Html.X().Component() syntax like in Ext.NET MVC (https://mvc5.ext.net/)). By what I see here, we're talking about Pages/ structure over Tag Helpers syntax. Just highlighting this because a combination over all these 4 alternatives is possible with Ext.NET 7.


I would add the 'edit' script as well.
...but in App.direct is null and I get:


Uncaught TypeError: fireFn.apply is not a function

You are just missing the [DirectModel] attribute decorating the GridPanelEditorInCodebehindModel class in GridPanelEditorInCodebehind.cshtml.cs. Just add it right above the class declaration (between lines 9 and 10), and Ext.direct should be there.

At this point part of your problems would be solved. You now can call App.direct.Edit(). But then again, you won't be able to do it.

Something interesting arises as you can use p.Listeners.Edit.Fn where the edit reference, client-side would be available during code build but won't be available when the event is actually fired. The context is lost.

Long story short, in GridPanelEditorInCodebehind.cshtml.cs:16 would become:



this.X().AddScript("window.edit = function (editor, e) {if (!(e.value === e.originalValue || (Ext.isDate(e.value) && Ext.Date.isEqual(e.value, e.originalValue))))" +


Then GridPanelEditorInCodebehind.cshtml.cs:61 ("reversed" line number is pure coincidence!)



p.Listeners.Edit.Handler = "edit.apply(this, arguments);";


Other solutions include just inlining the edit function in the Handler (it is not used anywhere else, is it?), defining the 'edit' method as a custom config of the component, or just adding the edit script to the page itself (only then p.Listeners.Fn should work). Well, you can also delay creating the grid (call a direct method to create the grid as soon as the page is redered), but it does seem like something that would provide a good user experience, as multiple requests to load the page can only slow things down.

With these changes, I could get the whole code to work here, you done a great job wioth the test case, thanks!

Well, hope this helps! Let us know if something was left unanswered. This is actually starting to delve off the initial topic (of an example with an editable grid, this is getting into the "editable grid from code behind", so maybe if you have any follow-up on this matter, in case the provided example fulfilled the initial request, it'd be best to start up a new thread.

bbros
Jan 05, 2021, 2:42 PM
I am moved by the joy!

Thank you very much, your explanation is very clear and I'm starting to figure out how to move in the new environment.
You can consider this post closed.

Thank you again

fabricio.murta
Jan 07, 2021, 6:08 AM
Thanks for the feedback, glad it helped!