tooltip computed links for asp button after button is clicked - c#

<ItemTemplate>
<tr>
<asp:LinkButton ID="btnID" runat="server"
ToolTip='The calculated IDs are: ' OnCommand="showIds"
CommandArgument='<%# Convert.ToInt32(Eval("Year")) + "," +
Convert.ToInt32(Eval("Month")) %>'>
<%# Convert.ToInt32(Eval("Count")) - Convert.ToInt32(Eval("LittleCount"))%>
</asp:LinkButton>
</tr>
</ItemTemplate>
As you can notice the tooltip text is static. In code behind, I do calculate and get some integers ( IDs ) every time the above button is clicked ( protected void showIds(object sender, CommandEventArgs e) { .... }) contained as a List<ExpressionListDictionary>. ( the asp:LinkButton is contained inside an asp:ListView )
What I want to do, is to change the tooltip into a dynamic one, containing all the already obtained IDs as links. ( Something like this: http://jsfiddle.net/IrvinDominin/jLkcs/5/ - but in my case I do need firstly to click the button for calculating the IDs, and after this I would need to change the tooltip text from code as it needs to show the respective IDs, as links if it is possible)
How can I achieve this?

If you have a class (or id or something) to identify the buttons you can make an jQuery document ready function to change the tooltip with ids to a link containing the ids.
I modifyed your fiddle: http://jsfiddle.net/jLkcs/545/
$(document).ready(function () {
$(".myLinkButton").each(function() {
createlink(this);
});
});
function createlink(obj){
var ids= $(obj).attr('title');
var linkHtml="<a href='javascript:alert(" + ids + ")'>link</a>"
$(obj).attr('title',linkHtml);
}

Why not simply adjust the ToolTip in the codebehind during postback?
protected void showIds(object sender, CommandEventArgs e)
{
((LinkButton)sender).ToolTip = "blahblah";
}

You can set your sender attributes if the CommandEventArgs CommandName is equal with your defined one
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
if (e.CommandName.Equals("showIds"))
{
//
}
}
Here is an working example, this will work, not counting in what user control LinkButton is used:
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : Page
{
public string btnNoTooltip = "No IDs are calculated";
public string btnTooltip = "The calculated IDs are:";
protected void Page_Load(object sender, EventArgs e)
{
}
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
if (e.CommandName.Equals("LinkButtonOrder"))
{
LinkButton lkTrigger = (LinkButton)sender;
if (lkTrigger.ToolTip.Equals(btnNoTooltip))
{
lkTrigger.ToolTip = btnTooltip + " " + e.CommandArgument;
}
else
{
lkTrigger.ToolTip += " " + e.CommandArgument;
}
Random random = new Random();
lkTrigger.CommandArgument = random.Next(0, 100).ToString();
Label1.Text = "Triggered: " + e.CommandName + " with Argument " + e.CommandArgument;
}
}
}
Markup:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<h3>LinkButton Command Event Example</h3>
<asp:LinkButton id="LinkButton1"
Text="Order Item Here"
CommandName="LinkButtonOrder"
ToolTip='No IDs are calculated'
CommandArgument="01"
OnCommand="LinkButton_Command"
runat="server"/>
<br />
<asp:LinkButton id="LinkButton2"
Text="Or Order Item Here"
CommandName="LinkButtonOrder"
CommandArgument="02"
ToolTip='No IDs are calculated'
OnCommand="LinkButton_Command"
Runat="server"/>
<br />
<br />
<asp:Label id="Label1" runat="server"/>
<asp:PlaceHolder id="plhInjectId" runat="server" Visible="false"></asp:PlaceHolder>
</asp:Content>

You can use jquery to generate Tool Tip on Page itself.
Add a hidden field for your all the already obtained IDs (comma sepearted) to asp:ListView
Populate this hidden in ItemCreated event on server
add a class to your link button, say 'ShowHyperlinkOnHover'
Bind mouseenter event to class ShowHyperlinkOnHover document.ready function of jquery, this will dynamically generate tool tip. and then on Mouse Over tool tip will be displayed.
$(document).ready(function () {
$(document).on("mouseenter", ".ShowHyperlinkOnHover", function(this){
// 2 is index of hidden field having comma seperated Ids
var dynaToolTip;
$(this).parent("td:nth-child(2)").split(',').each(
function(oneId) dynaToolTip=dynaToolTip+ anyFomationLogic(oneId);
);
$(this).attr('title',dynaToolTip);
});
});

