Conditional Logic for Gridview ItemTemplate (using mark up only) - c#

I have a gridview as shown below. When the EmpType is contract the EmpID must be masked as "XXX"; for regular employees, actual EmpID should be shown. Also, when it is masked, I need to add a button control in the EmpID column.
I need to do it using mark-up; not using code behind. How can we write the conditional logic for Gridview's ItemTemplate for this logic?
Note: .Net 4.0
<asp:GridView ID="Gridview1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField HeaderText="AssociateID" DataField="AssociateID" />
<asp:TemplateField HeaderText="EmpID">
<ItemTemplate>
<%# Eval("EmpID")%>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="EmpType" DataField="EmpType" />
</Columns>
</asp:GridView>
CODE BEHIND
List<Associate> associatesList = new List<Associate>();
associatesList.Add(new Associate { AssociateID = 1, EmpID = 101, EmpType = "Contract" });
associatesList.Add(new Associate { AssociateID = 2, EmpID = 102, EmpType = "Regular" });
Gridview1.DataSource = associatesList;
Gridview1.DataBind();

Try this
<%# Eval("EmpType") == "Contract" ? "XXX" : Convert.ToString(Eval("EmpID"))%>
Instead of
<%# Eval("EmpID")%>

Following works
<asp:TemplateField HeaderText="EmpID">
<ItemTemplate>
<%# Convert.ToString(Eval("EmpType")) == "Contract" ? "XXX" : Convert.ToString(Eval("EmpID"))%>
<asp:Button ID="Button1" runat="server" Text="Button"
Visible='<%# Eval("EmpType") == "Contract" ? true : false %>' />
</ItemTemplate>
</asp:TemplateField>
Related:
Row number can be obtained by following Get GridView Selected Row Values using Page Previous Page
CommandArgument="<%# ((GridViewRow)Container).RowIndex %>"

Related

How to get the Id from Gridview of Chechbox.checked?

I have GridView and a button as follows. Then i am binding the gridview with data from my database. GridView has two hiddenfield for Id and ClassIndex.
when i selecting a checkbox and click button, i want to get the corresponding Id and FileName.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="check" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="hdfId" runat ="server" Value='<%#Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="hdfClssIndex" runat ="server" Value='<%#Eval("ClassIndex") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblFileName" runat ="server" Text='<%#Eval("FileName") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and Button Like
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="Send Request" />
the code behind button is
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
var check = row.FindControl("check") as CheckBox;
if (check.Checked)
{
int Id = Convert.ToInt32(row.Cells[1].Text);
//some logic follws here
}
}
}
but i am getting an error like
Input string was not in a correct format.
What is the error and how to solve it?
Your looping correct.
But you forgot to notice one thing here, when you wanted to access CheckBox you did a FindControl on row. Which means you are trying to find some control in that row.
Then why are you accessing HiddenField control inside row with row.Cell[1].Text?
Try to find that also.
int Id = Convert.ToInt32(((HiddenField)row.FindControl("hdfId")).Value);

To add new row in gridview using javascript

In the below code i have gridview which has textbox and dropdownlist i want to add rows using javascript.My aim is to avoid postback on adding rows.
Markup code:
<asp:GridView runat="server" ID="gvProduct" AutoGenerateColumns="false"
Width="100%" CellPadding="4" ForeColor="#333333" ShowFooter="true"
PageSize-Mode="NumericPages" PagerStyle-Visible="true" AllowPaging="false" AllowSorting="true"
CssClass="mGrid" PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt"
OnRowDataBound="gvProduct_RowDataBound" OnRowCommand="gvProduct_RowCommand" OnRowDeleting="gvProduct_RowDeleting">
<Columns>
<asp:TemplateField HeaderText="Product Name" ItemStyle-Width="350px">
<ItemTemplate>
<asp:DropDownList ID="ddlProduct" runat="server" AutoPostBack="false" Style="width: 100%; height:23px" ></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Current Stock" ItemStyle-Width="80px" Visible="false">
<ItemTemplate>
<asp:Label ID="lblCurrentStock" runat="server" onkeypress="return isNumberKey(event, false);" Height="20px" style="width:80px" Enabled="false" ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity" ItemStyle-Width="80px">
<ItemTemplate>
<asp:TextBox ID="txtQuantity" onkeypress="return isNumberKey(event, false);" runat="server" Height="20px" Width="150px" onblur="js_function(this);" > </asp:TextBox>
<asp:Label ID="lblunittype" runat="server" ></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Button2" OnClientClick="AddRow(); return false;" runat="server" Text="Button" />
Javascript code:
function AddRow() {
var table = document.getElementById('<%=gvProduct.ClientID %>');
var newRow = table.insertRow();
var i = 0;
for (i = 0; i < table.rows[0].cells.length; i++) {
var newCell = newRow.insertCell();
newCell.innerHTML = 'New Row';
}
}
Gridview in asp = Table in HTML
new row in Gridview in asp = new row in Table in HTML
Sample JavaScript code:
function AddRow() {
let tableRef = document.getElementById('MainContent_gvItems');
let newRow = tableRef.insertRow(-1);//inserts at last row
let Cell0 = newRow.insertCell(0);
let Text0 = document.createTextNode('mydata');
Cell0.appendChild(Text0);
}
Btw, GridView must be visible even it's empty.
If you just want to add rows to the table for presentation, then #Mostafa Shehata answer should work fine.
However adding rows in JavaScript does not attached it to the GridView datasource. Therefore you'll experience issues with processing the data in the backend (such as saving to database).
Two possible solutions:
Replace GridView with a html table. The data can be populated & updated using a JavaScript calls to a restful API.
Pre-populate the GridView datasource with empty rows.
Data-bind x amount of empty fields (for example 10 empty fields).
In the GridView markup hide all the rows using css.
Run JavaScript to show rows that are not empty.
The “add row” button can just show the first empty row.
Add some sort of notification, if all empty fields have been used. (for example: "please save your data, before continuing").
In code behind, remove all empty fields before consuming it.

