Binding mouseover event to asp.net repeater - c#

I have an asp.net repeater that displays a title and and image.
The title is very long , so I want to display the title again on mouse over.
I tried to implement a mouse over but I have the following problem.
My display looks like this :
Repeater Element 1 Repeater Element 2
Title 1 Title 2
Image 1 Image 2
Now on doing a mouse over on Element1 , my mouse over displays Title1.
On doing a mouseover on Element2 , my mouse over displays Title1 again ,and I would like it to
display Title2 ? Can anyone point me on how i can achieve this.
My code is below :
<asp:Repeater ID="rptMonitorSummary" runat="server" OnItemDataBound="rptMonitorSummary_OnItemDataBound">
<ItemTemplate>
<asp:Panel ID="Pnl" runat="server" onmouseover="return showsamplepopup();" onmouseout="return hidesamplepopup();">
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">
<%# Eval("Name").ToString().Length > 9 ? (Eval("Name") as string).Substring(0, 9) : Eval("Name")%>
</h5>
<div id="popup" style="position: absolute; width: 80px; height: auto; background-color: Lime;
border-bottom: solid 3px gray; display: none; border-right: solid 3px gray; display: none;">
<%#Eval("Name")%>
</div>
<div class="center">
<asp:Image Width="50px" ID="btnPerformanceImage" runat="server" Height="28px"></asp:Image>
</div>
</li>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
The javascript functions are as follows :
function hidesamplepopup() {
document.getElementById('popup').style.display = 'none';
return false;
}
function showsamplepopup(e) {
e = (e) ? e : window.event;
var element = (e.target) ? e.target : e.srcElement;
var left = element.offsetLeft;
var top = element.offsetTop;
while (element = element.offsetParent) {
left += element.offsetLeft;
top += element.offsetTop;
}
document.getElementById('popup').style.display = 'block';
document.getElementById('popup').style.left = left;
document.getElementById('popup').style.top = top;
return false;
}

I do not know what is your requirement. It could have been a lot easier if you use jQuery tooltip.
This is just an alternative approach.
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(function () {
$(document).tooltip();
});
</script>
<asp:Repeater ID="rptMonitorSummary" runat="server"
OnItemDataBound="rptMonitorSummary_OnItemDataBound">
<ItemTemplate>
<asp:Panel ID="Pnl" runat="server">
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header" title="<%# Eval("Name").ToString() %>">
<%# Eval("Name").ToString().Length > 9 ?
(Eval("Name").ToString()).Substring(0, 9) : Eval("Name")%>
</h5>
<div class="center">
<asp:Image Width="50px" ID="btnPerformanceImage"
runat="server" Height="28px"></asp:Image>
</div>
</li>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>