Related

C# - Transfer the text of a hyperlink through a session inside a repeater

I want to transfer the text of a hyperlink through a session inside a repeater. But I can not think of the logic to do this. My repeater generates links within that dropdown menu and I want to get the text that appears in the link and pass it to another page Sectors.aspx. This is what I have done so far:
--- edit ---
I want that when the link is clicked, the text that is in the link is passed to the other page. For example, the menu has two links, APPLE and BANANA. When the user clicks APPLE, I want the next page Sectors.aspx to know that the user clicked APPLE and not the other options.
ASPX Page:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<div class="dropdown">
<button class="dropbtn">Setor</button>
<div class="dropdown_content">
<asp:Repeater ID="sectors_menu" runat="server">
<ItemTemplate>
<asp:HyperLink id="hyperlink1" NavigateUrl="Sectors.aspx" Text='<%#((System.Data.DataRowView)Container.DataItem)["sector"] %>' runat="server"></asp:HyperLink>
</ItemTemplate>
</asp:Repeater>
</div>
</div>
</asp:Content>
Code Behind
public partial class _Default : System.Web.UI.Page
{
MySqlConnection mysql_connection = new MySqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
string mysql_string;
MySqlDataAdapter mysql_data_adapter;
public void Page_Load(object sender, EventArgs e)
{
Sector_label();
}
public void Sector_label()
{
mysql_string = "SELECT * FROM employees GROUP BY sector";
mysql_data_adapter = new MySqlDataAdapter(mysql_string, mysql_connection);
DataTable data_table = new DataTable();
mysql_data_adapter.Fill(data_table);
DataView data_view = new DataView(data_table);
sectors_menu.DataSource = data_view;
sectors_menu.DataBind();
for (int count = 0; count < sectors_menu.Items.Count; count++)
{
var test = (HyperLink)sectors_menu.Items[count].FindControl("hyperlink1");
Session["session_hyperlink"] = test.Text;
// Debug.WriteLine(test.Text);
}
}
}
You could add the text as a parameter of the NavigateUrl:
<ItemTemplate>
<asp:HyperLink id="hyperlink1" NavigateUrl='<%# "Sectors.aspx?sector=" + Server.UrlEncode(((System.Data.DataRowView)Container.DataItem)["sector"]).ToString() %>' Text='<%#((System.Data.DataRowView)Container.DataItem)["sector"] %>' runat="server"></asp:HyperLink>
</ItemTemplate>
Then, Sectors.aspx can retrieve it through the "sector" parameter:
protected void Page_Load(object sender, EventArgs e)
{
string sector = Request.Params["sector"];
}
That id="hyperlink1" parameter looks fishy, though. You don't want all your hyperlinks to have the same ID.
Just replace hyperlink tag with this code ,
<asp:HyperLink runat="server" Navigateurl='<%#"Sectors.aspx?mySector="+ Eval("sector") %>'
Text='<%#((System.Data.DataRowView)Container.DataItem)["sector"] %>' />

Values in dynamically added controls not retained on postback

I have a page with a number of controls of type MyControl added dynamically. The count is stored in the ViewState, and only incremented with a button click.
In MyControl, I have a TextBox control, and a Label control. When the text is changed in the textbox, the value is multiplied by 2 and displayed in the label control.
To do this, I have added an OnTextChanged event and set AutoPostBack to true.
My problem is this: when I have any number of MyControl's on the page, and change the text in any of the textboxes, the label is updated and the values are retained on postback.
However, if I click the increment button on the page, all the values in the textboxes and labels are lost.
My code:
Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.Default" EnableViewState="true" %>
<html>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
Count:
<asp:Label ID="lblCount" runat="server"></asp:Label>
<asp:Button ID="btnAdd" runat="server" OnClick="btnAdd_Click" Text="+" />
<asp:Panel ID="pnlControls" runat="server"></asp:Panel>
</form>
</body>
</html>
Default.aspx.cs
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int count = 0;
//if not postback, then set count and store in viewstate
if (!Page.IsPostBack)
{
count = 1;
ViewState["count"] = count;
}
LoadControls();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
//increment count
ViewState["count"] = (int)ViewState["count"] + 1;
pnlControls.Controls.Clear();
LoadControls();
}
private void LoadControls()
{
//add controls to page
for (int i = 0; i < (int)ViewState["count"]; i++)
{
MyControl con = (MyControl)LoadControl("MyControl.ascx");
con.ID = i.ToString();
pnlControls.Controls.Add(con);
}
//set count label
lblCount.Text = ViewState["count"].ToString();
}
}
MyControl.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="Test.MyControl" EnableViewState="true" %>
<div>
<asp:TextBox ID="txtField" runat="server" OnTextChanged="txtField_TextChanged" AutoPostBack="true"></asp:TextBox>
<asp:Label ID="lblAnswer" runat="server" Text="answer:"></asp:Label>
</div>
MyControl.ascx.cs
public partial class MyControl : System.Web.UI.UserControl
{
public string Text;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void txtField_TextChanged(object sender, EventArgs e)
{
lblAnswer.Text = (int.Parse(txtField.Text) * 2).ToString();
}
}
Am I missing something obvious? How can I keep the values when the button is clicked?
The reason you lose the info of MyControl(s..) is when you click the button you clear them:
pnlControls.Controls.Clear();
If you want to keep the values I recomended you to use Session variables, for example an array when you fire "txtField_TextChanged" to save "lblAnswer.Text", be carefull with the ID's to differentiate from each other in the Session variable.
Finally, I'd put "LoadControls();" inside Page_Load, outside I think It's redundant.

