Using jQuery to get data attributes - c#

Now, bear in mind I'm just trying to ensure that the code works by consuming the ready event here. I just want to make sure that the data I expect is getting pulled by jQuery. I've also tried the load event.
In the end I'd want to use the load or ready event to set the image initially and then of course use the hover event to change that image on hover.
I've tried a lot of the answers here on SO and just can't seem to get this working, so hopefully y'all can help me.
JavaScript:
$(document).ready(function () {
$("#submenumain-link").ready(function () {
alert($(this).data()["selectedimage"]);
alert($(this).data()["hoverimage"]);
});
$("#submenumain-link").hover(function () {
alert($(this).data("selectedimage"));
alert($(this).data("hoverimage"));
});
});
HTML:
<li id="submenumain-link"
data-selectedimage="some-image.png"
data-hoverimage="some-other-image.png">
But for whatever reason the alert messages just state undefined. Am I missing something here?
EDIT
Note that if I place those same alert statements in the hover, it works as expected. What event could I use to do the initialization?

$(this).data('selectedimage');
You don't need the brackets []

The real problem is that ready should not be used in this way. The ready event should only be used with making sure the DOM is ready - http://api.jquery.com/ready/
So technically, inside of document.ready, all of the DOM is ready and should be available for these kinds of things. Inside of document.ready, the value of this refers to the document element, so you need to actually grab the li element. Your code should be something like this:
$(document).ready(function () {
var li = $("#submenumain-link");
alert(li.data()["selectedimage"]); // or li.data("selectedimage")
li.hover(function () {
//alert($(this).data("selectedimage"));
//alert($(this).data("hoverimage"));
});
});
http://jsfiddle.net/XN2LV/

The issue is your .ready() call. You should use a load event if you want to wait until something is loaded but in this case it is an li element that will already exist so your code should be:
$(document).ready(function() {
var test = $("#submenumain-link");
alert(test.data('selectedimage'));
alert(test.data('hoverimage'));
test.hover(function() {});
});

It should be alert($(this).data("selectedimage"));
Look here: HTML5 data-* Attributes.

Related

Show a loading animation while function completes

I have a function inside my .aspx.cs code which takes wuite a long time to do the processing until when I want to display a cool loading animation. I looked some of the earlier posts but either these didn't work for me, or were having solution specific to Page loading scenario (not loading a while a function completes).
I guess the right approach would be to fire a Javascript startLoader() function just before the the main function starts (which takes a long time), and then call a stopLoader() from the .aspx.cs itself to stop the loader when the function ends. Any suggestions how to implement this?
Yes, I've done this in ASP.NET Web From (not a ASP.NET MVC solution). You need to provide OnSubmit client side event handler. It basically break down to three parts: Javascript, HTML Div, and one line code behind:
Javscript:
function ShowLoading(e) {
// var divBg = document.createElement('div');
var divBg = document.getElementById('blockScreen');
var divLoad = document.createElement('div');
var img = document.createElement('img');
img.src = 'images/ajax-loader.gif';
divLoad.setAttribute("class", "blockScreenLoader");
divLoad.appendChild(img);
divBg.appendChild(divLoad);
document.getElementById('blockScreen').style.display = 'block';
// These 2 lines cancel form submission, so only use if needed.
//window.event.cancelBubble= true;
//e.stopPropagation();
}
function HideLoading() {
//alert('hideloading');
document.getElementById("form1").onsubmit = null;
document.getElementById('blockScreen').style.display = 'none';
//alert('done');
}
Add following DIV
<div id="blockScreen" class="blockScreen" style="display:none"> </div>
Finally, add the following to Page_Load in code behind.
Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "submit", "ShowLoading()");
Now, all of your page postbacks are essentially have to call onsubmit event. It will display the animation before the page postback finishes.
if you really want to do, then the only way is webworkers. You've probably heard about them, or if not, i seriously recommend to have a look.
Yes, fire startLoader() on OnCliencClick of your button or whatever element you are using to fire the server-side event and call stopLoader() from the server-side at the end of your process. Something like this:
//rest of the server-side code above ...
Page.ClientScript.RegisterStartupScript(this.GetType(), "someKey", "stopLoader();", true);
If you don't mind that the browser is not responsive in the meantime, the simplest way of doing this is using an animated gif:
Activity indicators
ajaxload.info
webscriptlab
The trick is showing the image when starting your processing, and hiding it when finished. You can show it in an img, and use jQuery or whatever you want to show/hide it.
If you need the browser to keep responsive, use Web Workers. But be aware that some of the older browsers don't support it. See this reference

Jquery class and its function

