Hi,
I have a customer request which asks for direct persistence of the RadGrid column order when a column is dropped in place with reordering.
I have tried the server way and client way, but I can only get it to work with a button command, so I think this has something to do with the system only knowing the new column order on postback.
Could you think of a way to make this work directly with Persistance Framework and AJAX?
Regards,
Marc
1 Answer, 1 is accepted
Hello Marc,
Since the RadPersistanceFramework does not offer client-side API to save the state of the supported controls, what you can use is to use the Persisting Grid Settings demo as a base to proceed by making the Save button invisible with style="display:none" and to programmatically click it when the user is resizing columns, the state is saved on the server, e.g
<telerik:RadScriptBlock runat="server">
<script>
function OnColumnSwapped(sender, args) {
$find("<%=Button1.ClientID%>").click();
console.log("Save button clicked");
}
</script>
</telerik:RadScriptBlock>
<asp:Button runat="server" ID="Button1" Text="Save" OnClick="Button1_Click"></asp:Button>
<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="800px" OnNeedDataSource="RadGrid1_NeedDataSource">
<ClientSettings ClientEvents-OnColumnSwapped="OnColumnResized"></ClientSettings>
...Implement the saving for the client events you'd like to cover - https://www.telerik.com/products/aspnet-ajax/documentation/controls/grid/client-side-programming/events/clientevents-class-members.
protected void Button1_Click(object sender, EventArgs e)
{
string user = UserSelection.SelectedValue;
InfoImage.Visible = true;
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.SaveState();
StatusLabel.Text = "Settings for " + user + " saved successfully!";
}After that you can restore the saved settings it in the pageLoad event, e.g.
<script>
function pageLoadHandler() {
$find("<%=Button2.ClientID%>").click(); //click the Load button when the page loads
Sys.Application.remove_load(pageLoadHandler);
}
Sys.Application.add_load(pageLoadHandler);
</script>A similar approach is discussed in the following forum thread: https://www.telerik.com/forums/column-display-persist#3818649. You can also check this video: https://www.youtube.com/watch?v=FYfgpTvDtBA.
Regards,
Vasko
Progress Telerik
My first problem is that the
ClientEvents-OnColumnSwappedevent never seems to fire.
Hi Marc,
If the event doesn't fire, it most likely means the ReorderColumnsOnClient property is not set, you will need to change it:
<ClientSettings AllowColumnsReorder="true" ReorderColumnsOnClient="true">Regards,
Vasko
Progress Telerik
Hi Vasko,
I am kinda lost here, I have the following code pieces from your demo's:
<telerik:RadPersistenceManager ID="RadPersistenceManager1" runat="server"><PersistenceSettings>
<telerik:PersistenceSetting ControlID="dtgProducts" />
</PersistenceSettings>
</telerik:RadPersistenceManager>
A Radgrid with:
<ClientSettings AllowDragToGroup="False" ReorderColumnsOnClient="true" AllowColumnsReorder="true" ColumnsReorderMethod="Reorder">
<ClientEvents OnColumnSwapped="OnColumnSwapped" />
<Resizing AllowColumnResize="false"></Resizing>
</ClientSettings>
The JS function:
<telerik:RadCodeBlock runat="server">
<script type="text/javascript">
function OnColumnSwapped(sender, args) {
$("<%=Button1.ClientID%>").click();
console.log("Save button clicked");
}
</script>
</telerik:RadCodeBlock>
The dummy button:
<telerik:RadButton ID="Button1" runat="server" Text="SAVE" OnClick="Button1_Click" />
The CodeBehind:
Protected Sub Button1_Click(sender As Object, e As EventArgs)
RadPersistenceManager1.StorageProviderKey = HttpContext.Current.User.Identity.Name.ToString()
RadPersistenceManager1.SaveState()
lbl_r.Text = "state saved"
End Sub
When I swap some columns, the JS seems to fire ("Save button clicked is appearing on the console"), but the server code is never executed because there is no Persistence file created in App_Code.
I have tried this with and without AJAXManager on the grid, both do not work.
Any idea what could cause this behavior?
Thanks,
Marc
Hello,
When a column is reordered, save immediately by handling the grid’s client-side swap event and triggering a hidden server button. This gives you direct persistence without requiring a visible Save action.
<telerik:RadGrid ID="RadGrid1" runat="server" OnNeedDataSource="RadGrid1_NeedDataSource">
<ClientSettings AllowDragToGroup="False" AllowColumnsReorder="True" ReorderColumnsOnClient="true">
<ClientEvents OnColumnSwapped="onColumnSwapped" />
</ClientSettings>
</telerik:RadGrid>
<telerik:RadButton runat="server" ID="SaveButton" OnClick="SaveButton_Click" Style="display:none;" />function onColumnSwapped(sender, args) {
let saveButton = $find("<%= SaveButton.ClientID %>");
if (saveButton) {
setTimeout(function () {
saveButton.click();
}, 0);
}
}
protected void SaveButton_Click(object sender, EventArgs e)
{
string user = GetUserKey();
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.SaveState();
}To restore correctly on refresh, load persisted state early in Page_Init (first request), not from a client startup script after render. This ensures the grid applies the saved column order before it is built on the page.
protected void Page_Init(object sender, EventArgs e)
{
RadPersistenceManager1.StorageProvider = new SessionStorageProvider();
if (!IsPostBack)
{
string user = GetUserKey();
if (!string.IsNullOrEmpty(user) && Session[user] != null)
{
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.LoadState();
}
}
}After moving restore logic to Page_Init, a load button click is no longer required for automatic page reload behavior. Keep manual load logic only if you want an explicit “Load Settings” action in the UI.
protected void LoadButton_Click(object sender, EventArgs e)
{
string user = GetUserKey();
if (!string.IsNullOrEmpty(user) && Session[user] != null)
{
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.LoadState();
RadGrid1.Rebind();
}
}I have prepared the below sample implementation for you to try:
<telerik:RadPersistenceManager ID="RadPersistenceManager1" runat="server">
<PersistenceSettings>
<telerik:PersistenceSetting ControlID="RadGrid1" />
</PersistenceSettings>
</telerik:RadPersistenceManager>
<telerik:RadAjaxManager ID="RadAjaxManager" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="SaveButton">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
<telerik:AjaxSetting AjaxControlID="LoadButton">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
<telerik:AjaxSetting AjaxControlID="RadGrid1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="800px" OnNeedDataSource="RadGrid1_NeedDataSource">
<MasterTableView AutoGenerateColumns="False" DataKeyNames="OrderID">
<Columns>
<telerik:GridBoundColumn DataField="OrderID" DataType="System.Int32"
FilterControlAltText="Filter OrderID column" HeaderText="OrderID"
ReadOnly="True" SortExpression="OrderID" UniqueName="OrderID">
</telerik:GridBoundColumn>
<telerik:GridDateTimeColumn DataField="OrderDate" DataType="System.DateTime"
FilterControlAltText="Filter OrderDate column" HeaderText="OrderDate"
SortExpression="OrderDate" UniqueName="OrderDate">
</telerik:GridDateTimeColumn>
<telerik:GridNumericColumn DataField="Freight" DataType="System.Decimal"
FilterControlAltText="Filter Freight column" HeaderText="Freight"
SortExpression="Freight" UniqueName="Freight">
</telerik:GridNumericColumn>
<telerik:GridBoundColumn DataField="ShipName"
FilterControlAltText="Filter ShipName column" HeaderText="ShipName"
SortExpression="ShipName" UniqueName="ShipName">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="ShipCountry"
FilterControlAltText="Filter ShipCountry column" HeaderText="ShipCountry"
SortExpression="ShipCountry" UniqueName="ShipCountry">
</telerik:GridBoundColumn>
</Columns>
</MasterTableView>
<ClientSettings AllowDragToGroup="False" AllowColumnsReorder="True" ReorderColumnsOnClient="true">
<Resizing AllowColumnResize="true"></Resizing>
<ClientEvents OnColumnSwapped="onColumnSwapped" />
</ClientSettings>
</telerik:RadGrid>
<telerik:RadButton runat="server" ID="SaveButton" Text="Save" OnClick="SaveButton_Click" Style="display: none;" />
<telerik:RadButton runat="server" ID="LoadButton" Text="Load" OnClick="LoadButton_Click" Style="display: none;" />
function onColumnSwapped(sender, args) {
let saveButton = $find("<%= SaveButton.ClientID %>");
if (saveButton) {
setTimeout(function () {
saveButton.click();
}, 0);
}
}
function loadState() {
let loadButton = $find("<%= LoadButton.ClientID %>");
if (saveButton) {
setTimeout(function () {
LoadButton.click();
}, 0);
}
}
protected void Page_Init(object sender, EventArgs e)
{
RadPersistenceManager1.StorageProvider = new SessionStorageProvider();
if (!IsPostBack)
{
string user = GetUserKey();
if (!string.IsNullOrEmpty(user) && Session[user] != null)
{
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.LoadState();
}
}
}
protected void SaveButton_Click(object sender, EventArgs e)
{
string user = GetUserKey();
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.SaveState();
}
protected void LoadButton_Click(object sender, EventArgs e)
{
string user = GetUserKey();
if (!string.IsNullOrEmpty(user) && Session[user] != null)
{
SessionStorageProvider.StorageProviderKey = user;
RadPersistenceManager1.LoadState();
RadGrid1.Rebind();
}
}
private string GetUserKey()
{
return "currentUser";
}
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
(sender as RadGrid).DataSource = OrdersTable();
}
private DataTable OrdersTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("OrderID", typeof(int)));
dt.Columns.Add(new DataColumn("OrderDate", typeof(DateTime)));
dt.Columns.Add(new DataColumn("Freight", typeof(double)));
dt.Columns.Add(new DataColumn("ShipName", typeof(string)));
dt.Columns.Add(new DataColumn("ShipCountry", typeof(string)));
dt.PrimaryKey = new DataColumn[] { dt.Columns["OrderID"] };
for (int i = 0; i < 10; i++)
{
int index = i + 1;
DataRow row = dt.NewRow();
row["OrderID"] = index;
row["OrderDate"] = DateTime.Now.Date.AddDays(index);
row["Freight"] = index * 0.01;
row["ShipName"] = "Name " + index;
row["ShipCountry"] = "Country " + index;
dt.Rows.Add(row);
}
return dt;
}
public class SessionStorageProvider : IStateStorageProvider
{
private System.Web.SessionState.HttpSessionState session = HttpContext.Current.Session;
static string storageKey;
public static string StorageProviderKey
{
set { storageKey = value; }
}
public void SaveStateToStorage(string key, string serializedState)
{
session[storageKey] = serializedState;
}
public string LoadStateFromStorage(string key)
{
return session[storageKey] as string;
}
}
Give it a try and let me know if it works for your case.
Regards,
Vasko
Progress Telerik