Dynamically added control and buttons postback

Hi I have a problem with my GridView.
Let's say that I create a GridView with 4 columns
|NAME|LASTNAME|OWNER|ADMINISTRATOR|
Owner and Administrator are columns that can contain a checkbox.
Second step: I fill the grid in some way.
Third step: I add dynamically the check box on the owner and admin columns, depending on some strange method.
Four step: When I click the Button below the gridview, the click event will read how many checkbox are checked and pass that number to another method.
This last step is quite difficult because all the checkboxes disappear, due to the postback of the button.
I looking for a method to save the checkboxes from the postback.
Can I call a method after the click, and before the postback?
Can I avoid the postback of a button?
(PS: I prefer to not go for js solution)
If you place the method call to dynamically add the check boxes in Page_Init they will not be removed on postback
It's not clear from your question why you need to have dynamically added CheckBox controls, when you can just set their state server-side in the RowDataBound event of the GridView. Here is a worked example of your requirment boiled down to the barest minimum to illustrate:
CheckboxGrid.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="CheckboxGrid.aspx.cs" Inherits="CheckboxGrid" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvResourceUsers" runat="server" AutoGenerateColumns="False" OnRowDataBound="gvResourceUsers_OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name"/>
<asp:BoundField HeaderText="Surname" DataField="Surname"/>
<asp:TemplateField HeaderText="Owner">
<ItemTemplate>
<asp:CheckBox ID="cbxOwner" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Administrator">
<ItemTemplate>
<asp:CheckBox ID="cbxAdministrator" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btnSubmit" Text="Save" OnClick="btnSubmit_Click"/>
</div>
</form>
</body>
</html>
CheckboxGrid.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CheckboxGrid : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Get data and bind the grid
gvResourceUsers.DataSource = GetData();
gvResourceUsers.DataBind();
}
}
protected void gvResourceUsers_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
//As each row is data-bound, set the checkbox state.
if (e.Row.RowType == DataControlRowType.DataRow)
{
var resourceUser = e.Row.DataItem as ResourceUser;
var cbxOwner = e.Row.FindControl("cbxOwner") as CheckBox;
var cbxAdministrator = e.Row.FindControl("cbxAdministrator") as CheckBox;
cbxOwner.Checked = resourceUser.Owner;
cbxAdministrator.Checked = resourceUser.Administrator;
}
}
protected void btnSubmit_Click(Object sender, EventArgs e)
{
var resourceUsers = new List<ResourceUser>();
//Iterate the gridview rows and populate the collection from the postback data.
foreach (GridViewRow row in gvResourceUsers.Rows)
{
resourceUsers.Add(
new ResourceUser
{
Name = row.Cells[0].Text,
Surname = row.Cells[1].Text,
Owner = ((CheckBox)row.Cells[2].FindControl("cbxOwner")).Checked,
Administrator = ((CheckBox)row.Cells[3].FindControl("cbxAdministrator")).Checked
});
}
}
private IEnumerable<ResourceUser> GetData()
{
//We just create some data for demo purposes. Here you would normally populate the collection from your database.
var resourceUsers = new List<ResourceUser>
{
new ResourceUser{Name = "Bob", Surname = "Taylor", Owner = true, Administrator = true },
new ResourceUser{Name = "Ann", Surname = "Carter", Owner = false, Administrator = true },
new ResourceUser{Name = "Toni", Surname = "Wong", Owner = false, Administrator = false}
};
return resourceUsers;
}
//A data view model to contain our view data for the grid
private class ResourceUser
{
public String Name { get; set; }
public String Surname { get; set; }
public Boolean Owner { get; set; }
public Boolean Administrator { get; set; }
}
}

