Why is e.Row.DataItem null in RowCreated function of GridView - c#

Partial HTML source for a GridView (ID: MyGrid):
...
<tr title="Task is Past Due" style="color:#C00000;background-color:#EBE9E9;">
<td>
<input type="image" name="ctl00$ContentMain$yourTasksGV$ctl04$btnShowDepend" id="btnShowDepend" title="Click to view Dependencies" class="gvTaskDep btnShowDepend" src="es.png" alt="" />
<div id="pnlSubTasks" class="pnlSubTasks">
<div>
</div>
</div>
</td>
<td style="background-color:DarkRed;">
</td>
<td class="taskTableColumn">SOMETHING</td>
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn">03-09-2015</td> //<asp:BoundField HeaderStyle-Width="7%" DataField="Due Date" HeaderText="Due" SortExpression="Due Date" ItemStyle-CssClass="taskTableColumn" />
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn">Something</td>
<td class="taskTableColumn"> </td>
<td class="taskTableColumn"></td>
<td class="hideTag">1</td>
<td class="hideTag">155</td>
</tr>
...
When I click on the btnShowDepend image to perform some operation, it fails in the GridView RowCreated function:
if (e.Row.RowType == DataControlRowType.DataRow)
{
var k = DataBinder.Eval(e.Row.DataItem, "Due Date"); //k=null
DateTime dt;
DateTime.TryParse(DataBinder.Eval(e.Row.DataItem, "Due Date").ToString(), out dt); //e.Row.DataItem = null
if (dt < DateTime.Today)
{
//or do it for a specific cell
e.Row.Cells[1].BackColor = System.Drawing.Color.DarkRed;
}
}
Why is k null and how can I modify the code to fix it.
Please note: If it can also be done using JQuery, I would like that solution.
I would like to make the font color RED to any row where the column's Due Date is less than today's date.

I'm not an ASP.net guy, but with jQuery you could use Date.parse like this:
$('#btnShowDepend').on('click', function () {
var now = Date.now();
$('td.taskTableColumn').each(function () {
var date = Date.parse($(this).text());
// Skip invalid dates
if (isNaN(date)) return;
if (date < now) {
$(this).css({
backgroundColor: 'red'
});
}
});
});
EDIT:
To cycle through the entire table, turning each row RED if its "6th column" contains a date earlier than today, you can do this like so:
$('#btnShowDepend').on('click', function () {
var now = Date.now();
$('#myTableId tr').each(function () {
var $row = $(this);
var the6thColumn = $row.find('.my6thColumnClass');
var date = Date.parse($(the6thColumn).text());
// Skip invalid dates
if (isNaN(date)) return;
if (date < now) {
$row.css({
backgroundColor: 'red'
});
}
});
});
Assuming:
The table in question has an id of myTableId
The "6th column" cells have a class of my6thColumnClass like so: <td class="my6thColumnClass">.

Related

Change TextBox Value and Update On Ajax Call

I am working on an ecommerce site where I am stuck on the cart management. Basically before login, products are kept in a session and I am trying to update the product quantity stored in the session using Ajax. I mean whenever I write in the 'Quantity To Change', the changed value should be reflected in the 'Quantity' column.
Note: I've shortened the post and figured out why it wasn't firing while debugging. Actually I was unable to get the id of the associated product. Now it passes the id. That's it. Now I've another issue - The TextBox are being created dynamically with a for loop. I used developer tools to figure out how the TextBoxes are generated dynamically and it is something like this:
For Product 1: cartDetails_0__Quantity
For Product 2: cartDetails_1__Quantity
I am wondering how to grab the quantity or values from the dynamically generated TextBoxes. If I put the generated id from HTML directly to Ajax, then it updates the quantity. Otherwise it doesn't. I've tried to use a loop in Ajax but I think, I am getting it wrong. Please see the View.
The view:
<table border="1" width="100%" cellpadding="4">
<thead>
<tr>
<th style="text-align:center;">Name</th>
<th style="text-align:center;">Price</th>
<th style="text-align:center;">Quantity</th>
<th style="text-align:center;">Quantity To Change</th>
</tr>
</thead>
<tbody>
#if (ViewBag.CartDetails != null)
{
for (int i = 0; i < cartDetails.Count(); i++)
{
<tr>
<td style="text-align: center; display:none;">#Html.DisplayFor(model => cartDetails[i].ProductId)</td>
<td id="ID" style="text-align: center;">#Html.DisplayFor(model => cartDetails[i].ProductName)</td>
<td style="text-align: center;">#Html.DisplayFor(model => cartDetails[i].Price)</td>
<td style="text-align: center;">#Html.DisplayFor(model => cartDetails[i].Quantity, new { #class = "quantityUpdate" })</td>
<td style="text-align: center;">#Html.TextBoxFor(model => cartDetails[i].Quantity, new { #class = "quantity", data_id = cartDetails[i].ProductId } )</td>
</tr>
}
}
</tbody>
</table>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
var url = '#Url.Action("UpdateCart")';
$(".quantityUpdate").change(function () {
var id = $(this).data('id');
var i = 0;
$('.quantityUpdate').each(function (i, item) {
$.post(url, { id: id, Quantity: $("#cartDetails_"+i+"__Quantity").val() }, function (response) {
if (response) {
$("#TotalPrice").load(window.location + " #TotalPrice");
}
});
})
alert(id);
alert($("#cartDetails_"+i+"__Quantity").val());
});
Here is an image sample that I am trying:
$('.quantity').change(function(){
$('.quantityUpdate').val($('.quantity').val());
// put code here
});
Instant Change
$('.quantity').keyup(function(){
$('.quantityUpdate').val($('.quantity').val());
// put code here
});
If the idea is to call ajax when you change the value in .quality textbox then this is how you should do:
$('.quantity').change(function(){
//your ajax call
});