Notice that getElementById will return the first element with that ID. And you're using the same ID for your Div's.
You should either use a different ID for each item of the repeater (generating different ID's for each of them), or change your logic to fetch them by some other property. I highly recommend using jQuery as well.

I would change the way which you are binding the events to elements, as your sample code doesn't use jQuery I'll assume you don't want it :)
First things first, you'll want to add a class to the asp:panel so that there will be some way of identifying and selecting all the instances. Also you'll want to use classes for your popups not IDs as IDs should be unique on a page.
then you can do something like:
var elements = document.querySelectorAll('.thatClassYouAdded'),
i = 0, l = elements.length;
for(;i<l;i++)
{
elements[i].addEventListener('mouseover', function(e) {
var popup = this.querySelector('.popup');
//do some stuff to popup
});
}
It's also important to note that querySelector is not supported in legacy browsers (see https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector for more info and support table) and older IEs (pre 9) use attachEvent instead of addEventListener which you may need to write additional code to support

Related

How to pass data between different c# and javascript

I have an ascx page with a div, when the div is clicked it calls a JS function and send an int
//HTML
<div style="float: right; margin-right: 150px;" class="innerDivStyle"
onclick="userStartExtend(2)">
<h1 style="margin-top: 50px">Product</h1>
</div>
//JavaScript function
function userStartExtend(num) {}
I need to use the num from userStartExtend function in a c# (file/page/code). I thought about querystring - set in javascript code and get in c# (possible?). Any other ideas ??
To make things clear : the c# code and javascript code dont share the same page.
What one normally does in a case where he wants to pass something from Javascript to .NET he uses eventHandlers, just don't forget to add attributes runat="server" id="DivId" and event handler OnServerClick="DivHandler".
Example:
<div runat="server" id="DivId" OnServerClick="DivHandler" style="float: right; margin-right: 150px;" class="innerDivStyle" onclick="userStartExtend(2)" >
<h1 style="margin-top: 50px">Product</h1>
</div>
then on C# side
public void DivHandler(object sender, EventArgs e)
{
//here sender is your <div> and e is data about 'click' event.
}
UPDATE: It appears that OnServerClick does not work properly ether. Here is workaround
HTML:
<div runat="server" id="DivId" OnServerClick="testMe('param1')" style="float: right; margin-right: 150px;" class="innerDivStyle" onclick="userStartExtend(2)" >
<h1 style="margin-top: 50px">Product</h1>
</div>
JavaScript:
function testMe(params) {
var btnID= '<%=MyButton.ClientID %>';
__doPostBack(btnID, params);
}
Server-side Page_Load:
string parameter = Request["__EVENTARGUMENT"];
if (parameter == "param1")
MyButton_Click(sender, e);
Make your div server side
<div id="serverSideId" runat="server" />
In your C# code, Page_PreRender should have this
int myValue = 2;
serverSideId.OnClientClick = "userStartExtend(" + myValue.ToString() + ")";
Add a hidden Field control in your use control
<asp:HiddenField ID="hdnval" runat="server" Value="" Visible="false">
update your javascript function as this
function userStartExtend(num) {
var myHidden= document.getElementById('<%= hdnval.ClientID %>');
if(myHidden)
{
myHidden.value=num;
}
}
Now use can access this server control at code behind

How to show/hide a nested list using JavaScript in ASP.NET?

Edit: Found the solution, and posted the answer below.
In my ASP.NET c# project, I have a ListView (ParentList) bound to a DataSource. Within the ParentList, inside the ItemTemplate, I have another Repeater (ChildList) bound to an attribute of each ListViewDataItem.
<asp:ListView ID="ParentList" runat="server" DataSourceID="objectDataSourceID" DataKeyNames="ID">
<ItemTemplate>
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Attribute1") %>' />
</td>
<td valign="top">
<asp:Repeater ID="ChildList" runat="server" DataSource='<%# Eval("Attribute2ReturnsAnotherList") %>'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<%# DataBinder.Eval(Container.DataItem, "childAttribute") %>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
...
</LayoutTemplate>
</asp:ListView>
The code above works just fine, everything renders great. Now I want to add a link that will show/hide the ChildList. Something like the below:
<td valign="top">
<a href="javascript:ToggleListVisibility()" >Show/Hide</a>
<asp:Repeater ID="ChildList" runat="server" DataSource='<%# Eval("Attribute2ReturnsAnotherList") %>'>
</asp:Repeater>
</td>
How can I achieve this? I can't just use getElementById as I normally would, as the ul lists are within a Repeater nested inside the ListView. I tried obtaining the parentNode, then accessing the children and toggling the visibility of the ul element within:
function ToggleListVisibility(source) {
var childrenlist = source.parentNode.children;
for (var i = 0; i < childrenlist.length; i++) {
if (childrenlist[i].tagName == 'ul') {
if (childrenlist.style.display == "none") {
childrenlist.style.display = "block";
} else {
childrenlist.style.display = "none";
}
}
}
}
<a href="javascript:ToggleListVisibility(this)" >Show/Hide</a>
but that didn't work. IE's 'error on page' gave me this error:
The parentNode is null or not an object.
I also tried setting the a runat="server" attribute to my ul element, then using <%# ulID.ClientID %> to pass the ul id to the Js function, but visual studio complained:
Server elements cannot span templates.
Finally, I tried just passing the ul object into the Js function, like this:
function ToggleListVisibility(src) {
if (src.style.display == "none") {
src.style.display = "block";
} else {
src.style.display = "none";
}
}
<a href="javascript:ToggleListVisibility(ulID)" >Show/Hide</a>
...
<ul id="ulID">
which works, but it toggles the visibility for the ChildList in all rows within my ParentList. I want it to only toggle the visibility for the ChildList in its own row.
I'm at a loss of what to do. JavaScript is not my forte, and I would appreciate if someone can provide some pointers. Thanks in advance.
Ok hopefully this will get you going - it worked for me in hiding a list. My source HTML looks like this:
<table>
<tbody>
...
<tr>
<td>
Hide
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</td>
</tr>
...
</tbody>
</table>
<script type="text/javascript">
function toggleListVisibility(src) {
var childrenList = src.nextSibling.nextSibling;
childrenList.style.display = "none";
}
</script>
Note I had to use two "nextSibling"'s due to a text node that is created right after the "hide" anchor. Depending on how you structure your HTML, that bit will be different.
I found the painfully simple answer that makes me feel like a doofus. All I needed to do is wrap my Repeater in a <div> element, then show/hide the entire thing.
<a href="javascript:ToggleListVisibility('<%# Container.FindControl("divWrapper").ClientID %>')" >Show/Hide</a>
<div id="divWrapper" runat="server">
<asp:Repeater ID="ChildList" runat="server">
</asp:Repeater>
</div>
function ToggleListVisibility(id) {
var wrapper = document.getElementById(id);
if (wrapper.style.display == "none") {
wrapper.style.display = "block";
} else {
wrapper.style.display = "none";
}
}
Hooray for overthinking!

Display Html Content in jQuery Tooltip for ASP.Net Repeater

I have an asp.net repeater that displays a title and an image. The image appears based on some of the calculations I do in the repeater ItemDataBound event.
I tried to implement a mouse over using jquery tooltip . But I can only display the title in the tooltip. I would like to display other details bound to the repeater (errorcalls, totalcalls - I use these details to perform calculations in the code behind) too within the tool tip.
Can anyone help me with what I should do ? I have the code below .
Code for the repeater :
<asp:Repeater ID="rptMonitorSummary" runat="server"
OnItemDataBound="rptMonitorSummary_OnItemDataBound">
<ItemTemplate>
<asp:Panel ID="Pnl" runat="server">
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header" title="<%# Eval("Name").ToString()%> ">
<%# Eval("Name").ToString().Length > 9 ?
(Eval("Name") as string).Substring(0, 9) : Eval("Name")%>
</h5>
<div id="divHover">
<asp:Image Width="80px" ID="btnPerformanceImage"
runat="server" Height="45px"></asp:Image>
</div>
</li>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
Code Behind :
protected void rptMonitorSummary_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
int errorcalls = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "ErrorRatingCalls"));
int totalcalls = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "TotalCalls"));
float Percentage = 100 - ((((float)errorcalls / (float)totalcalls)) * 100);
if (Percentage == GetMaxMonitorThresholdValuebyLevelId(1))
{
((Image)e.Item.FindControl("btnPerformanceImage")).ImageUrl = "../Images/Level1.png";
}
else if (Percentage >= GetMinMonitorThresholdValuebyLevelId(2))
{
((Image)e.Item.FindControl("btnPerformanceImage")).ImageUrl = "../Images/Level2.png";
}
}
}
Javascript code :
$(function () {
$(document).tooltip();
});
I use the following css for the tool tip :
.ui-tooltip
{
text-align: center;
max-width: 180px;
font: bold 12px "Helvetica Neue", Sans-Serif;
}
I use the references below :
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
So basically the tool tip currently shows info of the title in one line something like :
ABC
I would like to display something like this in multiple lines :
ABC
PassPercentage = 100
jQuery tool tip doesn't allow HTML tags inside title attribute out of the box.
However, you can creates temporary place holder for each text (of repeater item). Then pass the content to tooltip when mouse hovers.
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(function () {
$(document).tooltip({
items: "h5",
content: function () {
var tooltip = $(this).siblings('.tooltip');
return tooltip.html();
}
});
});
</script>
<asp:Repeater ID="rptMonitorSummary" runat="server" OnItemDataBound="rptMonitorSummary_OnItemDataBound">
<ItemTemplate>
<asp:Panel ID="Pnl" runat="server">
<li class="ui-widget-content ui-corner-tr">
<h5 class="ui-widget-header">
<%# Eval("Name").ToString().Length > 9 ? (Eval("Name").ToString()).Substring(0, 9) : Eval("Name")%>
</h5>
<div class="center">
<asp:Image Width="50px" ID="btnPerformanceImage" runat="server" Height="28px"></asp:Image>
</div>
<div class="tooltip" style="display: none">
<%# Eval("Name") %><br/>
PassPercentage = <asp:Literal runat="server" ID="PassPercentageLiteral" />
</div>
</li>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
protected void rptMonitorSummary_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
int errorcalls = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "ErrorRatingCalls"));
int totalcalls = Convert.ToInt32(DataBinder.Eval(e.Item.DataItem, "TotalCalls"));
float Percentage = 100 - ((((float)errorcalls / (float)totalcalls)) * 100);
var literal = e.Item.FindControl("PassPercentageLiteral") as Literal;
literal.Text = Percentage.ToString();
....
}
}
Perhaps you need to use the custom content function of the jQuery UI Tooltip instead:
http://jqueryui.com/tooltip/#custom-content
Using the $(this).is("h5") call, as in the example above, to customise the content when the user hovers over the h5 tag.

