Hi Fabricio, here is a standalone simplified example. There are two things I need to get working here:
1. Show/hide "Update Status" button based on the grid selection (if no records are selected the button stays hidden, once at least one record is selected it should appear)
2. When the transfer status is updated for selected records StatusEditor -> Edit, and the form disappears. I need the new status to be shown for all the affected records in the grid, without reloading the page.
Please note - my sample below has client status db update functionality commented out and it includes the editable cells functionality you helped me with.
Test.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="EXTTestCases.Test" %>
<%@ Register Src="StatusEditor.ascx" TagName="StatusEditor" TagPrefix="uc2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript">
var template = 'color:{0};';
var change = function (value, meta) {
meta.style = Ext.String.format(template, (value > 0) ? "green" : "red");
return value;
};
var pctChange = function (value, meta) {
meta.style = Ext.String.format(template, (value > 0) ? "green" : "red");
return value + "%";
};
var statusRenderer = function (value) {
var r = App.StoreCombo.getById(value);
if (Ext.isEmpty(r)) {
return "";
}
return r.data.Name;
};
var highlightEditable = function () {
document.querySelectorAll(".editable-cell").forEach(function (el) {
el.classList.add("editable-cell-highlight");
});
};
var dimEditable = function () {
document.querySelectorAll(".editable-cell").forEach(function (el) {
el.classList.remove("editable-cell-highlight");
});
};
</script>
<style type="text/css">
.editable-cell {
}
.editable-cell-highlight {
background-color: #f9ffd77f;
}
</style>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<ext:ResourceManager runat="server" DisableViewState="false" />
<ext:XScript ID="XSCRIPT1" runat="server">
<script>
var MultiClientX = {
statusedit: function (selection) {
this.open();
},
getSelection: function () {
var sel = Ext.encode(#{ GridPanel1 }.getRowsValues({ selectedOnly: true }));
if (sel != null) {
return sel;
}
},
refresh: function () {
try {
#{ GridPanel1 }.getView().refresh();
}
catch (err) {
alert(err);
}
}
};
</script>
</ext:XScript>
<ext:Store ID="StoreCombo" runat="server">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
<ext:GridPanel ID="GridPanel1" runat="server" Title="Editable GridPanel" Width="1000">
<CustomConfig>
<ext:ConfigItem Name="editingDisabled" Value="true" Mode="Raw" />
</CustomConfig>
<Store>
<ext:Store ID="Store1" runat="server">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" Type="Int" />
<ext:ModelField Name="Name" />
<ext:ModelField Name="Number" />
<ext:ModelField Name="Number_Overlay" />
<ext:ModelField Name="Name_Overlay" />
<ext:ModelField Name="Note" />
<ext:ModelField Name="TransferStatus_ID" Type="Int" />
</Fields>
</ext:Model>
</Model>
<Listeners>
<DataChanged Handler="if (App.btnSaveChanges) App.btnSaveChanges.setDisabled(!this.isDirty())" />
</Listeners>
</ext:Store>
</Store>
<ColumnModel runat="server">
<Columns>
<ext:Column runat="server" Text="Name" DataIndex="Name" Flex="1">
</ext:Column>
<ext:Column runat="server" Text="Number" DataIndex="Number" Flex="1">
</ext:Column>
<ext:Column runat="server" Text="Name New" DataIndex="Name_Overlay" Flex="1" TdCls="editable-cell">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:Column runat="server" Text="Number New" DataIndex="Number_Overlay" Flex="1" TdCls="editable-cell">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:Column runat="server" Text="Note" DataIndex="Note" Flex="1" TdCls="editable-cell">
<Editor>
<ext:TextField runat="server" />
</Editor>
</ext:Column>
<ext:Column runat="server" DataIndex="TransferStatus_ID" Text="Status" Width="200" TdCls="editable-cell">
<Renderer Fn="statusRenderer"></Renderer>
<Editor>
<ext:ComboBox ID="cbStatuses" StoreID="StoreCombo" DisplayField="Name" ValueField="ID" runat="server" />
</Editor>
</ext:Column>
</Columns>
</ColumnModel>
<TopBar>
<ext:Toolbar runat="server">
<Items>
<ext:Button runat="server" Text="Update Status">
<Listeners>
<Click Handler="MultiClientX.statusedit(Ext.encode(#{GridPanel1}.getRowsValues({selectedOnly:true})));" />
</Listeners>
</ext:Button>
<ext:Button
ID="btnEditGrid"
runat="server"
Text="Edit Grid"
OnDirectClick="EditGridButton_Click" />
<ext:Button
ID="btnSaveChanges"
runat="server"
Text="Save Changes"
AutoLoadingState="true"
Disabled="true"
Hidden="true">
<DirectEvents>
<Click OnEvent="SaveChangesButton_Click">
<ExtraParams>
<ext:Parameter Name="data_changes" Value="function() { return App.Store1.getChangedData(); }" Mode="Raw" />
</ExtraParams>
</Click>
</DirectEvents>
<Listeners>
<Hide Fn="dimEditable" />
<Show Fn="highlightEditable" />
</Listeners>
</ext:Button>
<ext:Button
ID="btnCancelEdit"
runat="server"
Text="Cancel"
AutoLoadingState="true"
OnDirectClick="CancelEditButton_Click"
Hidden="true" />
</Items>
</ext:Toolbar>
</TopBar>
<Listeners>
<BeforeEdit Handler="if (App.btnSaveChanges.hidden === true) return false" />
</Listeners>
<SelectionModel>
<ext:CheckboxSelectionModel runat="server" Mode="Multi" />
</SelectionModel>
<View>
<ext:GridView runat="server"></ext:GridView>
</View>
<Plugins>
<ext:CellEditing runat="server" ClicksToEdit="1" />
</Plugins>
</ext:GridPanel>
<uc2:StatusEditor ID="StatusEditor1" runat="server" />
</form>
</body>
</html>
Test.aspx.cs
using System;
using System.Collections.Generic;
using Ext.Net;
namespace EXTTestCases
{
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
{
this.BindData();
}
}
private void BindData()
{
this.StoreCombo.DataSource = TransferStatus.GetAll();
this.StoreCombo.DataBind();
this.Store1.DataSource = Client.GetAll();
this.Store1.DataBind();
}
protected void SaveChangesButton_Click(object sender, DirectEventArgs e)
{
var changes = e.ExtraParams["data_changes"];
if (changes != null)
{
X.Toast("Got these records to update in database: " + changes);
ChangeRecords<Client> clients = new StoreDataHandler(changes).BatchObjectData<Client>();
foreach (Client updated in clients.Updated)
{
Store1.GetById(updated.ID).Commit();
}
}
else
{
X.Toast("No records to update.");
}
this.btnEditGrid.Show();
this.btnSaveChanges.Hide();
this.btnCancelEdit.Hide();
}
protected void EditGridButton_Click(object sender, DirectEventArgs e)
{
this.btnEditGrid.Hide();
this.btnSaveChanges.Show();
this.btnCancelEdit.Show();
}
protected void CancelEditButton_Click(object sender, DirectEventArgs e)
{
BindData();
this.btnEditGrid.Show();
this.btnSaveChanges.Hide();
this.btnCancelEdit.Hide();
}
}
public partial class TransferStatus
{
public int ID { get; set; }
public string Name { get; set; }
public static List<TransferStatus> GetAll()
{
return new List<TransferStatus>
{
new TransferStatus {ID = 1, Name = "Pending"},
new TransferStatus {ID = 4, Name = "Accepted"},
new TransferStatus {ID = 7, Name = "Rejected"}
};
}
}
public partial class Client
{
public int ID { get; set; }
public string Name { get; set; }
public string Number { get; set; }
public string Name_Overlay { get; set; }
public string Number_Overlay { get; set; }
public int TransferStatus_ID { get; set; }
public string Note { get; set; }
public static List<Client> GetAll()
{
List<Client> clntList = new List<Client>();
clntList.Add(new Client() { ID = 10, Name = "Client1", Number = "01", Note = "Client 1 Note", Number_Overlay = "01", Name_Overlay = "Client1", TransferStatus_ID = 1 });
clntList.Add(new Client() { ID = 11, Name = "Client2", Number = "02", Note = "Client 2 Note", Number_Overlay = "02", Name_Overlay = "Client2", TransferStatus_ID = 7 });
return clntList;
}
}
}
StatusEditor.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="StatusEditor.ascx.cs" Inherits="EXTTestCases.StatusEditor" %>
<ext:XScript runat="server" ID="StatusEditXScript">
<script>
Ext.applyIf(MultiClientX, {
open: function () {
win = #{ StatusWinDetails };
win.show();
},
save: function () {
try
{
var sel = this.getSelection();
if (sel != null)
{
alert(sel);
MultiClientX.Edit(sel);
}
#{ StatusWinDetails }.hide();
this.refresh();
}
catch (err)
{
alert(err);
}
}
});
</script>
</ext:XScript>
<ext:Window
ID="StatusWinDetails"
runat="server"
Title="Update Transfer Status"
Icon="Group"
Width="400"
Height="400"
Modal="true"
Hidden="true"
Layout="CenterLayout">
<Items>
<ext:FormPanel ID="StatusPanel" runat="server">
<Items>
<ext:ComboBox
ID="TransferStatus"
runat="server"
FieldLabel="Set Transfer Status To"
AllowBlank="false"
DisplayField="Name"
ValueField="ID"
TypeAhead="true"
QueryMode="Local"
Name="TransferStatus"
ForceSelection="true"
TriggerAction="All"
EmptyText="Select Transfer Status..." Width="200" LabelAlign="Top">
<Store>
<ext:Store ID="StoreCombo" runat="server">
<Model>
<ext:Model runat="server" IDProperty="ID">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
</ext:ComboBox>
</Items>
</ext:FormPanel>
</Items>
<Buttons>
<ext:Button ID="btnSave" runat="server" Text="Save" Icon="Disk">
<Listeners>
<Click Handler="MultiClientX.save();" />
</Listeners>
</ext:Button>
<ext:Button ID="btnCancel" runat="server" Text="Cancel" Icon="Cancel">
<Listeners>
<Click Handler="this.up('window').hide();" />
</Listeners>
</ext:Button>
</Buttons>
</ext:Window>
StatusEditor.ascx.cs
using System;
using Ext.Net;
using System.Xml;
namespace EXTTestCases
{
public partial class StatusEditor : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
this.StoreCombo.DataSource = EXTTestCases.TransferStatus.GetAll();
}
[DirectMethod(Namespace = "MultiClientX", IDMode = DirectMethodProxyIDMode.None)]
public void Edit(object _json)
{
Ext.Net.ListItem newStat = this.TransferStatus.SelectedItem;
System.Xml.XmlNode xml = JSON.DeserializeXmlNode("{records:{record:" + _json + "}}");
foreach (XmlNode row in xml.SelectNodes("records/record"))
{
string ID = row.SelectSingleNode("ID").InnerXml;
//this is where transfer status for each selected client is saved to db.
//Data.Client tmp = new Data.Client();
//tmp.updateClientProperty(ID, "TransferStatus_ID", newStat.Value);
}
}
}
}