Updating record number after deletion in asp.net MVC 4 razor view

I am working on asp.net MVC 4 application. I have created a list using foreach loop and declared a variable to show record number. Each row has a delete icon, which when clicked, deletes that record and hides that row. this works fine except one issue. When user deletes first record or any record in middle of list, I want the record number of all the rows to be updated accordinlgy.
Here is razor view code:
#{
int i = 1;
foreach (var item in cartItem.CartItemsByStore)
{
<tr id="cartrow-#item.CartItemID">
<td class="transaction">#i</td>
<td class="item-details">
<img src="/images/tmp/order-product.jpg" width="63" height="63">
<div class="desc">
<span>
<p>#item.ItemName</p>
</span>
</div>
</td>
<td class="date-time">15 Jun 2014</td>
<td class="action">
X
</td>
</tr>
<tr class="sp" id="sp-#item.CartItemID">
<td colspan="20"></td>
</tr>
i++;
}
}
and here is deletion code:
$(function () {
// Document.ready -> link up remove event handler
$(".removeCartItem").click(function () {
if (confirm("Click OK if you want to delete this record; otherwise, click 'Cancel'")) {
// Get the id from the link
var recordToDelete = $(this).attr("data-id");
if (recordToDelete != '') {
// Perform the ajax post
$.post("/Cart/DeleteCartItem", { "id": recordToDelete },
function (data) {
// Successful requests get here
$('#cartrow-' + recordToDelete).fadeOut('hide');
$('#sp-' + recordToDelete).fadeOut('hide');
$('#spCartCount').text(data);
$('#row-' + recordToDelete).fadeOut('hide');
});
}
}
});
});
Try this
Partial view : "Store.csthml"
#model IEnumerable<CartItemsByStore>
#{
int i = 1;
foreach (var item in Model)
{
<tr id="cartrow-#item.CartItemID">
<td class="transaction">#i</td>
<td class="item-details">
<img src="/images/tmp/order-product.jpg" width="63" height="63">
<div class="desc">
<span>
<p>#item.ItemName</p>
</span>
</div>
</td>
<td class="date-time">15 Jun 2014</td>
<td class="action">
X
</td>
</tr>
<tr class="sp" id="sp-#item.CartItemID">
<td colspan="20"></td>
</tr>
i++;
}
}
CartController:
public ActionResult ReturnView()
{
//populate model
IEnumerable<CartItemsByStore>model =db.GetItemsByStore();
return PartialView("Store",model)
}
public ActionResult DeleteCartItem(int id)
{
//delete
return RedirectToAction("ReturnView");
}
Main View:
<div id="divStore">
#Html.Partial("Store",cartItem.CartItemsByStore)
</div>
$(".removeCartItem").click(function () {
if (confirm("Click OK if you want to delete this record; otherwise, click 'Cancel'")) {
// Get the id from the link
var recordToDelete = $(this).attr("data-id");
if (recordToDelete != '') {
// Perform the ajax post
$.post("/Cart/DeleteCartItem", { "id": recordToDelete },
function (data) {
// Successful requests get here
$("#divStore").html(data);
});
}
}
});