Set value of girdview textbox as command argument of button

Here is my grid view
<asp:GridView ID="grvClaimBanks" runat="server" AutoGenerateColumns="false" AllowPaging="false" OnRowCommand="grvClaimBanks_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Sr.No">
<ItemTemplate>
<%#Container.DataItemIndex +1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:TextBox ID="txtMoratoriumPeroid" runat="server">
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="lnkEditProduction" runat="server" CommandArgument='<%# Eval("TextileSLACId") %>' CommandName="EnterClaim" Text="Enter Claim" CausesValidation="false"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
Now i want to set value of "txtMoratoriumPeroid" as "CommandArgument" of "lnkEditProduction", so i can access that value in Row Command Event of grid view.
Is this possible?
If yes please help...
The way you are bind the TextBox wont give you value change in client side and your TextBox seem empty on server side. You can get current row of command button in RowCommand event and find TextBox to take its value.
GridViewRow row = (GridViewRow)(((Control)e.CommandSource).NamingContainer);
TextBox txtMoratoriumPeroid= row.FindControl("txtMoratoriumPeroid") as TextBox;
if(txtMoratoriumPeroid != null)
{
//Your code here.
string txtMoratoriumPeroidText = txtMoratoriumPeroid.Text;
}
No it is not possible to give dynamic CommandArgument on the fly.
But you can achieve this by
LinkButton lbtnSender = (LinkButton)sender;
TextBox txtMoratoriumPeroid = (TextBox)lbtnSender.Parent.Parent.FindControl("txtMoratoriumPeroid");
string MoratoriumPeroid = txtMoratoriumPeroid.Text;

Display DataGrid Column as Hyperlink Column depending on column value

I have the below DataGrid which works with no problem
<asp:DataGrid ID="fileBrowserGrid" runat="server" Width="100%" PageSize="14" AllowPaging="True"
CellPadding="1" GridLines="None" BorderColor="#636E92" BorderWidth="0px" AutoGenerateColumns="False"
OnPageIndexChanged="fileBrowserGrid_PageIndexChanged">
<AlternatingItemStyle CssClass="mainbodytextalt"></AlternatingItemStyle>
<ItemStyle CssClass="metadatabodytext"></ItemStyle>
<HeaderStyle CssClass="metadatabodytitle"></HeaderStyle>
<FooterStyle CssClass="Blue"></FooterStyle>
<Columns>
<asp:BoundColumn DataField="LoadedFileID" HeaderText="Loaded File Id" Visible="False"></asp:BoundColumn>
<asp:BoundColumn DataField="DataSupplierCode" HeaderText="Data Supplier Code"></asp:BoundColumn>
<asp:BoundColumn DataField="DataSupplierName" HeaderText="Data Supplier Name"></asp:BoundColumn>
<asp:BoundColumn DataField="Filename" HeaderText="File Name"></asp:BoundColumn>
<asp:BoundColumn DataField="DateLoaded" HeaderText="Date Loaded"></asp:BoundColumn>
<asp:BoundColumn DataField="LoadStatus" HeaderText="Status"></asp:BoundColumn>
</Columns>
<PagerStyle CssClass="Gray"></PagerStyle>
</asp:DataGrid>
code behind:
DataSet dataSet = results.DataSet;
this.fileBrowserGrid.DataSource = dataSet;
this.fileBrowserGrid.DataBind();
I want to change the Status column so that will display a hyperlink to errormessage.aspx with id as querystring value if the value is 'Failed' but stay as normal text value if its anything else.
Ideally I don't want to make changes to my stored procedures
I've been looking at RowDataBind but haven't been able to get that working.
Any ideas? Thank you!
I have a solution with only the aspx and not touch the cs backend
You can predict the render of template Column. Try this
I suppose that the code status that indicate failed is "failed"
<asp:TemplateColumn>
<HeaderTemplate>
<b>Status </b>
</HeaderTemplate>
<ItemTemplate>
<asp:PlaceHolder ID="Ok" runat="server" Visible='<%# (Eval("LoadStatus").ToString()=="Failed"?false:true) %>'><%----%>
<asp:Label ID="Label1" Text='<%# Eval("LoadStatus") %>' runat="server" />
</asp:PlaceHolder>
<asp:PlaceHolder ID="Ko" runat="server" Visible='<%# (Eval("LoadStatus").ToString()=="Failed"?true:false) %>'><%----%>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# string.Format("DataLoaderErrorMessage.aspx?id={0}",Eval("LoadedFileID"))%>'><%# Eval("LoadStatus") %></asp:HyperLink>
</asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateColumn>
1) Set the AutoGenerateColumns property of the datagrid to false.
2) Create a template column instead of a bound column for the status.
3) Set the 'DataField' property for every column (Except the template column) so they know which value to display from the sql datasource.
4) Edit the template column and add a html div in there with the id divStatus
<asp:TemplateField HeaderText="Status">
<ItemTemplate>
<div id="divStatus" runat="server">
</div>
</ItemTemplate>
</asp:TemplateField>
Iterate through all the rows after setting the datasource of the gridview and do something like the following.
for(int i = 0; i < dataSet.Tables[0].Rows.Count; i++)
{
HtmlGenericControl divStatus = (HtmlGenericControl)fileBrowserGrid.Rows[i].FindControl("divStatus");
if(dataSet.Tables[0].Rows[i]["LoadStatus"].ToString() != "Failed")
divStatus.InnerHtml = dataSet.Tables[0].Rows[i]["LoadStatus"].ToString();
else
divStatus.InnerHtml = "<a href='pageURL.aspx?ID=" + dataSet.Tables[0].Rows[i]["LoadedFileID"].ToString() + "'> Failed : " + dataSet.Tables[0].Rows[i]["LoadedFileID"].ToString() + "</a>";
}