Repeater and Custom Control - Dynamically adding to the collection and retaining values

It has been so long since I've used Web Forms I find myself not remembering most of the perks.
I have a user control that has a button, a repeater and the ItemTemplate property of the repeater is another user control.
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add" OnClick="btnAdd_Click"/>
<br/>
<asp:Repeater runat="server" ID="rptrRequests">
<ItemTemplate>
<uc1:ucRequest ID="ucNewRequest" runat="server" />
</ItemTemplate>
</asp:Repeater>
The idea is that when the user clicks on the Add button a new instance of the ucRequest is added to the collection. The code behind is as follows:
public partial class ucRequests : UserControl
{
public List<ucRequest> requests
{
get
{
return (from RepeaterItem item in rptrRequests.Items
select (ucRequest) (item.Controls[1])
).ToList();
}
set
{
rptrRequests.DataSource = value;
rptrRequests.DataBind();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
requests = new List<ucRequest>();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = requests;
reqs.Add(new ucRequest());
requests = reqs;
}
}
After much googling I now remember that I should be binding the Repeater in the OnInit method in order for the ViewState to put the captured data of the controls within the ucRequest control on them between post backs but when I try to do that I will always have a single instance of the control on the Repeater since its Items collection is always empty.
How could I manage to do this?
Thanks in advance.
You just need control ids in view state stead of entire control collection.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequests.ascx.cs"
Inherits="RepeaterWebApplication.ucRequests" %>
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add"
OnClick="btnAdd_Click" />
<br /><asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequest.ascx.cs"
Inherits="RepeaterWebApplication.ucRequest" %>
<asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
private List<int> _controlIds;
private List<int> ControlIds
{
get
{
if (_controlIds == null)
{
if (ViewState["ControlIds"] != null)
_controlIds = (List<int>) ViewState["ControlIds"];
else
_controlIds = new List<int>();
}
return _controlIds;
}
set { ViewState["ControlIds"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (int id in ControlIds)
{
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = ControlIds;
int id = ControlIds.Count + 1;
reqs.Add(id);
ControlIds = reqs;
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
Try to get the ucRequests during the OnItemDatabound event, at that point you can edit the content of itemtemplate of the repeater. You can get there after the postback caused by the click on the add button. Here's a sample with a similar scenario

Problem with a hyperlink

I put a hyperlink inside a datalist..
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server">'<%# Eval("ThreadTitle") %>'</asp:HyperLink>
<br />
<br />
</ItemTemplate>
I want it to enable it to be pressed so that the datalist event will be triggered and transfer me to another page:
protected void DataList1_SelectedIndexChanged(object sender, EventArgs e)
{
Server.Transfer("AnswerQuestion.aspx?x=" + DataList1.DataKeyField + "&question=" + DataList1.SelectedValue + "&time=" + DateTime.Now);
}
Unfortunately, the link seems to be disabled and I cant press on it to trigger the DataList Selected event..
How can I make the hyperlink active ?
If you want to trigger a selecteditemchaned event use a LinkButton instead of hyperlink.
<asp:DataList ID="DataList1" runat="server"
onselectedindexchanged="DataList1_SelectedIndexChanged">
<ItemTemplate>
<asp:LinkButton ID="sjdj" runat="server" CommandName="Select">
<%# Container.DataItem %></asp:LinkButton>
</ItemTemplate>
</asp:DataList>
In the code behind have
protected void DataList1_SelectedIndexChanged(object sender, EventArgs e)
{
Server.Transfer("~/jjtestjj.aspx?" + DataList1.DataKeyField);
}
why arent you using the Hyperlink as a hyperlink?
You can set the NavigationURL and Text using the OnItemDataBound (or equivalent) event.
this code works with an asp:Repeater:
protected void Row_DataItem(object row, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.AlternatingItem || args.Item.ItemType == ListItemType.Item)
{
var item = (DataItemPOCO)args.Item.DataItem;
var link = (HyperLink)args.Item.FindControl("HyperLink1");
link.Text = item.LinkText;
link.NavigateUrl = item.URL;
}
}

Categories