Implementing search page - asp.net

I'm new to ASP.Net and trying to implement a search page in my project.
I created a simple search.aspx
<asp:TextBox runat="server" ID="txtSearch" MaxLength="250"/>
<asp:LinkButton ID="lnkSearch" runat="server" Text="Search" OnClick="Search_Click" ClientIDMode="Static" />
<asp:Repeater ID="rep" runat="server" >
....
</asp:Repeater>
and the search.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
txtSearch.Text = Request.Params["q"].ToString();
BindRepeater(); //reads Request.Params["q"] and fetches data
txtSearch.Focus();
this.Page.Form.DefaultButton = this.lnkSearch.UniqueID;
}
protected void Search_Click(object sender, EventArgs e)
{
Response.Redirect("/Search.aspx?q=" + txtSearch.Text);
}
Problem is that when I type something in txtSearch and hit enter or click search, the page reloads with the old query string and old search results, seems that txtSearch.Text is updated with old Query value before hitting Search_Click
For Example if I enter search.aspx?q=apple in address bar the page returns correct results and txtSearch's Text = "apple" .. if I type green apple and hit enter, page returns apple results, and txtSearch's Text = "apple", also the link is search.aspx?q=apple
I tried
AutoPostBack="True|False" for the TextBox
if (!IsPostBack)
txtSearch.Text = Request.Params["q"].ToString();
but I can't use it I guess since I'm posting back to same page, no?
I also tried
if (IsPostBack && txtSearch.Text != Request.Params["q"].ToString())
txtSearch.Text = Request.Params["q"].ToString();

This seems a strange way of doing it to me.
My preference would be to have the search logic in the event handler itself, rather than implementing this strange post-back loop.
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack == false)
{
// If passed in on first entry to the page
var searchQuery = Reqest.Params["q"];
if (String.IsNullOrWhitespace(searchQuery) == false)
{
txtSearch.Text = searchQuery;
Search_Click(null, null);
}
}
txtSearch.Focus();
this.Page.Form.DefaultButton = this.lnkSearch.UniqueID;
}
protected void Search_Click(object sender, EventArgs e)
{
// Pass the value of the search to the repeater
BindRepeater(txtSearch.Text);
}
Note that I'm passing the search text to BindRepeater so you'd have to update it to use the parameter value rather than query string

Related

CheckBox on a GridView

I have a grid view that has 3 columns(Name, Address, Status) and a checkbox.The Status has 3 properties, Active, Pending, and Disabled. The page load all the information from the database. When loading the page, only accounts that are ACTIVE should be displayed (and the checkbox should remain unchecked)
When clicking the checkbox, the page should load the DISABLED, along with the accounts already displayed When the page loads for the first time.
Aspx:
<asp:CheckBox ID="ChkBox1" runat="server" AutoPostBack="true" OnCheckedChanged="cbShowAllColumn_Changed" TextAlign="Right" Text="Show All"/>
</asp:Panel>
Code behind:
protected void cbShowColumn_Changed(object sender, EventArgs e)
{
string columnName = (sender as CheckBox).ID.Substring(1);
gvTest.Columns[(int)Enum.Parse(typeof(AccountColumns), columnName)].Visible = (sender as CheckBox).Checked;
}
protected void cbShowAllColumn_Changed(object sender, EventArgs e)
{
bool _checked = (sender as CheckBox).Checked;
foreach (Control ctrl in pAccount.Controls)
if (ctrl is CheckBox)
{
(ctrl as CheckBox).Checked = _checked;
gvMain.Columns[(int)Enum.Parse(typeof(AccountColumns), (ctrl as CheckBox).ID.Substring(2))].Visible = _checked;
}
}
I compiled a small asp .net page to do what you asked.
Note: In your project, you should probably take the "source" out of the BindGrid method, so that you don't "get" the data from scratch every time the page is posted back to. I did it that way because I used an anonymous type.
Note #2 I converted an int to your enum and then to a string. Since you use real data you should handle that differently, by using the enum itself.
Markup:
<asp:CheckBox ID="ChkBox1" runat="server" AutoPostBack="true" OnCheckedChanged="cbShowAllColumn_Changed" TextAlign="Right" Text="Show All"/>
<br/>
<asp:gridview ID="gvMain" runat="server" >
</asp:gridview>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
BindGrid(false);
}
private void BindGrid(bool showActiveOnly)
{
var source = Enumerable.Range(1, 10)
.Select(number => new { number, status = (Enum.ToObject(typeof(Statuses), number % 3)).ToString() });
var filteredSource = source.Where(x => x.status == "Active" || !showActiveOnly);
gvMain.DataSource = filteredSource;
gvMain.DataBind();
}
protected void cbShowAllColumn_Changed(object sender, EventArgs e)
{
bool _checked = (sender as CheckBox).Checked;
BindGrid(_checked);
}
private enum Statuses
{
Active,
Pending,
Disabled
}

