I am adding GridView rows dynamically as follows that works fine:
C#:
private void SetInitialRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);
//Store the DataTable in ViewState
ViewState["CurrentTable"] = dt;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
private void AddNewRowToGrid()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i )
{
//extract the TextBox values
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i 1;
dtCurrentTable.Rows[i - 1]["Column1"] = box1.Text;
dtCurrentTable.Rows[i - 1]["Column2"] = box2.Text;
dtCurrentTable.Rows[i - 1]["Column3"] = box3.Text;
rowIndex ;
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
Gridview1.DataSource = dtCurrentTable;
Gridview1.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
//Set Previous Data on Postbacks
SetPreviousData();
}
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i )
{
TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
if (Session["val"] != null)
{
List<string> aLst = (List<string>)Session["val"];
foreach (var item in aLst)
{
Label lbl1 = (Label)Gridview1.Rows[rowIndex].Cells[3].FindControl("lblCount");
lbl1.Text = (10 - item.Length " characters remain").ToString();
}
}
box1.Text = dt.Rows[i]["Column1"].ToString();
box2.Text = dt.Rows[i]["Column2"].ToString();
box3.Text = dt.Rows[i]["Column3"].ToString();
rowIndex ;
}
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
SetInitialRow();
}
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
AddNewRowToGrid();
}
ASP.NET:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("table[id*=Gridview1] input[id*=TextBox1]").keyup(function () {
var length = parseInt($(this).attr("maxlength"));
$(this).next(".count").html(length - $(this).val().length " characters remain");
var val = $("table[id*=Gridview1] input[id*=TextBox1]").val();
debugger;
$.ajax({
type: "POST",
url: "/Default16.aspx/GetListofString",
data: JSON.stringify({ name: val }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (values) {
$.each(values, function (i, value) {
//alert(value);
$(this).next(".count").html(length - value.length " characters remain");
});
}
});
})
})
</script>
<div>
<asp:gridview ID="Gridview1" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" MaxLength="10"></asp:TextBox>
<%--<span >10 characters remain</span>--%>
<asp:Label ID="lblCount" runat="server" CssClass="font-sm count" Text="10 characters remain"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row"
onclick="ButtonAdd_Click" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:gridview>
</div>
This is really pretty basic and worked. Now my requirement is to count word limit for the text boxes in the GridView. I already did it with jQuery
which again works as expected. The thing is I want to keep the state of the word count when a user adds a new row to the GridView which is done using server side code.
In the above image, you can see when the word limit is supposed to be 0 in the first row, adding the second row gets the first text box word limit to 10 again (But that should be 0 as there is nothing left to write).
I was planning to use Ajax
call as follows to persist the word limit count but that seems bit confusing:
[System.Web.Services.WebMethod(EnableSession = true)]
public static List<string> GetListofString(string name)
{
List<string> aLst;
if (HttpContext.Current.Session["val"] == null)
{
aLst = new List<string>();
aLst.Add(name);
}
else
{
aLst = (List<string>)HttpContext.Current.Session["val"];
aLst.Add(name);
}
return aLst;
}
Is there any better way that I can make it work? It should show the word count as well persist the word count on adding new rows.
CodePudding user response:
Ok, so the event for GV when wanting to set color of a box, do some formatting, or in this case set a value in the GV?
Use the row data bound event. it will fire any time you bind.
And this quite much suggests you can dump your foreach to set this value.
So, this code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
{
Label lbl1 = (Label)e.Row.FindControl("lblCount");
TextBox Text1 = (TextBox)e.Row.FindControl("TextBox1");
int intTextLen = Text1.Text.Length;
lbl1.Text = (10 - intTextLen).ToString() " characters remain";
}
}
}
I only grabbed the length of textbox 1, but above shows the idea. So, anytime you bind/load the GV, then that value will be set. You don't need a loop, foreach or whatever. It also nice (no foreach), but you on conceptual level only have to deal with the one row at hand.