Add Read more button to view Gridview Description text - c#

I have a Gridview that fetches Description text from the database and once it's over some text limit, I want the Gridview to let users click "Read more" from where they can see the full text without having to navigate to a new url. Thank you in advance.
My Gridview Columns are as follows:
<asp:BoundField DataField="Id" HeaderText="Id" SortExpression="Id" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
<asp:BoundField DataField="Source" HeaderText="Source" SortExpression="Source" />
<asp:BoundField DataField="Message" HeaderText="Message" SortExpression="Message" />
<asp:BoundField DataField="Date" HeaderText="Date" DataFormatString="{0:dd/MM/yyyy}" SortExpression ="Date" />

Add ItemTemplate with a Lable Control and LinkButton as read more in Gridview Like:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label20" runat="server" Text='<%#((string)Eval("ColumnName")).Length<20?Eval("ColumnName"):((string)Eval("ColumnName")).Substring(0,20)+"..." %>' ToolTip='<%#Eval("question") %>' Width="100"></asp:Label>
<asp:LinkButton ID="LinkButton1" runat="server" Visible='<%#SetVisibility(Eval("ColumnName"),20) %>' OnClick="LinkButton1_Click">Read More...</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Here Lable text it will contain only 20 char and link button will show Read More but Lable tooltip contain all characters of that column. On Link Button click we fire an event to show all data in that Label.
protected void LinkButton1_Click(object sender, EventArgs e)
{
//Read More Link Button from Gridview on Click
LinkButton lb = (LinkButton)sender;
GridViewRow row = lb.NamingContainer as GridViewRow;
//Finding the description Text Lable
Label qst = row.FindControl("Label20") as Label;
// Setting Link Button Text
lb.Text = (lb.Text == "Read More...") ? "Hide..." : "Read More...";
//Swaping tooltip value to text and vices versa as Tooltip has all charecters
string temp = qst.Text;
qst.Text = qst.ToolTip;
qst.ToolTip = temp;
}
protected bool SetVisibility(object Desc, int length)
{
return Desc.ToString().Length > length;
}
Hope this will help you to find out your solution.
Updates:
It seems Your Column has null value to handle this you can check for null and then convert :
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label20" runat="server" Text='<%#Eval("ColumnName")==DBNull.Value ? string.Empty :(((string)Eval("ColumnName")).Length<20?Eval("ColumnName"):((string)Eval("ColumnName")).Substring(0,20)+"...") %>' ToolTip='<%#Eval("question") %>' Width="100"></asp:Label>
<asp:LinkButton ID="LinkButton1" runat="server" Visible='<%# Eval("ColumnName")==DBNull.Value ? false :SetVisibility(Eval("ColumnName"),20) %>' OnClick="LinkButton1_Click">Read More...</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>

I would suggest using a linkbutton and binding the message in the ItemTemplate:
<asp:TemplateField HeaderText="Message">
<ItemTemplate>
<%# Bind("Message") %> - <asp:linkbutton id="btnReadMore" runat="server" causesvalidation="false" commandname="readmore" commandargument="<%# Bind("MessageId") %>" />
</ItemTemplate>
</asp:TemplateField>
The logic for the link button can then popup a
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "readmore")
{
Session["messageid"] = e.CommandArgument.ToString();
Response.Redirect("popuppage.aspx?id=" + Session["messageid"].ToString() + "");
}
}
In the popuppage.aspx will be logic to fetch the complete message using the messageid from the Query string.

Related

How to find the HTML input button on gridview row data bound event without adding runat="Server" tag

