Getting error When dt.value length is < 4 - asp.net

I have this code which works fine as long as as dt.Value is different to "int".
This is the line which errors:
(dt.Value.ToLower().Substring(0, 4).Equals("date"))
It works fine if dt.Value is varchar or datetime.
I provided my suggested solution at the end of this post.
// Edit
if (e.CommandName == "Edit")
{
// Get the item
RepeaterItem Item = ((RepeaterItem)((Button)e.CommandSource).NamingContainer);
// Get buttons and repeater
Button savebtn = (Button)(Item.FindControl("btnSave"));
Button editbtn = (Button)(Item.FindControl("btnEdit"));
Repeater rFields = (Repeater)(Item.FindControl("repFields"));
// Enable my fields
foreach (RepeaterItem RI in rFields.Items)
{
// Get data type
HiddenField dt = (HiddenField)(RI.FindControl("hdnDBDataType"));
// Set controls
if (RI.FindControl("chkSetting").Visible) ((CheckBox)RI.FindControl("chkSetting")).Enabled = true;
if (RI.FindControl("ddlSetting").Visible) ((DropDownList)RI.FindControl("ddlSetting")).Enabled = true;
if (RI.FindControl("txtSetting").Visible)
{
((TextBox)RI.FindControl("txtSetting")).Enabled = true;
// Check my data type
if (dt.Value.ToLower().Substring(0, 4).Equals("date")) ((CalendarExtender)RI.FindControl("extDateTime")).Enabled = true;
}
}
}
Is this a good fix ? TIA
if(dt.Value != "int" && dt.Value.ToLower().Substring(0, 4).Equals("date"))

Substring will throw an error if the second parameter is higher than the lenght of the string. What you need to do is check the length before doing the substring or use a method like #Igor suggested in the comments.
Your suggestion to check != "int" is not fullproof if let's say somehow the value is any string less than 4 characters.
(dt.Value.Length > 3 && dt.Value.ToLower().Substring(0, 4).Equals("date"))
I will also put #Igor suggestion here because it is also fullproof:
(dt.Value.StartsWith("date", StringComparison.OrdinalIgnoreCase)

Related

Depending source for drop down list

I have one drop down list in my pages that its source comes of below code. Now I like to put 1 text box adjusted on my drop down list and when I type on that, source of drop down list (DocumentNo) depend on what I type in the text box and when text box is null drop downs list shows all the (DocumentNo) , please help how I have to change my code,
protected void ddlProjectDocument_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var query = from p in _DataContext.tblDocuments
orderby p.DocumentNo
select p;
int maxs = 0;
foreach (tblDocument v in query)
{
if (v.DocumentNo.Length > maxs)
maxs = v.DocumentNo.Length;
}
foreach (tblDocument vv in query)
{
string doctitle = vv.DocumentNo;
for (int i = vv.DocumentNo.Length; i < maxs; i++)
{
doctitle += " ";
}
doctitle += " | ";
doctitle += vv.TITLE;
// Use HtmlDecode to correctly show the spaces
doctitle = HttpUtility.HtmlDecode(doctitle);
ddlProjectDocument.Items.Add(new ListItem(doctitle, vv.DocId.ToString()));
}
}
First, I would highly recommend storing the result of that query at the beginning of the method into something like a session variable so that you don't have to continually query the database every time you hit this page.
Second, you should use the OnTextChanged event in ASP.NET to solve this problem. Put in the OnTextChanged attribute to point to a method in your code behind that will grab the query result values (now found in your session variable) and will reset what is contained in ddlProjectDocument.Items to anything that matched what was being written by using String.StartsWith():
var newListOfThings = queryResults.Where(q => q.DocumentNo.StartsWith(MyTextBox.Value));
At this point all you need to do is do that same loop that you did at the end of the method above to introduce the correct formatting.

Duplicate values in multiple textbox

How to validate whether the text in multiple textboxes are unique from each other.
It looks like that in asp.net but its not a valid syntax
bool hasNoDuplicate = (txtEmergencyName1.Text.Trim() <> txtEmergencyName2.Text.Trim() <> txtEmergencyName3.Text.Trim <> txtEmergencyName4.Text.Trim);
I am looking for an efficient appraoch, kind of lambda expression or inbuilt in asp.net
Since you're asking for lambda, here's a linq approach.
var allTxt = new[] { txtEmergencyName1, txtEmergencyName2, txtEmergencyName3, txtEmergencyName4 };
var allText = allTxt.Select((txt, i) => new { Text = txt.Text.Trim(), Pos = i + 1 }).ToList();
bool hasNoDuplicate = !allText.Any(t => allText.Skip(t.Pos).Any(t2 => t.Text == t2.Text));
Put all relevant TextBoxes in a collection like an array and use Enumerable.Any. By skipping all before the current textbox you avoid checking the TextBoxes twice.
If all relevant TextBoxes are in a container control like a Panel, you could also use Enumerable.OfType to find them:
IEnumerable<TextBox> allTxt = this.EmergencyPanel.Controls.OfType<TextBox>();
Side-note: it's premature optimization anyway to look for the most performant way to validate some controls. This is nothing what you are doing constantly and there are never millions of controls. Instead you should look for the shortest or most readable approach.
You can use and && or or || operator accordingly
bool isDuplicate=(txtEmergencyName1.Text.Trim() == txtEmergencyName2.Text.Trim()
&& txtEmergencyName2.Text.Trim() == txtEmergencyName3.Text.Trim);
it will set true or false in the isDuplicate variable.
Edit 1
bool isDuplicate=(txtEmergencyName1.Text.Trim() == txtEmergencyName2.Text.Trim()
&& txtEmergencyName2.Text.Trim() == txtEmergencyName3.Text.Trim
&& txtEmergencyName1.Text.Trim() == txtEmergencyName3.Text.Trim
);
You could also do something like
var test = new TextBox();
var AlltBox = new List<TextBox>() { new TextBox() };
for(int i=1; i == 5;i++)
AlltBox.Add((TextBox)this.FindName("txtEmergencyName"+i));
bool exist = AlltBox.Any(tb => ((tb.Text == test.Text)&& tb.Name != test.Name));
but i don't know about the performance

