PDA

View Full Version : Mark GridPanel Store Dirty From Code Behind



aliabdulla
Aug 21, 2020, 6:12 PM
Dears,

I would like to set all Store items for GridPanel as Dirty from code behind:



Function LoadTheMonth() As Boolean

Dim strSQl As String = clsSQL.getTheMonthList()
Dim ds As DataSet = clsDB.getData(strSQl)

If Not ds Is Nothing Then
If ds.Tables(0).Rows.Count > 0 Then
Dim myStore = ddlTheMonth.GetStore

myStore.DataSource = ds.Tables(0)
myStore.DataBind()
End If
End If
Return True

End Function


How to achieve that?

fabricio.murta
Sep 08, 2020, 10:45 PM
Hello @aliabdulla!

I am afraid you'd need to add a client-script code to mark all records as dirty as soon as the grid is defined.

The good news though is that you can keep your code at server-side with this:



myStore.AddScript("App.Store1.each(function(rec) { rec.dirty = true; })");


It does not really matter to add this call after or before lines 10-11 in your code (before or after data binding), because the script will be queued by default to be called -after- the store is defined in the client-side logic; but you probably want it to be within the test between lines 7-12, and of course, after the myStore variable is defined at line 8.

Hope this helps!

aliabdulla
Sep 29, 2020, 5:42 PM
Hello,

The code does not worked for me, and here the test case:



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

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

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
this.Store1.DataSource = this.Jobs;
this.Store1.DataBind();
this.Store1.AddScript("App.Store1.each(function(rec) { rec.dirty = true; })");
}

private List<Job> Jobs
{
get
{
List<Job> jobs = new List<Job>();

for (int i = 1; i <= 50; i++)
{
jobs.Add(new Job(
i,
"Task" + i.ToString(),
DateTime.Today.AddDays(i),
DateTime.Today.AddDays(i + i),
(i%3 == 0)));
}

return jobs;
}
}