I have following code in html
<asp:GridView ID="grdFiles" runat="server" AutoGenerateColumns="false" Width="100%" OnRowDataBound="grdFiles_RowDataBound" >
<Columns>
<asp:BoundField DataField="BatchNo" HeaderText="Batch No" />
<asp:BoundField DataField="totalspnumber" HeaderText="Total SP Number" />
<asp:BoundField DataField="VendorName" HeaderText="Vendor Name" />
<asp:BoundField DataField="Location" HeaderText="Location" />
<asp:BoundField DataField="prefix" HeaderText="Prefix" />
<asp:BoundField DataField="dateofexport" HeaderText="Date Of Export" />
<asp:BoundField DataField="ExpiryDate" HeaderText="Expiry Date" />
<asp:TemplateField>
<ItemTemplate>
<input id="downloadButton" fileid="<%# Eval("id") %>" filename="<%# Eval("exportedFileName") %>" type="button" tee="<%# Eval("isexported") %>" value="<%# Eval("isexported").ToString()=="2"?"Download again?":"Download" %>" onclick="SetFileUploaded(this)" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and I am trying to find the downloadButton in gridview OnRowDataBound event but its shows null,
here is my c# code
protected void grdFiles_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataControlFieldCell cell = (DataControlFieldCell)e.Row.Controls[7];
// Access the button
HtmlInputButton downloadButton = (HtmlInputButton)cell.FindControl("downloadButton");
// Check the condition
if (true)
{
// Hide the button
downloadButton.Visible = false;
}
}
}
Why use a "input" html button?
why not just drop in a plain jane asp.net button, and use that?
And don't bother with the gridview event model, you don't care, and don't need it. (not worth the trouble).
So, say we have this grid:
<asp:GridView ID="GridFiles" runat="server"
AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" CssClass="table">
<Columns>
<asp:BoundField DataField="FileName" HeaderText="FileName" />
<asp:BoundField DataField="UpLoadTime" HeaderText="UpLoaded" />
<asp:TemplateField HeaderText="Preview">
<ItemTemplate>
<asp:Image ID="Image1" runat="server" Width="140px"
ImageUrl='<%# "UpLoadFiles/" + Eval("FileName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Download" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="cmdDownLoad"
runat="server" Text="Download" CssClass="btn"
OnClick="cmdDownLoad_Click"
CommandArgument='<%# Eval("FileName") %>' />
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code to load:
GridFiles.DataSource = MyRst("SELECT * FROM MyUpLoadFiles");
GridFiles.DataBind();
Ok, so when we click the download button in that gv?
Then this code:
protected void cmdDownLoad_Click(object sender, EventArgs e)
{
Button myBut = sender as Button;
GridViewRow gRow = myBut.NamingContainer as GridViewRow;
string strFileOnly = gRow.Cells[0].Text;
string strFile = "";
strFile = Server.MapPath(#"~/UpLoadFiles/" + strFileOnly);
string sMineType = MimeMapping.GetMimeMapping(strFileOnly);
Response.ContentType = sMineType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + strFileOnly);
Response.TransmitFile(strFile);
Response.End();
}
So, you are "always" free to pick up/get/use/enjoy the current row click with above.
And note how I did use the cell's colleciton, but since I setup the command arugment of a plain jane button with this:
CommandArgument='<%# Eval("FileName") %>'
Then code behind becomes this:
Button myBut = sender as Button;
string strFileOnly = myBut.CommandArgument;
string strFile = "";
strFile = Server.MapPath(#"~/UpLoadFiles/" + strFileOnly);
So, just use a standard everyday button, and pick up the grid view row as per above. Or use a expression for the button command argument, and you may well not even have to mess with, or worry about the grid row, but use that simple button command argument.
So, above grid when displayed looks like this:

How to get cell value in a GridView on LinkButton Click Event? Or RowCommand?

I Have a GridView which conntains multiple records and couple of Link Buttons Named Edit and Detail. Now i want to Get the Name of the User (NOT Index), when a user click on Detail Link Button. Like "Name", "FatherName" etc
Here is the .aspx code
<asp:GridView ID="dgvEmployeesInformation" runat="server" CssClass=" table table-bordered table-hover table-responsive" DataKeyNames="Id" AutoGenerateColumns="False" OnRowCommand="dgvEmployeesInformation_RowCommand" OnRowDataBound="dgvEmployeesInformation_RowDataBound" AllowPaging="True" AllowSorting="True" OnPageIndexChanging="dgvEmployeesInformation_PageIndexChanging">
<%--1st Column--%>
<Columns>
<asp:BoundField HeaderText="ID" DataField="Id" ControlStyle-BackColor="#0066ff" Visible="False">
<ControlStyle BackColor="#0066FF"></ControlStyle>
</asp:BoundField>
<asp:BoundField HeaderText="Name" DataField="Name" />
<asp:BoundField HeaderText="Employee No" DataField="EmployeeNo" />
<asp:BoundField HeaderText="Father Name" DataField="FatherName" />
<asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="AddEmployeeBasic1.aspx?thid={0}" HeaderText="Update" NavigateUrl="~/AddEmployeeBasic1.aspx" Text="Edit" />
<asp:TemplateField HeaderText="Action" ShowHeader="True">
<ItemTemplate>
<asp:LinkButton ID="lbDelete" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbDetail" OnClick="lbDetail_Click" DataNavigateUrlFields="Id" DataNavigateUrlFormatString="EmployeesDetails.aspx?EmpID={0}" NavigateUrl="~/EmployeesDetails.aspx" HeaderText="Show Detail" Text="Detail"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is the lbDetail_Click Code
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
Label lblUserName = (Label)clickedRow.FindControl("Name");
EmployeeID.EmpName = lblUserName.ToString();
}
When i put my program on Debugging mode, the lblUserName return NULL
Here is the picture.
What i want is that, when a user click on Detail LinkButton, then on lbDetail Click event, it gets the Name of the Employee and store it in a static variable. Following is the picture
I don't understand how to solve this problem. Please help me through this. Your help will be really appreciated.
I would just add data attributes to the details button then get it's values at code behind.
For example:
1.) Add new data-myData='<%# Eval("Name") %>' attribute and its value to button
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbDetail" OnClick="lbDetail_Click" Text="Detail" data-ID='<%# Eval("ID") %>' data-myData='<%# Eval("Name") %>' ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
2.) Get those data from event handler
protected void lbDetail_Click(object sender, EventArgs e)
{
LinkButton button = (LinkButton)sender;
var name = (string)button.Attributes["data-myData"];
var selectedID = (string)button.Attributes["data-ID"];
Session["selectedID"] = selectedID ;
}
lblUserName is null because it's not a Label, but a BoundField.
What you could do it get the Cell value.
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
Label1.Text = clickedRow.Cells[1].Text;
}
Or use a TemplateField that does contain a Label Name
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="Name" runat="server" Text='<%# Eval("Name")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Here is how your code should look:
protected void lbDetail_Click(object sender, EventArgs e)
{
GridViewRow clickedRow = ((LinkButton)sender).NamingContainer as GridViewRow;
var username = clickedRow.Cells[1].Text;
if(string.IsNullOrEmpty(username))
{
return;
}
EmployeeID.EmpName = username;
}