Bind and access checkbox value within a gridview

In my grid view I've a checkbox column, and am binding the gridview with a dictionary. I need to get the corresponding Id from the checked boxes.
In my dictionary I've the key values like
Id Name
-- ----
1 Arts
2 Science
3 Engineering
Here, I tried to bind the value for this checkbox as
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkSelItem" value="<%# Eval("Key.Id") %>"
runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Department">
<ItemTemplate>
<%# Eval("Key.Name") %>
</ItemTemplate>
<HeaderStyle HorizontalAlign="Left" />
</asp:TemplateField>
and from the codebehind, I tried like
foreach (GridViewRow row in gridDepartments.Rows)
{
CheckBox chkSelItem = (CheckBox)row.FindControl("chkSelItem");
if (chkSelItem.Checked)
{
int departmentId = int.Parse(chkSelItem.Text);
////
////
}
}
its throwing error, or not showing any value for the checkbox.
I also trid with FindControl, but no use of it, coz in the key & Value pair am using a class(which inherits another class) and a bool. thats what am trying like this, can anyone help me here, thanks in advance.....
You can try this one...
Bind id to lable instead of to checkbox as below.
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="chkSelItem" runat="server" />
<asp:Label ID="lblSelectedItem" value=<%# Eval("Key.Id")) %> visible="False"/>
</ItemTemplate> </asp:TemplateField>
In codebehind try this
foreach (GridViewRow row in gridDepartments.Rows)
{
CheckBox chkSelItem = (CheckBox)row.FindControl("chkSelItem");
Label lblSelectedItem= (Label)row.FindControl("lblSelectedItem");
if (chkSelItem.Checked)
{
int departmentId = int.Parse(lblSelectedItem.Text);
}
}
Hope this is what u want...
Use
CheckBox chkSelItem = (CheckBox)row.cell[0].FindControl("chkSelItem");// Replace row.cell[0] accrding to you celll index
instead of
CheckBox chkSelItem = (CheckBox)row.FindControl("chkSelItem");
In Aspx page:
<asp:CheckBox ID="chkSelItem" Text="<%# Eval("Key.Id") %>" runat="server" />
In code-behind add a check to ensure the item is not null:
CheckBox chkSelItem = (CheckBox)row.FindControl("chkSelItem");
if (chkSelItem != null && chkSelItem.Checked && !string.IsNullOrEmpty(chkSelItem.Text))
{
int departmentId = int.Parse(chkSelItem.Text);
}
I think you have to use Text instead of value as you are assigning to value and getting text property. Text will be empty string and parsing it with int throws exception.
int.Parse(chkSelItem.Text);
<asp:CheckBox ID="chkSelItem" value="<%# Eval("Key.Id") %>" runat="server" />
Would be
<asp:CheckBox ID="chkSelItem" Text="<%# Eval("Key.Id") %>" runat="server" />
Or
If you have to use Value of check box, then access value not Text
<asp:CheckBox ID="chkSelItem" value="<%# Eval("Key.Id") %>" runat="server" />
int departmentId = int.Parse(chkSelItem.Attributes["value"].ToString());

Categories