I'm creating a really simple "tag cloud" function for a project database. I want the user to be able to check various tags and, then, with an autopostback on the checked box(es), display the associated projects that have those tags.
It works, but the checkboxes are resetting after postback. I want the checkboxes to remain checked (or unchecked, as the case may be) so the user can select multiple tags.
I've searched and seen that some say to put the databinding event within an if(!isPostBack). I've tried that, but it doesn't seem to matter.
aspx code:
<asp:DataList ID="TagDataList" runat="server" OnDataBinding="databindthesucker" DataKeyField="TagName">
<ItemTemplate>
<asp:CheckBox AutoPostBack="true" ID="TagCheckbox" runat="server" Text='<%#Eval ("dZTagName") %>' />
<asp:HiddenField ID="TagNameHidden" runat="server" Value='<%#Eval ("dZTagName") %>'/><br />
</ItemTemplate>
</asp:DataList>
<asp:DataList ID="ProjectDataList" runat="server" DataKeyField="projectID">
<ItemTemplate>
<asp:HyperLink ID="ProjectLink" runat="server" NavigateUrl='<%# "/Project/Default.aspx?PID=" + Eval ("projectID") %>' Text='<%# Eval ("projectID") + ": " + Eval ("projectName") %>'> </asp:HyperLink><br />
</ItemTemplate>
</asp:DataList>
and then the cs...
protected void Page_Load(object sender, EventArgs e)
{
displaytags(sender, e);
}
protected void displaytags(object sender, EventArgs e)
{
var qrygettags = (from t in db.TagTables
select new { t.TagName }).Distinct().ToList();
TagDataList.DataSource = qrygettags;
TagDataList.DataBind();
CheckBox TagCheckbox = (CheckBox)TagDataList.Items[0].FindControl("TagCheckbox");
}
protected void databindthesucker(object sender, EventArgs e)
{
foreach (DataListItem item in TagDataList.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
CheckBox TagCheckbox = (CheckBox)item.FindControl("TagCheckbox");
HiddenField TagNameHidden = (HiddenField)item.FindControl("TagNameHidden");
string Tagstring = TagNameHidden.Value.ToString();
if (TagCheckbox.Checked)
{
var qrygetprojects = (from p in db.projects
join pt in db.TagTables on p.projectID equals pt.projectID
where pt.TagName == Tagstring
select new
{
pt.projectID,
p.projectName
}).ToList();
ProjectDataList.DataSource = qrygetprojects;
ProjectDataList.DataBind();
}
}
}
}
Any ideas?
Related
I have a repeater that in it has one dropdown list and one linkbutton.
I want to get the selected value of the dropdown list by CommandArgument in linkbutton, but it just knows default value of dropdown list.
My code :
<asp:Repeater runat="server" ID="Repeater1" OnItemDataBound="Page_Load2"OnItemCommand="list_ItemCommand" >
<ItemTemplate>
<asp:DropDownList ID="dlPricelist" CssClass="width100darsad dropdownlist" runat="server" AutoPostBack="true" ViewStateMode="Enabled" >
</asp:DropDownList>
<asp:LinkButton ID="btnAddToCart" runat="server" class="btn btn-success btnAddtoCardSinglepage" CommandArgument='<%#Eval("id") %>' CommandName="addtocard">اضافه به سبد خرید</asp:LinkButton>
<asp:Label ID="xxxxxx" runat="server" Text="Label"></asp:Label>
</ItemTemplate>
</asp:Repeater>
Code behind:
protected void Page_Load2(object sender, RepeaterItemEventArgs e)
{
if (!IsPostBack)
{
string id = Request.QueryString["id"].ToString();
DataSet dsselectcategory = BLLTour.left3join(id.Trim().ToString());
var dlPricelist = (DropDownList)e.Item.FindControl("dlPricelist");
dlPricelist.DataSource = dsselectcategory.Tables[0];
dlPricelist.DataTextField = "pricelistPrice";
dlPricelist.DataValueField = "priceid";
dlPricelist.DataBind();
}
}
protected void list_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "addtocard")
{
foreach (RepeaterItem dataItem in Repeater1.Items)
{
Label xxxxxx = (Label)e.Item.FindControl("xxxxxx");
LinkButton btnAddToCart = (LinkButton)e.Item.FindControl("btnAddToCart");
xxxxxx.Text = ((DropDownList)dataItem.FindControl("dlPricelist")).SelectedItem.Text; //No error
}
}
}
I don't know how I should fix it.
You are using very old technology to show data that's not appropriate.
But if you are serious to use it, you must use FindControll method in ItemTemplate of your repeater control. You should find dropdownlist first, and then cast it to a object to be able to use it's value.
I have a GridView and for one of the columns I'm using a drop down list that displays a list of users:
<asp:GridView style="float:left"
ID="gvBookings"
ShowHeaderWhenEmpty="true"
CssClass="tblResults"
runat="server"
OnRowDataBound="gvBookings_RowDataBound"
DataKeyField="ID"
AutoGenerateColumns="false"
allowpaging="false"
<Columns>
<asp:BoundField DataField="FinishDate" HeaderText="Finish Date"></asp:BoundField>
<asp:TemplateField HeaderText="Time Spent By">
<ItemTemplate>
<asp:DropDownList id="ddlUsers" runat="server" ></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In the code behind I need to call a function that updates the database when the drop down list is changed. I have done this already for the FinishDate column so is there a similar way to do this for the drop down menu?
Code behind:
protected void gvBookings_RowDataBound(object sender, GridViewRowEventArgs e)
{
BHTaskClass.BookingTask booking = (BHTaskClass.BookingTask)e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (TableCell c in e.Row.Cells)
{
if (count == 1)
{
string FinishTime = booking.FinishTime.HasValue ? booking.FinishTime.Value.ToString("hh':'mm") : "";
c.Text = "<input type=\"text\" id=\"txtFinishTime" + booking.ID + "\" style=\"width:70px\" type=\"text\" onblur=\"UpdateFinishTime(" + booking.ID + ",this.value)\" value=\"" + FinishTime + "\" >";
}
if (count == 2)
{
ddlUsers.SelectedValue = booking.TimeSpentName;
}
count++;
}
}
}
So when the FinishDate textbox is changed it calls the UpdateFinishTime function and this updates the database. How do I call a function for the drop down list?
ASPX
<asp:DropDownList id="ddlUsers" runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="YourFunction_Changed">
</asp:DropDownList>
Code behind:
protected void YourFunction_Changed(object sender, EventArgs e)
{
//do stuff...
}
To get the Row ID you can do it as below
protected void YourFunction_Changed(object sender, EventArgs e)
{
//do stuff...
int Index = ((GridViewRow)((sender as Control)).NamingContainer).RowIndex;
// your logic follows based on the Index
}
before I asked this I did some checking around to make sure that this doesn't turn out to be a duplicate and ways to get the row values from a row that has a checkbox in its template field...but I can't seem to get it working...So far I have tried
protected void Page_Load(object sender, EventArgs e)
{
Entities NW = new Entities();
var customers =
from c in NW.Customers
where (c.ContactName.StartsWith("Ma") || c.ContactName.StartsWith("An")
|| c.ContactName.StartsWith("T")
|| c.ContactName.StartsWith("V")
)
orderby c.ContactName ascending
select new
{
c.CustomerID,
c.ContactName,
c.CompanyName,
c.City
};
gv1.DataSource = customers.ToList();
gv1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gv1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox chkRow = (row.Cells[0].FindControl("CB") as CheckBox);
if (chkRow.Checked)
{
Label1.Text = row.Cells[2].Text;
}
}
}
}
I have stepped through the button click event and when it gets to
if (chkRow.Checked)
its showing as null and skips over it..
my markup is
<asp:GridView ID="gv1" runat="server">
<HeaderStyle BackColor="SkyBlue" />
<AlternatingRowStyle BackColor="Yellow" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="CB" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
when I look at the source after I run, the checkboxes are all named differently than what I gave them the ID of "CB", attached is the pic of the source when its running
I am not sure what I am doing wrong with this
Your GridView should have more columns, because you are referencing Cell[2] in your code.
You might try to use row object to look for your control:
CheckBox chkRow = (row.FindControl("CB") as CheckBox);
I have a repeater with a textbox inside. I am trying to edit the information inside the textbox, retrieve the new data, and write to the DB. With my code its giving me the original info that was in the box. Not the new information that I have added. Here is my code
html:
<asp:LinkButton id="saveReviewLinkButton" text="Save" runat="server" onCommand="saveReviewLinkButton_OnCommand" />
<table>
<asp:Repeater id="ReviewRepeater" runat="server" onItemDataBound="ReviewRepeater_ItemDataBound">
<itemtemplate>
<tr >
<td ><asp:TextBox id="titleLabel" runat="server" width="200px" textMode="MultiLine"/></td>
</tr>
</itemtemplate>
</table>
c#:
protected void ReviewRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
Review review = (Review)e.Item.DataItem;
TextBox titleLabel = (TextBox)e.Item.FindControl("titleLabel");
titleLabel.Text = review.Title;
}
}
protected void saveReviewLinkButton_OnCommand(object sender, EventArgs e)
{
TextBox titleLabel = new TextBox();
foreach (RepeaterItem dataItem in ReviewRepeater.Items)
{
titleLabel = (TextBox)dataItem.FindControl("titleLabel");
string newInfo = titleLabel.Text;
}
}
Please make sure, you are binding the data to the repeater by checking in page load
if(!IsPostBack)
BindData();
I am rather new at asp.net.
I´m trying to use ImageButton to link to another page. ImageButton is inside a Repeater and the code is following:
<ul id = "ulMap">
<asp:Repeater ID="Repeater1" runat="server" >
<ItemTemplate>
<li>
<asp:ImageButton ID="ImageButton1"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
ImageUrl="~/Icons/Ny_mappa.png"
onclick="ImageButton1_Click" />
<br />
<asp:LinkButton ID="lnkButton"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
onclick="LinkButton3_Click"
Text='<%#Eval("Nav_Name") %>'></asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
And the code behind is the following:
protected void LinkButton3_Click(object sender, EventArgs e)
{
Guid guid = new Guid(((LinkButton)sender).CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
Guid guid = new Guid(((ImageButton)sender).CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
Well, for the LinkButton this works fine but not for ImageButton. Protected void ImageButton1_Click never happens. Can anybody help?
I thin you need to handle the Repeater_ItemCommand event to get this working properly. It'll probably save a bit of code as well.
MSDN Repeater ItemCommand
Also, if you're linking to another page do you need to postback to the page then perform some kind of redirection or would it make more sense to have that logic in the new page?
Instead of OnClick, you should you should OnCommand. Like this.
<ul id = "ulMap">
<asp:Repeater ID="Repeater1" runat="server" >
<ItemTemplate>
<li>
<asp:ImageButton ID="ImageButton1"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
ImageUrl="~/Icons/Ny_mappa.png"
OnCommand="ImageButton1_Click" />
<br />
<asp:LinkButton ID="lnkButton"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
OnCommand="LinkButton3_Click"
Text='<%#Eval("Nav_Name") %>'></asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
And this (notice the CommandEventArgs instead of EventArgs and ImageClickEventArgs):
protected void LinkButton3_Click(object sender, CommandEventArgs e)
{
Guid guid = new Guid(e.CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
protected void ImageButton1_Click(object sender, CommandEventArgs e)
{
Guid guid = new Guid(e.CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
You can't handle server-side events for repeater child controls like this.
Think of it this way - if there is 100 buttons, you need 100 event handlers for each button. ImageButton1_Click will only work for the ImageButton with the id of 1.
The answer is to wire up the ItemCommand event for your repeater.
Like this:
<asp:repeater id = "Repeater`" runat = "server" onItemCommand = "SomeEvent">
Then you handle the "SomeEvent" for all buttons that trigger this event:
protected void SomeEvent ( Object src, RepeaterCommandEventArgs e ) {
var whoClickedMe = ((ImageButton) e.CommandSource );
}
Here's a good article on doing this.