Obtain a GridRow field by clicking a button on same row

I have a GridRow that looks like the following:
item_id name age
1 bob 13 (button)
2 tom 4 (button)
5 jim 24 (button)
In my grid view the button was added like so:
<Columns>
<asp:BoundField DataField="item_id" HeaderText="item_id"
InsertVisible="False" ReadOnly="True" SortExpression=item_id" />
<asp:BoundField DataField="name" HeaderText="name"
SortExpression="name" />
<asp:BoundField DataField="age" HeaderText="age"
SortExpression="age" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="button" runat="server" OnClick="RegisterClick" DataField="button" HeaderText="button" SortExpression="button"
CommandName="button"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Register" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
How can I get the item_id value by simply clicking on the button in the row?
I would like to access the item_id value in the OnClick method. Any ideas how to make this happen?
As the other comment mentioned, bind the "item_id" instead of using the row index. Instead of:
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Try (use single quotations instead of double):
CommandArgument='<%# Eval("item_id") %>'
In the code behind use the following to get the id:
int id = Convert.ToInt32(((Button)sender).CommandArgument);
In the CommandArgument of text box, bind the item_id instead of the row index. That's probably the fastest.
<asp:Button ID="button" runat="server" OnClick="RegisterClick" DataField="button" HeaderText="button" SortExpression="button"
CommandName="button"
CommandArgument='<%# Eval("item_id") %>'
Text="Register" />
In the button click event,
protected void RegisterClick(object sender, EventArgs e)
{
var itemId = (sender as Button).CommandArgument;
}

How to edit an entire column for all rows asp:GridView