Read label value in code behind

Am using the below code to assign the label text using javascript. It's working well. But i can't able to read the label text in code behind. Please help me to fix this issue.
Javascript:
==========
var lbl_total = document.getElementById('<%= lbl_total.ClientID %>');
lbl_total.innerHTML = '500';
c# code behid :
===============
string total = lbl_total.Text; //It always return "";
client side changes for label will not get reflected in server side as its data is not posted to server. So the solution is to take an input hidden control and set its value with label's updated value. Below is the sample code:
<script type="text/javascript">
$(document).ready(function() {
var total = 0;
$('#Button1').click(function() {
total += 150;
$("span[id$=lbl_TotalCount]").html(total);
$("input:hidden[id$=MyHidden]").val(total);
});
});
</script>
html
<form id="form1" runat="server">
<div>
<input id="Button1" type="button" value="button" />
<asp:Button ID="btn_saveForm" runat="server" Text="save" CssClass="btnForm" OnClick="btn_saveForm_Click" />
<asp:Label ID="lbl_TotalCount" Style="color: #00e4ff; font-family: Arial; font-weight: bold;
text-decoration: underline" runat="server" Text="0">
</asp:Label>
<asp:HiddenField ID="MyHidden" runat="server" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</div>
</form>
full Article : Get label value in code behind whose text is changed via JavaScript/jQuery