How to get individual error labels to show C# asp.net

I am working on a contact page and would like some help please on how to display error labels at individual times when the textboxes are empty. I have used 3 textboxes. I am a new student in C# asp.net. I really appreciate your time and help. Thanks!
//if no or incorrect entries are entered panel with red message using a label appears to remind the user of
//if name, email, enquiry is blank error labels show up
if (nameContactUsTextBox.Text == "" && emailContactUsTextBox.Text == "" && enquiryContactUsTextBox.Text == "")
{
nameErrorLabel.Visible = true;
emailErrorLabel.Visible = true;
equiryErrorLabel.Visible = true;
}
if (nameContactUsTextBox.Text != "" && emailContactUsTextBox.Text == "" && enquiryContactUsTextBox.Text == "")
{
emailErrorLabel.Visible = true;
equiryErrorLabel.Visible = true;
}
if (nameContactUsTextBox.Text == "" && emailContactUsTextBox.Text != "" && enquiryContactUsTextBox.Text == "")
{
nameErrorLabel.Visible = true;
equiryErrorLabel.Visible = true;
}
if (nameContactUsTextBox.Text == "" && emailContactUsTextBox.Text == "" && enquiryContactUsTextBox.Text != "")
{
nameErrorLabel.Visible = true;
emailErrorLabel.Visible = true;
}
aspx file
<p>
<table style="width: 100%;">
<tr>
<td class="boring">Name</td>
<td class="auto-style1">
<asp:TextBox ID="nameContactUsTextBox" runat="server" CssClass="boring" ToolTip="Enter Name" Width="441px"></asp:TextBox>
<asp:Label ID="nameErrorLabel" runat="server" CssClass="redalert" Text="*complete name" Visible="False"></asp:Label>
</td>
</tr>
<tr>
<td class="boring">E-Mail</td>
<td>
<asp:TextBox ID="emailContactUsTextBox" runat="server" CssClass="boring" ToolTip="Enter Email" Width="443px"></asp:TextBox>
<asp:Label ID="emailErrorLabel" runat="server" CssClass="redalert" Text="*complete email" Visible="False"></asp:Label>
</td>
</tr>
<tr>
<td class="boring">Enquiry</td>
<td class="auto-style5">
<asp:TextBox ID="enquiryContactUsTextBox" runat="server" CssClass="classic" Height="158px" ToolTip="Enter Enquiry" Width="441px"></asp:TextBox>
<asp:Label ID="equiryErrorLabel" runat="server" CssClass="redalert" Text="*complete enquiry" Visible="False"></asp:Label>
</td>
</tr>
<tr>
<td class="auto-style5"></td>
<td class="auto-style2"></td>
</tr>
<tr>
<td class="smallheader" colspan="2"> </td>
</tr>
<tr>
<td class="auto-style5"> </td>
<td class="auto-style2"> </td>
</tr>
<tr>
<td class="auto-style5" colspan="2">
<asp:Button ID="sendButton" runat="server" CssClass="smallheader" OnClick="sendButton_Click" Text="Send" ToolTip="Sending to NeoMan!" Width="200px" />
<asp:Button ID="homeButton" runat="server" CssClass="smallheader" OnClick="homeButton_Click" Text="Home" ToolTip="Continue Shopping With NeoMan" Width="200px" />
<asp:Button ID="resetButton" runat="server" CssClass="smallheader" OnClick="resetButton_Click" Text="Reset Form" ToolTip="Clear Form" Width="200px" />
</td>
</tr>
<tr>
You could use the TextChangedEvent like so:
protected void nameContactUsTextBox_TextChanged(object sender, EventArgs e)
{
nameErrorLabel.Visible = nameContactUsTextBox.Text == "";
}
And add the textchanged-event for each of the textboxes.
Microsoft already have buil ib validators that you can use to do this sort of task. To make sure that the field is not empty use the Required Field validator see this example on the w3c school website http://www.w3schools.com/aspnet/showaspx.asp?filename=demo_reqfieldvalidator.
For more complex validation use can use the regular expression validator. check the msdn website(http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.regularexpressionvalidator%28v=vs.110%29.aspx) for this it quite straight forward.
you can also investigate the JQuery validator it is quite flexible to do more interesting validation.
That's because you need to hide labels when they're not supposed to be shown, not only hide it. Change ifs to if-elses and add a summary else condition
else
{
nameErrorLabel.Visible = false;
emailErrorLabel.Visible = false;
equiryErrorLabel.Visible = false;
}
You should use the
placeholder
property of the textbox to display the type of value you need entered and examine those answers with jquery either after the boxes lose focus or upon a click of a button. If you need some sample code let me know

