I am implementing a grid view and putting a textbox in the Headers to be able to filter the data for each column. I have the following code for the ontextchanged trigger for every textbox.
protected void Filter_TextChanged(object sender, EventArgs e)
{
string ColumnName = ((TextBox)sender).Attributes["EventArg"];
string FilterValue = ((TextBox)sender).Text;
if (string.IsNullOrEmpty(FilterValue))
{
EntityDataSource1.Where = "";
}
else
{
int dummy;
if (int.TryParse(FilterValue, out dummy))
{
EntityDataSource1.Where = "it." + ColumnName + " = " + FilterValue;
}else
{
EntityDataSource1.Where = "it." + ColumnName + " Like '%" + FilterValue + "%'";
}
}
}
The aspx is as follows
<asp:TextBox ID="txtCaseNr" runat="server" CssClass="form-control" OnTextChanged="Filter_TextChanged" AutoPostBack="true" TextMode="Number"></asp:TextBox>
Everything works so far except that to prevent text being written at textboxes expecting integers i set the textmode=number. And it is not being triggered when the textbox is emptied to remove the filter.
I hope my problem is clear. Any solutions are welcome.
Thanks,
Related
I am having the following problem: I want to call a method whenever a specific li is clicked. Problem is that the li is dynamically created in a literal.text string, where I do import things from my database.
Whenever I try to call a method it does not work. I want to call a method whenever the user clicks on each li and get that li information inside my method (haven't wrote the method code yet, because I can't get it called.)
Thoughts?
protected void Page_Load(object sender, EventArgs e)
{
string conString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source="
+ Server.MapPath("~/ebookstoredb.mdb");
using (OleDbConnection con = new OleDbConnection(conString))
{
con.Open();
string query = "SELECT * FROM CATEGORY";
using (OleDbCommand cmd = new OleDbCommand(query, con))
{
OleDbDataReader reader = cmd.ExecuteReader();
String msg = "";
while (reader.Read())
{
lit1.Text += "<ul>" + "<li runat=\"server\" OnClick=\"ProductsInfo\">" + reader["ID"]
+ "," + reader["Name"]
+ "</li>"
+ "</ul>";
}
reader.Close();
}
con.Close();
}
}
protected void ProductsInfo(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}
Unfortunately, you cannot create server-side events on a Literal Control.
However, you can add client-side javascript functionality to post back a request.
In your aspx using:
<div>
<asp:Literal runat="server" ID="lit1"></asp:Literal>
</div>
Your aspx.cs should contain:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lit1.Text += "<ul>" + "<li \' onclick=\'javascript: __doPostBack(\"getProduct\", \"1\");\'>"
+ "Product " + "1"
+ "</li>"
+ "</ul>";
}
if (Request.Form["__EVENTTARGET"] != null && Request.Form["__EVENTTARGET"] == "getProduct")
{
getProduct_Click(null, null);
}
}
private void getProduct_Click(object sender, System.EventArgs e)
{
Response.Write("You Clicked on " + Request.Form["__EVENTARGUMENT"]);
}
This will set up each li to pass their own value to the event argument hidden control and perform a postback to the server.
You can then check if the event target is the required one and call a method with the value that was posted back.
Just change the sample lit1 text above to iterate through your data.
I've never used literals before, but from reading about them... with a literal displaying just static html, you will need to have each li call a javascript function that will then do a postback to the method you want. So build your li like this:
lit1.Text += "<ul><li><a onclick=\"CallProductInfo(" + reader["ID"]+ ")\">" + reader["ID"]
+ "," + reader["Name"]
+ "</a></li></ul>";
Then you have to have a javascript function that does the actual postback to your server side code or redirects to the products info page with the passed id. That is, in your page (not the code behind), have a script something like this for the postback...
<script>
function CallProductInfo(id)
{
__doPostBack('ProductInfoId', id);
}
</script>
In you code behind, in your page load event handler, you'd have something like this:
if (Request["__EVENTTARGET"] == "ProductInfoId")
{
ProductInfo(Convert.ToInt64(Request["__EVENTARGUMENT"]));
}
Ok so guys i found out what was the problem. Our mr.genious instructor told us today that we can use a datagrid..Sigh.
Thanks everyone for your replies!
I'm new in ASP.NET; I have a DropDownList in a page (with a masterpage):
<asp:DropDownList ID="cmbPrueba" runat="server" OnSelectedIndexChanged="cmbPrueba_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Value="0">Compresor de Aire</asp:ListItem>
<asp:ListItem Value="1">Compresor/Unidad de Refrigeración</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="btnActualizar" runat="server" Text="Actualizar" OnClick="btnActualizar_Click" />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
Depending of the DropDownList (cmbPrueba) the placeHolder creates controls using the string array; (I made the string arrays simulating string result of database).
So, if I take itemIndex=0 ("CompresorDeAire) I will create: "TextBox", "Calendar", "TextBox";
if I take index=1 (CompresorUnidadDeRefrigeracion ) the controls are: "DropDownList", "TextBox", "Calendar", "Calendar", "TextBox"... but there is a "DropDownList" control, so I will full it with this info:
private string[] CompresorUnidadDeRefrigeracionTipoCompresor = new string[] { "Compresor Alternativo", "Compresor de Tornillo", "Unidad de Refrigeración" };
And so on. Here is the code:
public partial class Controles : System.Web.UI.Page
{
private Label _Label;
private TextBox _TextBox = new TextBox();
private Calendar _Calendar = new Calendar();
private DropDownList _DropDownList = new DropDownList();
private string[] CompresorDeAire = new string[] { "TextBox", "Calendar", "TextBox" };
private string[] CompresorUnidadDeRefrigeracion = new string[] { "DropDownList", "TextBox", "Calendar", "Calendar", "TextBox" };
private string[] CompresorUnidadDeRefrigeracionTipoCompresor = new string[] { "Compresor Alternativo", "Compresor de Tornillo", "Unidad de Refrigeración" };
private string[] BombaElectrica = new string[] { "TextBox", "TextBox", "TextBox", "TextBox", "TextBox", "TextBox" };
protected void Page_Load(object sender, EventArgs e)
{
LoadInfo(CompresorDeAire);
}
private void LoadInfo(string[] Arreglo)
{
for (int i = 0; i < Arreglo.Length; i++)
{
_Label = new Label();
_TextBox = new TextBox();
_Calendar = new Calendar();
_DropDownList = new DropDownList();
_Label.Text = Arreglo[i].ToString() + i.ToString();
_Label.ID = _Label.Text;
PlaceHolder1.Controls.Add(_Label);
PlaceHolder1.Controls.Add(new LiteralControl("<br />"));
if (Arreglo[i] == _TextBox.GetType().Name.ToString())
{
_TextBox.ID = "txt" + _Label.ID;
//_TextBox.AutoPostBack = true;
PlaceHolder1.Controls.Add(_TextBox);
}
else if (Arreglo[i] == _Calendar.GetType().Name.ToString())
{
_Calendar.ID = "cln" + _Label.ID;
PlaceHolder1.Controls.Add(_Calendar);
}
else if (Arreglo[i] == _DropDownList.GetType().Name.ToString())
{
_DropDownList.ID = "cmb" + _Label.ID;
//_DropDownList.AutoPostBack = true;
foreach (var item in CompresorUnidadDeRefrigeracionTipoCompresor)
{
int j = 0;
_DropDownList.Items.Add(item);
j++;
}
PlaceHolder1.Controls.Add(_DropDownList);
}
PlaceHolder1.Controls.Add(new LiteralControl("<br /><br />"));
}
}
protected void cmbPrueba_SelectedIndexChanged(object sender, EventArgs e)
{
txtMensaje.Text = "";
PlaceHolder1.Controls.Clear();
switch (cmbPrueba.SelectedIndex)
{
case 0:
this.LoadInfo(CompresorDeAire);
break;
case 1:
this.LoadInfo(CompresorUnidadDeRefrigeracion);
break;
case 2:
this.LoadInfo(BombaElectrica);
break;
}
}
protected void btnActualizar_Click(object sender, EventArgs e)
{
txtMensaje.Text = "";
for (int i = 0; i < PlaceHolder1.Controls.Count; i++)
{
switch (PlaceHolder1.Controls[i].GetType().Name.ToString())
{
case "TextBox":
TextBox TB = PlaceHolder1.FindControl(PlaceHolder1.Controls[i].ID) as TextBox;
txtMensaje.Text += PlaceHolder1.Controls[i].GetType().Name + " " + PlaceHolder1.Controls[i].ID + " " + TB.Text + "\n";
TB.Text += "*";
break;
case "Calendar":
Calendar Cal = PlaceHolder1.FindControl(PlaceHolder1.Controls[i].ID) as Calendar;
txtMensaje.Text += PlaceHolder1.Controls[i].GetType().Name + " " + PlaceHolder1.Controls[i].ID + " " + Cal.SelectedDate.ToShortDateString() + "\n";
break;
case "DropDownList":
DropDownList DD = PlaceHolder1.FindControl(PlaceHolder1.Controls[i].ID) as DropDownList;
txtMensaje.Text += PlaceHolder1.Controls[i].GetType().Name + " " + PlaceHolder1.Controls[i].ID + " " + DD.Text + "\n";
break;
}
}
}
protected void btnLimpiar_Click(object sender, EventArgs e)
{
PlaceHolder1.Controls.Clear();
txtMensaje.Text = "";
}
}
When I run the code by default is Index = 0 , I use the textbox and calendar, and click "Actualizar" and I can see the info in the text box, when I choose Index=1 (and load the 2nd array) all the new controls show up, but if I choose a date or I write in the textbox and click in the buttom "Actualizar" the page return to the previous page (array 1).
I appreciate your help! thanks.
I am assuming that when you say “the page return to the previous page (array 1).” That you mean the first array (in the zero-th element)
The problem is that .NET will not automatically re-create the dynamic controls for you on the post back. You have to handle that.
Here are the basic steps for the first page request:
Execute the Page_load event, which calls LoadInfo for CompresorDeAir.
Then when you selected a different entry in the dropdown and then click Actualizer button then it does a post back with these basic steps:
Execute the Page_load event, which calls LoadInfo for CompresorDeAir.
Execute cmbPrueba_SelectedIndexChanged which throws away the dynamic controls that were added in the page load and loads the control for the selected index.
Execute btnActualizer_Click event which shows the controls in the dynamic place holder, these being the ones for the selected dropdown value.
Then when you change the text or date and then click Actualizer button it does these steps:
Execute the Page_load event, which calls LoadInfo for CompresorDeAir.
Execute btnActualizer_Click event which shows the controls in the dynamic place holder. In this case the ones from the page load are shown. the controls from the prior selected dropdown list item do not get created.
The only time the controls from the selected item in the dropdown list are added to the place holder is when the selected item changes for the dropdown.
The solution is put a hidden variable in the form to hold the last selected item from the drop down. Everytime the selected index changes then update this hidden value. In the page load event, on a postback, load the appropriate array based on that hidden value.
I've been struggling with this C# problem all night.
I have a override ToString(), which is working fine, and I can put my data out in a ListBox. But as the data is very long, with a bunch of classes, the output becomes long.
I wanted to be able to break my ListBox output into multiplelines.
Here is the override in the class file:
//ToString
public override string ToString()
{
return "Name " + firstName + lastName + ". Nationality " + nationality + ". Lives in " + address + " " + zipCode + " " + city + " " + country + "."//
+ " Height is " + height + " meters. Hair color is " + hairColor + " and eye color is " + eyeColor + ". Specialmarkings: "//
+ specialMark + ". Is associated with " + association + ". Codename is " + codeName + "Photo (filename): " + photo;
}
Here is the index code:
public partial class Index : System.Web.UI.Page
{
static ArrayList personarraylist;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
personarraylist = new ArrayList();
}
}
protected void ButtonCreate_Click(object sender, EventArgs e)
{
//create new object
Person p = new Person(TextBox1FirstName.Text, TextBox2LastName.Text, TextBox3Nation.Text, TextBox4Address.Text, //
TextBox5City.Text, TextBox7Country.Text, //
TextBox10HairColor.Text, TextBox11EyeColor.Text, TextBox12SpecialMark.Text, TextBox13Asso.Text, TextBox14Codename.Text, TextBox15Photo.Text, //
Convert.ToDouble(TextBox9Height.Text), Convert.ToInt32(TextBox6ZipCode.Text), Convert.ToInt32(TextBox8Pass.Text));
//add object to arraylist
personarraylist.Add(p);
}
protected void ButtonShow_Click(object sender, EventArgs e)
{
//clear list box
ListBox1.Items.Clear();
//loop through Arraylist
for (int i = 0; i < personarraylist.Count; i++)
{
ListBox1.Items.Add(personarraylist[i].ToString());
ListBox1.Items.Add("");
TextBox1.Text = "";
}
}
}
Is it possible to break the output in multiplelines in a ListBox?
I was trying to inject some html breaktags in the override return, but these get stripped, yeah this is a webapplication.
Thanks in advance for your time.
PS I am a newbie in C# (Student), so be kind ;)
UPDATE:
Hi again all, thx for the help, I already tried with Environment.Newline and the other solutions, but these seem to be overlooked when displaying the text in a ListBox. I can see the breakpoints in the codebehind, but in the browser the listbox still just keeps it all in one line. So I decided to use a TextBox instead, which breaks the text automaticly and where I point out.
//loop through Arraylist
for (int i = 0; i < personarraylist.Count; i++)
{
TextBox1.Text += personarraylist[i].ToString();
}
Again thx for the help :-)
You can use Environment.NewLine or simply "\n" to create multiple lines of text.
If that doesn't work, you can try using the DataList control:
<asp:DataList id="myDataList" runat="server">
<ItemTemplate>
Line 1
<br />
Line 2
</ItemTemplate>
</asp:DataList>
namespace KetBanBonPhuong.Controls.Default
{
public partial class SugFriends : System.Web.UI.UserControl
{
private string Uid;
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Cookies["UId"] != null)
{
string value = Request.Cookies["UId"].Value;
Uid = UserService.GetId_Cookie(value);
}
else
{
Uid = Session["Id"].ToString();
}
LoadListSuggest();
}
private void LoadListSuggest()
{
string str = "";
List<RankByUser> list = new List<RankByUser>();
list = RankByUserService.GetListRank(Uid);
foreach (RankByUser rank in list)
{
str += "<li><div class=\"sug_acc\">"
+ "<img src=\"" + rank.Avatar + "\" alt=\"avatar\"/>"
+ "" + rank.LastName + " " + rank.FirstName + ""
+ "</div>"
+ "<div class=\"rank\">"
+ "rank: " + rank.Rank + ""
+ "Kết bạn"
+ "</div></li>";
}
ltrListSug.Text = str;
}
}
}`
It's a user control SugFriends.ascx being add in Default.Master
When I click "a.button" postback event to server?(I want to insert data to database, I used Sql server)
How to do it? Make tag a event onclick 'like' LinkButton: Onclick()?
Thanks for your helping! I found solution that problem! I used Ajax onclick for each tag a, event post Ajax.aspx, in here I can code work with database!
Add an onclick="(javascript:__doPostBack('','');" attribute to the <a> tag to perform a postback via Javascript. Like this:
+ "Kết bạn"
More details here
Response to comment:
Try creating a button on the page
<asp:Button ID="btnPlaceHolder" Visible="False" runat="server" /> and then do what I said in this solution but instead use __doPostBack('<%=btnPlaceHolder.UniqueID %>', '')
From there, you can use the method block
Private Sub btnPlaceHolder_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPlaceHolder.Click to run the code you want on postback.
In my code I create the menu items dynamically:
string listClientID = BulletedList1.ClientID.Replace('_', '$');
int counter = 0;
foreach (DataRow dataRow in database.DataTable.Rows)
{
// Add Button
ListItem listItem = new ListItem();
listItem.Value = "buttonItem" + Convert.ToString(dataRow["rank"]);
listItem.Text = " " + Convert.ToString(dataRow["title"]);
listItem.Attributes.Add("onclick", "__doPostBack('" + listClientID + "', '"+ counter.ToString() +"')");
BulletedList1.Items.Add(listItem);
counter++;
}
This menu is inside a update panel:
<div id="MenuItemBox">
<asp:BulletedList
ID="BulletedList1"
runat="server"
OnClick="MenuItem_Click"
>
</asp:BulletedList>
</div>
What I want is when a listitem is clicked it performs a postback. But when I run this, the onclick event is only runned once.
For example. I have 4 listitems. When I click the first item the first time the onclick event is executed. Now I click the second item, the onclick event is also executed. But when I now click the first item again the onclick event is not fired.
When I check the error console in FireFox or Oprah I don't get any errors.
So my question is: how can I fix this and what am I doing wrong?
It seems you need to rebind it after postback.
Where do you add items to the menu and are you checking IsPostBack property?
Please compare html after first loading and postpack to see if _dopostback dissappear.
Then Try to remove IsPostBack check.
My code is working well.
Here is it.
public partial class _Default : System.Web.UI.Page {
protected void Page_Load (object sender, EventArgs e) { }
protected override void OnInit (EventArgs e) {
base.OnInit(e);
//if (!IsPostBack) {
string listClientID = BulletedList1.ClientID.Replace('_', '$');
int counter = 0;
List<SomeClass> items = new List<SomeClass>(){ new SomeClass() { Rank = 1, Title = "2"},
new SomeClass () {Rank = 2, Title = "Two"}};
foreach (var item in items) {
// Add Button
ListItem listItem = new ListItem();
listItem.Value = "buttonItem" + item.Rank;
listItem.Text = " " + item.Title;
listItem.Attributes.Add("onclick", "__doPostBack('" + listClientID + "', '" + counter.ToString() + "')");
BulletedList1.Items.Add(listItem);
counter++;
}
//}
}
protected void MenuItem_Click (object sender, BulletedListEventArgs e) {
Response.Write(e.Index);
}
class SomeClass {
public int Rank;
public string Title;
}
}
Probably UpdatePanel is causing the trouble. I would try pulling it out of UpdatePanel and then would see(which I believe it should) if that works?
Secondly, you can probably just populate the list items Values and Texts only, and then under mnuMainMenu_MenuItemClick(object sender, MenuEventArgs e) event; look for the specific item that has been clicked (e.Item.* public properties), and then probably would use Response.Redirect() to do the job; well, just thinking out loud...