How to output current user's AD sAMAccountName to a textbox

I'm designing an eform that submits information into a CSV. I need to display the current user's sAMAccountName and the Datetime.Today in two of the text fields.
Any idea of how this would be done?
I've been trying: c#
public string UserName { get { return Session["UserName"]; } }
to:
<asp:TextBox ID="UserName" runat="server" Width="44px" ReadOnly="true"></asp:TextBox>
You can pre-populate input values in your form in the Page_Load event:
protected void Page_Load(object sender, EventArgs e) {
UserName.Text = "my value";
TxtCurrentDate.Text = DateTime.Today.ToString();
}
Just augmenting this quickly with another bit of info, I was originally adding the Page_Load cmds to the codebehind's Page_load event, be sure that all prepopulation of text-boxes is handled on the .aspx page.
All contained within the .aspx
protected void Page_Load(object sender, EventArgs e)
{
txtDate.Text = DateTime.Now.ToString();
}
<td><asp:TextBox ID="txtDate" runat="server" Width="181px" ReadOnly="true"></asp:TextBox></td>
Thanks again for the helpful reply mellamokb

asp.net editing data

I'm reading data from database and showing it in a page for editing:
<h2>Create new topic:
<asp:Label ID="_lblTopicName" runat="server" Text=""></asp:Label></h2>
<p>
Edit Level:
<br/>
<asp:DropDownList ID="_dtlEditRole" runat="server"></asp:DropDownList>
<br/>
View Level:
<br/>
<asp:DropDownList ID="_dtlViewRole" runat="server"></asp:DropDownList>
<br/>
<asp:TextBox ID="_tbxTopicText" TextMode="MultiLine" runat="server" Height="204px"
Width="885px"></asp:TextBox>
</p>
<asp:Button ID="_btnSaveTopic" runat="server" Text="Save" onclick="_btnSaveTopic_Click" />
I fill the fields in Page_PreRender() like so:
private string _topicString;
private Topic _topic = null;
private Topics_GetTopicByTopicResult _findTopicResults = null;
protected void Page_PreRender(object sender, EventArgs e)
{
// Load the User Roles into checkboxes.
_dtlEditRole.DataSource = Roles.GetAllRoles();
_dtlEditRole.DataBind();
_dtlViewRole.DataSource = Roles.GetAllRoles();
_dtlViewRole.DataBind();
_topicString = Request.QueryString["Topic"];
if (String.IsNullOrEmpty(_topicString))
{
Response.Redirect("~/Default.aspx");
}
else
{
_topic = new Topic();
_findTopicResults = _topic.FindTopic(_topicString);
if (_topic != null)
{
// Check if the user has permission to access
if (RoleHelper.IsEditAllowed(_findTopicResults.ViewRoleName))
{
_lblTopicName.Text = _findTopicResults.Topic;
_tbxTopicText.Text = _findTopicResults.Text;
_dtlEditRole.SelectedValue = _findTopicResults.EditRoleName;
_dtlViewRole.SelectedValue = _findTopicResults.ViewRoleName;
}
else
{
Response.Redirect("~/Error.aspx?ReturnUrl=" + HttpUtility.UrlEncode(Request.RawUrl));
}
}
else
{
Response.Redirect("~/CreateTopic.aspx?Topic=" + _topicString);
}
}
}
But now when i click _btnSaveTopic button the fields:
private string _topicString;
private Topic _topic = null;
private Topics_GetTopicByTopicResult _findTopicResults = null;
They are all NULL and im not able to update aything.
Here's my button click event:
protected void _btnSaveTopic_Click(object sender, EventArgs e)
{
_topic.UpdateTopic(_findTopicResults.ID, _findTopicResults.Topic, _tbxTopicText.Text,
_dtlViewRole.SelectedItem.Text, _dtlEditRole.SelectedItem.Text);
Response.Redirect("~/ViewPage.aspx?Topic=" + _topicString);
}
What would be the right way doing this?
ASP.NET Page Life Cycle states that Page_Init should be used to 'initialize control properties' which looks like what you are doing.
Also, it's usually good practice to breakup such large sections of code into smaller refactored methods. Try to keep the amount of code directly placed in event handlers to a minimum.
You can start by right-clicking a section of highlighted code in visual studio -> refactor -> extract method
Also, if you need more help understanding how to improve your code, you should ask a question pointing to this question on the code review site: here
You are re-binding the drop down list (and therefore wiping out the 'SelectedValue') in your Page_PreRender method. Wrap the method in
protected void Page_PreRender(object sender, EventArgs e)
{
if( !IsPostBack){
//your current code
}
}
and it should work.