How to show a div after postback on a button click?

Here i have a div in which i am showing it during the mouse hover in the master page and after mouse hover three href links will appear in that div .After clicking that href link it is traversing to another page,postback happens and that div is getting hidden in the master page.I need to show that div after that click also.I have used updatepanel and tried it but still it is not working.here is my code
//Div part
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="Update" runat="server">
<ContentTemplate>
<div runat="server" class="divSUBMenu" id="describe" style="width: 700px; height: 20px;
font: Arial, Helvetica, sans-serif;" onclick="show(0)">
</div>
</ContentTemplate>
</asp:UpdatePanel>
//Onhover part
<a href="#" onmouseover="showit(0)">
<img src="Images/Analyze_over.jpg" name="image1" width="84" height="22" border="0"
id="image1" alt="" /></a>
//Javascript for mousehover(working fine)
var submenu = new Array();
submenu[0] = ' <font style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"><a style="color: #FFFFFF; text-decoration: none;" href="ATrendAnalysis.aspx">Trend Analysis</a> <a style="color: #FFFFFF; text-decoration: none;" href="AEventPerformance.aspx">Event Performance</a> <a style="color: #FFFFFF; text-decoration: none;" href="ACannibalization.aspx">Cannibalization</a> <a style="color: #FFFFFF; text-decoration: none;" href="AHaloEffect.aspx">Halo Effect</a> <a style="color: #FFFFFF; text-decoration: none;" href="AVolumeDecomposition.aspx">Volume Decomposition</a></font></span>';
var delay_hide = 500;
var menuobj = document.getElementById ? document.getElementById("describe") : document.all ? document.all.describe : document.layers ? document.dep1.document.dep2 : "";
function showit(which) {
clear_delayhide();
document.getElementById("describe").style.visibility = 'visible';
thecontent = (which == -1) ? "" : submenu[which];
if (document.getElementById || document.all) {
menuobj.innerHTML = thecontent;
}
else if (document.layers) {
menuobj.document.write(thecontent);
menuobj.document.close();
}
}
and finally the part below is not working during the onclick but this alert is working
function show(which) {
alert("test");
document.getElementById("describe").style.visibility = 'visible';
}
Any suggestion??
EDIT:
This is the href am clicking
<a style="color: #FFFFFF; text-decoration: none;" href="ATrendAnalysis.aspx">Trend Analysis</a>
You have to use ClientScriptManager
http://msdn.microsoft.com/en-us/library/3hc29e2a.aspx
Example:
void Page_Load(object sender, EventArgs e)
{
if(checkDisplayCount.Checked)
{
String scriptText = "";
scriptText += "function DisplayCharCount(){";
scriptText += " spanCounter.innerText = " +
" document.forms[0].TextBox1.value.length";
scriptText += "}";
ClientScriptManager.RegisterClientScriptBlock(this.GetType(),
"CounterScript", scriptText, true);
TextBox1.Attributes.Add("onkeyup", "DisplayCharCount()");
LiteralControl spanLiteral = new
LiteralControl("<span id=\"spanCounter\"></span>");
PlaceHolder1.Controls.Add(spanLiteral);
}
}
Since the div is set to runat=server, you could control this on the server side - setting describe.IsVisible = false initially, and changing it to describe.IsVisible = true post-click.
If for whatever reason this must be done on the client, due to reliance on other scripts or something, then make sure you're looking for the control by using the correct identifier - it could be, depending on the version of ASP.NET you're using, that the control is prefixed with ctl00_x. In fact, even in newer versions of ASP.NET (above .NET 3.5), I think the UpdatePanel might explicitly alter the identifiers of its elements using a prefix so as to keep track of what it contains, don't quote me on that though. Check the rendered markup output on the page to check this.

Categories

Resources