Show validation message depending on each other

I have a following code in aspx page:
<TABLE id="tblGeneratedTo" cellspacing="0" cellpadding="0" width="100%" align="left" border="0" runat="server">
<TR>
<td width="20%" align="left"><FONT face="Verdana" size="2"><strong>To:</strong></FONT> </TD>
<td width="80%">
<asp:textbox id="txtGeneratedTo" runat="server" CssClass="ptinput" MaxLength="10" Width="90px"></asp:textbox>
<A onclick="window.open('../calPopUp.aspx?textbox=txtGeneratedTo','cal','width=230,height=190,left=400,top=200')"
href="javascript:;"> <IMG src="../images/SmallCalendar.gif" border="0"></A> <FONT class="fontbody">
(mm/dd/yyyy)</FONT>
</TD>
</TR>
<tr>
<td colspan="2" align="right">
<asp:RegularExpressionValidator ID="Regularexpressionvalidator4" runat="server" CssClass="fontbody"
Display="Dynamic" ErrorMessage="*Date should be in (mm/dd/yyyy) format."
ValidationExpression="^([\d]{1,2}/[\d]{1,2}/[\d]{4})$"
ControlToValidate="txtGeneratedTo"></asp:RegularExpressionValidator>
<asp:CompareValidator ID="CompareValidator6" runat="server" CssClass="fontbody"
Display="Dynamic" ErrorMessage="'End' date cannot fall before 'Start' date."
ControlToValidate="txtGeneratedTo" Type="Date" Operator="GreaterThanEqual"
ControlToCompare="txtGeneratedFrom"></asp:CompareValidator>
</td>
</tr>
</TABLE>
To:
(mm/dd/yyyy)
Here I have a textbox and two validation controls on it viz. regular expression and compare on actual page when I put some garbage value in textbox I see both the message at a time:
I want to see only one message at a time. Most preferably show comparevalidator message iff regularexpression validator is satisfied or else show only regularexpression validator.
How to achieve this? It will be easy if we can do something for this from MarkUp only rather than codebehind.
For this you have to use CustomValidator. The Validator
<asp:CustomValidator ID="CompareDateValidator" runat="server"
ClientValidationFunction="CompareDateValidatorClient"
ErrorMessage="Some error message" />
The ClientValidationFunction that accompanies this
function CompareDateValidatorClient(sender, args) {
var fromValue = document.getElementById('<%=txtGeneratedFrom.ClientID%>').value;
var toValue = document.getElementById('<%=txtGeneratedTo.ClientID%>').value;
var isValid = false;
if (ValidateDate(fromValue)) {
if (ValidateDate(toValue)) {
if (Date.parse(toValue) > Date.parse(fromValue)) {
isValid = true;
}
else
sender.innerHTML = "'End' date cannot fall before 'Start' date.";
}
else
sender.innerHTML = "To date should be in (mm/dd/yyyy) format.";
}
else
sender.innerHTML = "From date should be in (mm/dd/yyyy) format.";
args.IsValid = isValid;
}
function ValidateDate(str) {
var rm_date = /^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$/;
//triple check for not empty, mm/dd/yyyy format and whether the date is valid
return (str.trim() !== "" && str.match(rm_date) && !isNaN(Date.parse(str)));
}
//remedial javascript. trim function
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s*(\S*(?:\s+\S+)*)\s*$/, "$1");
};
}
// ControlToValidate property supports hooking up single element.
//The below hack hooks both txtGeneratedFrom and txtGeneratedTo to the validator
var validatorObj = document.getElementById("<%= CompareDateValidator.ClientID %>");
ValidatorHookupControlID("<%= txtGeneratedFrom.ClientID %>", validatorObj);
ValidatorHookupControlID("<%= txtGeneratedTo.ClientID %>", validatorObj);

Fill dropdown list in casceding way and set each dropdown list before its first value