public class Job
{
public Job(int id, string name, DateTime start, DateTime end, bool completed)
{
this.ID = id;
this.Name = name;
this.Start = start;
this.End = end;
this.Completed = completed;
}

public int ID { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public bool Completed { get; set; }
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>GridPanel with FitLayout - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:Window
ID="Window1"
runat="server"
Collapsible="true"
Maximizable="true"
Icon="Lorry"
Title="Job List"
Width="600"
Height="300"
X="50"
Y="50"
Layout="Fit">
<Items>
<ext:GridPanel
runat="server"
Header="false"
Border="false">
<Store>
<ext:Store ID="Store1" runat="server" PageSize="10">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
<ext:ModelField Name="Start" Type="Date" />
<ext:ModelField Name="End" Type="Date" />
<ext:ModelField Name="Completed" Type="Boolean" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server"
Text="ID"
Width="40"
Sortable="true"
DataIndex="ID">
<Filter>
<ext:NumberFilter />
</Filter>
</ext:Column>
<ext:Column runat="server"
Text="Job Name"
Sortable="true"
DataIndex="Name"
Flex="1">
<Filter>
<ext:StringFilter />
</Filter>
</ext:Column>
<ext:DateColumn runat="server"
Text="Start"
Width="120"
Sortable="true"
DataIndex="Start"
Format="yyyy-MM-dd">
<Filter>
<ext:DateFilter>
<DatePickerOptions runat="server" TodayText="Now" />
</ext:DateFilter>
</Filter>
</ext:DateColumn>
<ext:DateColumn runat="server"
Text="End"
Width="120"
Sortable="true"
DataIndex="End"
Format="yyyy-MM-dd">
<Filter>
<ext:DateFilter>
<DatePickerOptions runat="server" TodayText="Now" />
</ext:DateFilter>
</Filter>
</ext:DateColumn>
<ext:Column runat="server"
Text="Completed"
Width="80"
Sortable="true"
DataIndex="Completed">
<Renderer Handler="return (value) ? 'Yes':'No';" />
<Filter>
<ext:BooleanFilter />
</Filter>
</ext:Column>
</Columns>
</ColumnModel>
<View>
<ext:GridView runat="server" LoadMask="false" />
</View>
<Plugins>
<ext:GridFilters runat="server" />
</Plugins>
<BottomBar>
<ext:PagingToolbar
runat="server"
DisplayInfo="true"
DisplayMsg="Displaying Jobs {0} - {1} of {2}"
/>
</BottomBar>
</ext:GridPanel>
</Items>
</ext:Window>
</form>
</body>
</html>


Kindly, advice.

fabricio.murta
Sep 29, 2020, 10:14 PM
Hello @aliabdulla!

How are you checking the store's dirty status? You sample shows me the store is indeed dirty on load. Change your paging toolbar to add a button to inquire store dirty status like this:



<ext:PagingToolbar
runat="server"
DisplayInfo="true"
DisplayMsg="Displaying Jobs {0} - {1} of {2}">
<Items>
<ext:Button runat="server" Icon="Cog" Handler="Ext.toast('Store dirty status: ' + App.Store1.isDirty());" />
</Items>
</ext:PagingToolbar>


It says "true" to me on load. Maybe you are talking about a different dirty status, could you elaborate on that?

Notice store's isDirty() method is specific to Ext.NET so you're not going to see that from Sencha. In case you are relying in something else to check if the store is dirty, let us know and we can work from that (if using the mentioned method doesn't suit you).

Hope this helps!

aliabdulla
Sep 30, 2020, 7:41 AM
Dear,

I want the user to see that all cells are dirty like this:

25445

How to achieve that?

fabricio.murta
Sep 30, 2020, 7:03 PM
Hello @aliabdulla!

The best way to achieve this is by using the own grid logic to ensure it works the way you need it.

This is how marking the grid like that works:

- the initial value is X
- you set the value to anything different than X
- the grid marks it as dirty and places the little red tip on the cell
- that specific cell then has the ability to be reject()'ed or commit()'ed.

How does that work? Internally, Ext JS keeps two layers of data. One with the original data you bound on load, and a second that is filled as values are changed. Whenever the value changes back to the original values (or is committed), the cell will show as unchanged.

This means that, in order to get all the cells marked as changed, it is needed to not only run a set() call to all individual record+field pairs (effectively every cell in the grid), but also the value must be different.

Knowing that, I can think on a couple alternatives.

initial/unchanged data is fake defaults

You can initialize the grid with values unlikely chosen by the user (empty strings, very very old dates). Then run thru every cell setting the new values you want in a similar code to the one you set every record as dirty (but now, via rec.set("field", "value") for every single field/value in the grid).

In this case, if you add any means to "undo" changes to the grid (reject changes), the user will be seeing all those default values and the grid showing as "not edited" (no "red tips" in the cells).

current actual data, but then make the programmatic changes

This could be useful if you are pre-filling a grid of changes to the user, probably not your case. In this case, just fill with the initial values then set up the changed fields (so potentially some cells won't read as dirty if they match original values). The field set up would be teh same as the alternative above. Just initial data changes. "Undoing" the changes will show the initial (and perhaps also valid) values to the user.

the dirty marks are used like a form validation

If you want to use the dirty status as a form validation, that is, the cell shows the red tip until the user enters valid data therein, then I believe it is a bad idea. You should instead write some logic to actually "Paint" the individual cells in DOM level, and then another logic to validate the records. So you call the validation on load and apply (say) a CSS class to the cell, "painting it as invalid" where it applies. Then as values are changed, have an edit event check if the "painting" should be removed. Then in some circumstances (like grid refreshes) the initial validation might run to ensure all invalid cells are still reflecting their state.

bottomline

So any of the three approaches above fits your scenario? Let us know if some do, and if you're still lost on how to proceed with them, we can provide more clues to what best suits your scenario. Unfortunately it is not that simple to just mark them as dirty without actually changing the data, as recurrent logic in the tree will just wipe out the markings.

Hope this helps!