I am developing discussion panel in asp.net in which I am drawing some spans through javascripts
$("#commenttr").after("<tr id="+i+"><td class=\"labelPortion\"></td><td class=\"controlPortion\">" +out[i]+ "</td><td><span style = \"cursor:pointer\" class = \"plblAgreeComment\" id = \"" + ids[i+1] + "\"> Vote Up </span> <span style = \"cursor:pointer\" class = \"plblDisAgreeComment\" id = \"" + ids[i+1] +"\">Vote Down </span><span id = \"ptxtAgreeComment\" >"+ agrees[i+1] + " </span></td></tr>");
But when I am calling the jquery function
$(".plblAgreeComment").click(function(){
alert("hi");
}
Its not working. Please help me.
Description
You need jQuery .live() or .on() method to bind events to dynamically created html.
Choose .live() or .on() depending on the version of jQuery you are using.
.live() Available since jQuery 1.3. Attach an event handler for all elements which match the current selector, now and in the future.
.on() Available since jQuery 1.7. Attach an event handler function for one or more events to the selected elements.
Sample
$(".plblAgreeComment").live('click', function(){
alert("hi");
});
$(".plblAgreeComment").on('click', function(){
alert("hi");
});
More Information
jQuery.live()
jQuery.on()
Update: jsFiddle Demonstration
Use jQuery on since you are adding these items to your DOM dynamically
$(function(){
$("body").on("click",".plblAgreeComment",click(function(){
alert("hi");
});
});
on will work for current elements and future elements.
http://api.jquery.com/on/
on is available from jQuery 1.7 onwards, If you are using an older version of jQuery, you should check live http://api.jquery.com/live/
Try using .on in below syntax,
$(document).on('click', '.plblAgreeComment', function(){
alert("hi");
});
In the above code, use the table selector instead of document select.
two things.. you might have an extra character in class name when generating the html for your row.
class = \"plblAgreeCom
maybe should be:
class =\"plblAgreeCom
or you're attaching click handler before the DOM is being modified in which case:
$(".plblAgreeComment").click(function(){
alert("hi");
}
should be:
$(".plblAgreeComment").live("click", function(){
alert("hi");
}
If you want to bind events to dynamically injected DOM elements, you need to use the on method so that any new elements are bound to that event listener:
$(".plblAgreeComment").on("click", function(){
alert("hi");
}
Note: there are other methods, such as live() that will achieve similar effects, but they are being deprecated in favor of on, which handles this situation for every scenario.

ajax asp.net and jquery conflict

I have multiple jquery files in my project.
Yesterday googled this problem and find solution. I edited this
$(document).ready(function () {
with this
function pageLoad() {
Now problem is that if i will use this in all my jquery files. Every scripts will stops working.
That is two different things. The
$(document).ready(function () {
is from and to jquery, it tells when the DOM is loaded and it start executing the code inside.
The
function pageLoad() {
is from ASP.NET and it is one of handler of Application.Load (client-side)
The reason why it will stop working is because in the same page you can only have one event with the same name, by default pageLoad will be the handler of Application.Load but you can associate another name. I don't see why you have problems between the two, can you explain it better?
EDIT:
After your comment, if you want/need to use Sys.Application.add_load (by default pageLoad) you should add a different name for each js file you need.
From msdn:
// Attach a handler to the load event.
Sys.Application.add_load(applicationLoadHandler);
function applicationLoadHandler() {
// Redirect to alternate page if not business hours.
var d = new Date();
if (!(8 < d.getHours() < 17)) {
window.location = "AfterHours.aspx";
}
As you can see, you can give a different name to add_load and you should give a different name to use more than one for the same page/request.
}
Replace pageLoad with something like this:
$(function() {
// This will be executed when the page is loaded
});
or to avoid name collisions...
(function($) {
// This will be executed when the page is loaded
})(jQuery);
Edit: As rich.okelly pointed out the second example will run as soon as the script is loaded.

Executing a Javascript function from an asp.net codebehind?

OK, this feels like a question that should be easy to answer, but as with so much mixing of asp.net and jQuery, it's a bit of a nightmare.
What I want to do is be fading a div in and out at various times during the client's viewing of my asp.net page; I fade it out using jQuery's fadeTo() before triggering an UpdatePanel update (to indicate that the data there is not fresh) and I want to fade it in again once the UpdatePanel has been updated. I've gotten as far as updating the UpdatePanel in the codebehind, and this results in the div's content changing... but how do I fade the div back in again?
The way I see it, there are 2 ways; register an event handler on page load to detect when the div's content has been changed and fade it back in, or call a function from the asp.net codebehind when I've updated the div to fade it back in.
In the first case, there doesn't seem to be any event triggered by the div's content changing, so I can't seem to do that. If anyone knows how I could get a client event to trigger when I update the div, that would be a nice solution.
In the second case, I thought that this was what ClientScriptManager was for, but it doesn't quite do what I want. I want to be able to register a particular Javascript function with ClientScriptManager and then tell ClientScriptManager to execute it in the client, from my codebehind. You can't seem to do that. ClientScriptManager.RegisterClientScriptBlock() simply inserts some <script> into the HTML output, rather than calling a function. Presumably this would work if I kept registering things like:
<script>fadeBackIn();</script>
because the Javascript would be immediately evaluated and run, but this feels messy, and that feeling is intensified by the fact that I'd have to keep randomly generating a new unique value for the key argument of ClientScriptManager.RegisterClientScriptBlock(), because it's specifically designed to stop this kind of repeated code. However, I'm struggling to see an alternative. Can anyone come up with a good idea as to a better mechanism to get this to work?
I'd really like something along the lines of:
ClientScriptManager.RegisterClientScriptFunction("fadeBackIn", "function fadeBackIn(){ ... }");
[...]
ClientScriptManager.ExecuteClientScriptFunction("fadeBackIn");
but I don't see that functionality available. :-(
You can attach to the page loaded event. The pageLoaded handler recieves an argument of type PageLoadedEventArgs which contains a get_panelsUpdated method that you can call to enumerate all the UpdatePanels whose content was just updated.
Example:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded(sender, args)
{
var panels = args.get_panelsUpdated();
if (panels.length > 0)
{
for (var i in panels)
{
if (panels[i].id == "DesiredUpdatePanelId")
{
fadeBackIn();
}
}
}
}
Because html is stateless, you'll need an asynchronous way of determining if the content has changed in your div. I would try using the window.setInterval to check if your content has changed every 500ms or so.
If your div looks like this:
<div id="mycontent">Blah, blah.</div>
Then this might be a solution:
$(function(){
var $mycontent = $('#mycontent');
var myContentHtml = $mycontent.html();
var intervalId;
function checkIfDivChanged()
{
window.clearInterval(intervalId);
if (myContentHtml != $mycontent.html())
{
myContentHtml = $mycontent.html();
// run update here..
fadeBackIn();
// if you want to stop the check then uncomment next line..
// return;
}
intervalId = window.setInterval(checkIfDivChanged, 500);
}
checkIfDivChanged();
});
If you are using, or are willing to use the ASP.NET Ajax Control Toolkit, it contains a control that does exactly what you are looking for: UpdatePanelAnimation.
Take a look here for more information on that control, and here for more information on using animations.
I have written small script with pure JavaScript (no jQuery required), you can just have this script in your page and change the alert part.. plus of course the ID of the div element.
<script type="text/javascript">
var _watchTimer = 0;
window.onload = function WindowLoad(evt) {
_watchTimer = window.setInterval("WatchForChange();", 100);
}
function WatchForChange()
{
var oDiv = document.getElementById("MyDivToWatch");
if (oDiv == null)
{
window.clearInterval(_watchTimer);
return;
}
var prevHtml = oDiv.getAttribute("prev_html") || "";
var curHtml = oDiv.innerHTML;
if (prevHtml != curHtml)
{
if (prevHtml.length > 0)
{
alert("content changed");
}
else
{
//first run, ignore
}
oDiv.setAttribute("prev_html", curHtml);
}
}
</script>
<div id="MyDivToWatch">I can be changed..</div>
<button type="button" onclick="document.getElementById('MyDivToWatch').innerHTML += ' like this..';">Change</button>
Added the whole code used to test, used a button to dynamically change the contents but it should work with changing it via AJAX call aka UpdatePanel.

JQuery Facebox Plugin : Get it inside the form tag

I am wanting to use the Facebox plugin for JQuery but am having a few issues getting it running how I want. The div that houses the facebox content is created outside of the tag so even though I am loading up some web controls none of them are firing back to the server.
Has anyone dealt with this that can give me some pointers?
poking around the facebox.js I came across this line in the function init(settings)...
$('body').append($.facebox.settings.faceboxHtml)
I changed that to ...
$('#aspnetForm').append($.facebox.settings.faceboxHtml)
and it loads up in the form tag, not sure yet if there are any side effects
You can use this code to register the PostBack event:
btn.OnClientClick = string.Format("{0}; $.facebox.close();",ClientScript.GetPostBackEventReference(btn, null));
this will let the button fires a PostBack.
Even after the :
$('#aspnetForm').append($.facebox.settings.faceboxHtml)
change I found it problematic. When you look at the page source using firebug you see that all the html in the div assigned to be the facebox div is doubled up (repeated).
So all of those controls with supposed unique id's are doubled up on the page, that can't be good on the postback, i've decided putting asp.net web controls in a facebox is not a good idea.
I modified facbox.js to do this. Maybe there is a better solution but this works like a charm
Here what i did:
add two lines on top of facbox.js before '(function($)'
var willremove = '';
var willremovehtml = '';
find "reveal: function(data, klass) {" and add this lines before the first line of function.
willremove = data.attr('id')
willremovehtml = $('#'+willremove).html()
$('#'+willremove).html('')
find "close: function() {" and make it look like below.
close: function() {
$(document).trigger('close.facebox')
$('#'+willremove).html(willremovehtml)
willremovehtml = ''
willremove = ''
return false
}

Categories