So I have google'd and searched stackoverflow, and now my brain is overloaded. I am a novice at asp.net, but getting the hang of it.
My current requirement is to have a gridview where upon load, 1 column for all rows is immediately placed into edit mode. I used this question and code to get me going:
Allowing one column to be edited but not another
<asp:gridview id="CustomersGridView"
datasourceid="CustomersSqlDataSource"
autogeneratecolumns="false"
autogenerateeditbutton="true"
allowpaging="true"
datakeynames="CustomerID"
runat="server">
<columns>
<asp:boundfield datafield="CustomerID" readonly="true" headertext="Customer ID"/>
<asp:boundfield datafield="CompanyName" readonly="true" headertext="Customer Name"/>
<asp:boundfield datafield="Address" headertext="Address"/>
<asp:boundfield datafield="City" headertext="City"/>
<asp:boundfield datafield="PostalCode" headertext="ZIP Code"/>
</columns>
</asp:gridview>
I have searched and found a few good solutions, however, I do not fully understand them and have been unsuccesful at implementing them. They are:
Edit/Update a single GridView field
Put multiple rows of a gridview into edit mode
So my question is, how would you go about placing a column, (e.g, ZIP Code) into edit mode for all rows at the same time?
All help is appreciated!
Thanks!
Stephen
You won't be able to use the built-in edit functionality, but you can achieve this by loading the column in edit mode using a TemplateField:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand" ...>
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SomeColumn") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="SomeOtherColumn" HeaderText="Foo" />
...
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="Button1" runat="server" CommandName="Update" CommandArgument='<%# Container.ItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-behind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
GridViewRow row = GridView1.Rows[(int)e.CommandArgument];
if (row != null)
{
TextBox txt = row.FindControl("TextBox1") as TextBox;
if (txt != null)
{
//get the value from the textbox
string value = txt.Text;
}
}
}
EDIT: Putting a button outside of the GridView, you would update like this:
<asp:GridView>
...
</asp:GridView>
<asp:Button ID="Button1" runat="server" Text="Update" OnClick="Button1_Click" />
Code-behind:
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
TextBox txt = row.FindControl("TextBox1") as TextBox;
if (txt != null)
{
//get the value from the textbox
string value = txt.Text;
}
}
}

Checkbox in TemplateField in Gridview loses checked on postback

I have a gridview with a template field. In that template field is a checkbox. I have a submit button outside of the gridview to assign the records that were checked. On the postback no checkboxes register as being checked. Here is my Code:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="cb" Checked="false" runat="server" />
<asp:Label ID="lblCFID" runat="server" Visible="false" Text='<%# Eval("ID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderStyle-HorizontalAlign="Center" DataField="Name" HeaderText="Name" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" DataField="DOB" HeaderText="Date of Birth" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" HeaderText="Gender" DataField="Gender" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" HeaderText="Status" DataField="Status" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" HeaderText="Plan Name" DataField="PlanName" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" HeaderText="Type" DataField="ControlType" />
<asp:BoundField HeaderStyle-HorizontalAlign="Center" HeaderText="Date of Service" dataformatstring="{0:MMMM d, yyyy}" htmlencode="false" DataField="DateofService" />
</Columns>
protected void AssignRecords(object sender, EventArgs e)
{
int Rows = gvASH.Rows.Count;
for (int i = 0; i < Rows; i++)
{
//CheckBoxField cb = ((CheckBoxField)gvASH.Rows[i].Cells[1]).;
CheckBox cb = (CheckBox)gvASH.Rows[i].Cells[0].FindControl("cb");
Label lblID = (Label)gvASH.Rows[i].Cells[0].FindControl("lblCFID");
if (cb.Checked == true)
{
string ID = lblID.Text;
//Assign Code
}
}
}
I have a breakpoint set on the string ID = lblID.Text; but it never finds any that are checked.
I think what you are missing is, when you click on the button and your page is postback, you rebinding to gridview, you need to bind in this condition like
if (!Page.IsPostBack)
{
GridView1.DataSourceID = "yourDatasourceID";
GridView1.DataBind();
}
On a postback, the contents of the GridView are re-created from the postback Viewstate data between page_init and page_load. Perhaps try examining your Gridview in page_load to see what's there.
set the autopostback attribute of Checkbox
AutoPostBack="true"

Categories

Resources