Ajax CalendarExtender, How to get the date after i click on a button?

I want to add add an Ajax CalendarExtender to my page. And then after selecting a date and clicking on a button I get the selected Day in a label.
I have a text box which is the target of the CalendarExtender
<asp:TextBox ID="DateText" runat="server" ReadOnly="true" ></asp:TextBox>
<ajaxToolkit:CalendarExtender
ID="Calendar1"
runat="server"
TargetControlID="DateText"
Format="MMMM d, yyyy"
PopupPosition="Right"
/>
<asp:Button runat="server" ID="Button1" onclick="Button1_Click" />
In the Code Behind:
On the first page load I set the date to Today.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Calendar1.SelectedDate = DateTime.Today;
}
}
In the Button1_Click Event
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = Calendar1.SelectedDate.Value.Day.ToString();
}
The problem is when I click the button (or after any post backs) the value selected get reset to Today's date.
And if I don't set it to DateTime.Today in the Page_Load It get reset to null and throw a null exception.
How can I solve this?
Thank you very much for any help.
I hope i was clear
Maybe this will work:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if(!Calendar1.SelectedDate)
Calendar1.SelectedDate = DateTime.Today;
}
}
The solution to the issue is making use of Request.Form collections. As this collection has values of all fields that are posted back to the server and also it has the values that are set using client side scripts like JavaScript.
Thus we need to do a small change in the way we are fetching the value server side.
C#
protected void Submit(object sender, EventArgs e)
{
string date = Request.Form[txtDate.UniqueID];
}

ListBox retains posted value even after being databound

Please note that the problem described below is almost the exact opposite to the common problem of "my control shows the same value every time the page loads. I understand the behavior expressed is generally not desirable.
I have a listbox which is being databound in the page load event even on postback.
When the event handler for the selectedindex changed is hit, the control somehow has the posted value even though it has already been bound again and should not have a selectedindex at this point.
Does anyone know how this could be possible.
EDIT:
To demonstrate that the SelectedIndex is indeed reset you can create a form with the following simple markup:
<label for="textbox1">Original Posted Value: </label>
<asp:TextBox runat="server" ID="textbox1" />
<asp:DropDownList runat="server" ID="dropdown" OnSelectedIndexChanged="dropdown_SelectedIndexChanged" AutoPostBack="true" />
<label for="textbox2">Value at point handler is hit: </label>
<asp:TextBox runat="server" ID="textbox2" />
With the following code in the .cs
protected void Page_Load(object sender, EventArgs e)
{
textbox1.Text = dropdown.SelectedIndex.ToString();
dropdown.DataSource = new string[] { "none", "A", "B", "C" };
dropdown.DataBind();
}
protected void dropdown_SelectedIndexChanged(object sender, EventArgs e)
{
textbox2.Text = dropdown.SelectedIndex.ToString();
}
Notice that the value in the second textbox will alway be 0.
The problem here is that the datasource is getting re-assigned and re-bound on each page load including postbacks. The selected index is changed and then changed back to 0.
Try cathcing the postbacks, and only set the datasource if it is not a postback (the initial load) such as this in the .cs
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
textbox1.Text = dropdown.SelectedIndex.ToString();
}
else
{
dropdown.DataSource = new string[] { "none", "A", "B", "C" };
dropdown.DataBind();
}
}
protected void dropdown_SelectedIndexChanged(object sender, EventArgs e)
{
textbox2.Text = dropdown.SelectedIndex.ToString();
}

Resources