Compare Validator for two dates

I have two labels and two text boxes, a Compare validator and a button.
I need it to compare two dates (rental date , return date ) and when the rental date is less or equal to return date are the same. No validation message.
While when when the rental date is less than the return date, display an input error message.
The compare validator has been set with :
controltocompare : txtrental,
controltovalidate: txtreturndate,
operator :greater than equal,
type:date,
errormessage: return date must be greater or equal than rental date,
I am not sure how to get the btn to display it ?
You need to set the property "CausesValidation" of your button to "true" to trigger validation on its click.
Make sure the CompareValidator has runat="server"
Create a method to display message.
private void AlertBox(string Msg)
{
string s = "alert('" + Msg + "')";
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "ckey", s, true);
}
find the code to validate and throw alert message.
if (!String.IsNullOrEmpty(txtrental.Text) && !String.IsNullOrEmpty(txtreturndate.Text))
{
DateTime ssSD = Convert.ToDateTime(txtrental.Text);
DateTime qsED = Convert.ToDateTime(txtreturndate.Text);
int chktxtfd1_sd = ssSD.CompareTo(qsSD);
if ((chktxtfd1_sd == 0 || chktxtfd1_sd == -1) )
{
//do something bcoz condition is true
}
else
{
lvflag = false;
AlertBox("date must be greater or equal than rental date");
}
}
If you find it useful, please mark it as your answer else let me know...

Insert a control before another control inside a ItemDataBound event

I tried to Solution suggested here, but it didn't work in my case. using Page.Controls.IndexOf() for any of the elements on my page, when called in the ItemDataBound event method, returns -1.
I need to insert a linebreak based on certain conditions for stuff generated by my Data repeater. Here is the method:
private String lastCharacter = "";
public void users_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
HyperLink link = (HyperLink)e.Item.FindControl("micrositeLink");
Tuple<String, String> user = (Tuple<String, String>)e.Item.DataItem;
link.NavigateUrl = "/" + user.Item1;
link.Text = user.Item2;
// makes a break in the data when going from one bunch of data to another.
if (user.Item1.Length >= 2)
{
if (lastCharacter == "")
lastCharacter = user.Item1[1].ToString().ToLower();
else if (lastCharacter != user.Item1[1].ToString().ToLower())
{
HtmlGenericControl lineBreak = new HtmlGenericControl("br");
if (Page.Controls.IndexOf(link) >= 0)
Page.Controls.AddAt(Page.Controls.IndexOf(link), lineBreak);
lastCharacter = user.Item1[1].ToString().ToLower();
}
}
}
The bound data is a list of users in my system with names beginning with a particular letter. My goal is to further sub-divide this data with a line break between groups of data that have the same second letter. For instance:
AaPerson Aarad AaStuff
Aathing
AbItem AbStuff
Acan Achandle
To me, inserting a line break before the elements where the second letter changes is the obvious solution, but other suggestions are also appreciated.
Try using e.Item.Controls.IndexOf instead:
if (e.Item.Controls.IndexOf(link) >= 0)
e.Item.Controls.AddAt(e.Item.Controls.IndexOf(link), lineBreak);

Gridview remove items

I have I gridview in which the data source is a List<T>. When I try to remove an item from the gridview in my buttonRemove_Click() function another function which handles the RowDeleting event is invoked where I remove the item from the List<T> as well. The problem is that if I select to remove multiple items from the gridview the index of the gridview and that of my List<T> un-syncs. For example I have 10 items in my gridview and in my List and I try to remove the last two items. Here is how I do it in my buttonRemove_Click function
foreach (GridViewRow row in gridViewItems.Rows)
{
CheckBox cb = (CheckBox)row.FindControl("checkBox");
if (cb != null && cb.Checked)
{
gridViewItems.DeleteRow(row.DataItemIndex);
}
}
Then in the RowDeleting function, I'll first receive the event for the index 8, I removed it. Now when it comes to deleting the last item (index 9), then it'll throw exception because the index is out of range. How do I solve this problem?
I think the problem will be solved if I try removing the rows in reverse order i.e. starting from the highest index. Can anyone tell how can this be done?
GVGLCode1.DataSource = dt;
GVGLCode1.DataBind();
int iCount = GVGLCode1.Rows.Count;
for (int i = 0; i <= iCount; i++)
{
CheckBox cb = (CheckBox)GVGLCode1.rows[i].FindControl("checkBox");
if (cb != null && cb.Checked)
{
GVGLCode1.DeleteRow(i);
}
}
Please try with this.
May be it can help u.

Resources