In my project I am making one form which contains three dropdown lists each for company,department and vacancies with "Select" as their default text. I am feeling company dropdown list at form load event but default text is "Select" now when user select company, second list should be filled with departments of selected company but default text should be "select". Again when user select department,the third list should be filled with vacancies on the selected department of selected company but default text should be "select".
I am trying to fill other two dropdown list with "selected index change" event of company list and department list respectively. but its not working as I want.
Here is my code for .aspx page.
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<table width="100%">
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td align="center" class="tdtitle" colspan="4">
Search Candidates
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td class="RowHeight" width="20%">
Select Company</td>
<td width="30%">
<asp:DropDownList ID="companyList" runat="server" AutoPostBack="True"
onselectedindexchanged="companyList_SelectedIndexChanged" Width="150px">
<asp:ListItem>-Select Company-</asp:ListItem></asp:DropDownList>
</td>
<td width="20%">
Select Department</td>
<td width="30%">
<asp:DropDownList ID="deptList" runat="server" AutoPostBack="True"
Width="150px" onselectedindexchanged="deptList_SelectedIndexChanged" onclick="Validate();">
<asp:ListItem>-Select Department-</asp:ListItem></asp:DropDownList>
</td>
</tr>
<tr>
<td class="RowHeight" width="20%">
Select Vacancy</td>
<td colspan="3" width="*">
<asp:DropDownList ID="vacanyList" runat="server" Width="200px">
<asp:ListItem>-Select Vacancy-</asp:ListItem></asp:DropDownList>
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
<tr>
<td align="center" colspan="4">
<asp:Label ID="notifyLbl" runat="server" Font-Size="Large" ForeColor="Red"
Text="Label"></asp:Label>
</td>
</tr>
<tr>
<td colspan="4">
</td>
</tr>
</table>
<script type="text/javascript">
function alertOnBadSelection() {
var select = document.getElementById('companyList');
if (select.options[select.selectedIndex].value == "-Select Company-") {
alert('Please Select Company!');
return false;
}
}
</script>
</asp:Content>
/And below is the code for my .aspx.cs page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class HR_Department_searcAppForVac : System.Web.UI.Page
{
DataOperation oDo = new DataOperation();
protected void Page_Load(object sender, EventArgs e)
{
// deptList.Attributes.Add("onchange", "alertOnBadSelection();");
notifyLbl.Visible = false;
if (!IsPostBack)
{
try
{
DataTable objCmpnyTable = oDo.DropDownList("select * from tblCompanyMaster");
if (objCmpnyTable.Rows.Count > 0)
{
foreach (DataRow Row in objCmpnyTable.Rows)
{
companyList.Items.Add(new ListItem(Row["CompName"].ToString(), Row["CompId"].ToString()));
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "There is not any company in the list.";
}
}
catch (Exception)
{
throw;
}
}
else
{
//deptList.SelectedIndex = -1;
//vacanyList.SelectedIndex = 1;
}
}
protected void companyList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (companyList.SelectedIndex > 0)
{
deptList.Items.Clear();
string str = "select * from vwCompWiseList where CompId=" + companyList.SelectedValue;
DataTable objDeptTable = oDo.DropDownList("select DeptId,DeptName from vwCompWiseDept where CompId= "+companyList.SelectedValue);
if (objDeptTable.Rows.Count > 0)
{
foreach (DataRow Row in objDeptTable.Rows)
{
deptList.Items.Add(new ListItem(Row["DeptName"].ToString(), Row["DeptId"].ToString()));
}
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Select Company....";
}
}
catch (Exception)
{
throw;
}
}
protected void deptList_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (deptList.SelectedIndex > 0)
{
vacanyList.Items.Clear();
DataTable objVacancytbl = oDo.DropDownList("select VacId,VacTitle from tblVacancyMaster where DeptId =" + deptList.SelectedValue + " and CompId=" + companyList.SelectedValue);
if (objVacancytbl.Rows.Count > 0)
{
foreach (DataRow Row in objVacancytbl.Rows)
{
vacanyList.Items.Add(new ListItem(Row["VacTitle"].ToString(), Row["VacId"].ToString()));
}
vacanyList.SelectedIndex = -1;
vacanyList.ClearSelection();
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Ops..!There is no available vacancy....";
}
}
else
{
notifyLbl.Visible = true;
notifyLbl.Text = "Select Department...";
}
}
catch (Exception)
{
throw;
}
}
}
Please show my problem and its solutions.
I think you may want to leverage jquery cascading drop downs . Using a cascading drop down javascript (jquery) will call back and reload dependent drop downs based on the value(s) selected in the previous drop down.

Categories