Cannot bind click() event to HTML control - javascript

Here's my setup. I'm using .NET:
I have a Main.aspx lets call it. That page inherits a master page and the Master Page as usual includes the jQuery library and other includes that we use for jQuery that are global in scope
In Main.aspx is an HTML plain vanilla IFrame:
In that IFrame is another .aspx page. Lets call it for all tense and purposes Sub.aspx
In Sub.aspx I've got the following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<link href="Content/Styles/Site.css" rel="stylesheet" type="text/css" />
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div id="facebookPhotos-iFrameContent">
<div>
<p id="buttoTestContainer">
<input type="image" id="btnLogin" src="images/loginBtn.jpg" />
</p>
</div>
</div>
</form>
<script type="text/javascript">
var loginButtonID = 'btnLogin';
//alert(loginButtonID);
window.fbAsyncInit = function () {
// Initialize/load the JS SDK
// cookie is set to true to activate JS SDK cookie creation & management
FB.init({ appId: facebookApplicationID, status: true, cookie: true, xfbml: false });
alert("got here");
// also handles the case when they are already logged in
$('#' + loginButtonID).click(function () {
alert("login button was fired");
TestLogin();
});
//...rest of code
});
The problem:
When trying to debug to make sure that .click() event gets called so it binds to my control, I never get to the first alert "got here" so that I know the JS was called at least up to that point. So not sure why. I see absolutely no JS errors in my FireBug console either.

Your function never executes. Remove the window.fbAsyncInit = function() { } and the code will run as interpreted. Or, use $(document).ready(function() { }); to execute it after the DOM is ready.
Also, the Javascript libraries in the parent frame are not inherited by the child. But you can reference them like parent.fbAsyncInit = function() { } or parent.jQuery(); for example.

resolved. That init function should be the only thing in there. Moved all other code outside the window.fbAsyncInit because I do not want to load the others asynchronously, I want to load it after the DOM has completed. The only thing that should be loaded at the same time is the registering/Initialization of that SDK.

Related

Javascript Function Not Being Called after dynamic loading

I have a weird issue that i am hoping someone can help resolve.
Problem
When i load html dynamically via .load() function, if any aspect of html in the loaded fragment tries to access the javascript query functions in original HTML page, it doesn't work. Example code below:
Main HTML page (main.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<!--javascript load functions etc... standard header stuff -->
</head>
<body>
<div id="dynamic_section_fragment"></div>
Load Fragment
<script type="text/javascript">
// <![CDATA[
function loadFragment() {
$("#dynamic_section_fragment").load("/api/fragment/");
};
$(".checkvalue").click(function () {
$.getJSON("/api/checkvalue", {term: $(this).attr('value')}, function () {
console.info("submitted for checking");
})
});
// ]]>
</script>
</body>
</html>
FRAGMENT File (fragment.html)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
</head>
<body>
<div th:fragment="check_value">
<br/>
Check the value in the attribute field
<br/>
<a href="javascript:" th:attr="value='123'" class="checkvalue">Check This<a/>
</div>
</body>
</html>
SPRING MVC Controller Method
#RequestMapping("/api/checkvalue")
public String getFragment(Model model) {
return "fragment :: check_value";
}
So a run down of actions:
-Main.html page loads
-User clicks on Load Fragment hyperlink
-Javascript dynamically loads the relevant fragment into the div
-User clicks on Check This hyperlink, nothing happens
Is there something i am missing or something i need to be aware?
It is as if Thymeleaf has preregistered all the possible scenarios of events and doesn't allow any others.
Only way i have been able to get it to work is by injecting the "checkvalue" javascript within the fragment, which as you can agree is a bad way of doing things.
Help is appreciated.
You are applying the click event listener to all existing objects with the checkvalue class.
$(".checkvalue").click(function ()
What you rather wish to do (to make the click event apply to all the existing and any new added, dynamically) is to set a event on a parent in the dom tree (parent both to the existing and to all that will be added).
In your case, the body tag would probably be the safe bet.
The following should suffice:
$('body').on('click', '.checkvalue', function() { ...
Simplified, the code will apply a listener on the body element instead of the .checkvalue objects, and whenever a object with the .checkvalue class is clicked (wether dynamically or statically loaded), the event will fire.
edit
I would also suggest that you, in your javascript, don't use jquery before you know for certain that it is loaded.
The jquery lib have a way of fixing this for you, by using the $( document ).ready() function:
$( document ).ready(function() {
// All jquery dependant code here.
});

What's wrong with this simple Safari Extension code?

I'm creating a Safari extension that will stay in Safari's menubar, and upon being clicked, it will open all links containing a certain string. However, it's not working.
This is what my extension builder screen looks like: http://i.imgur.com/xRXB1.png
I don't have any external scripts set as I have the script in my HTML file, because I only want it to run when clicked.
And I have a global.html page with the following code in it:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<script>
safari.application.addEventListener("comnand", performCommand, false);
Function performCommand(event) {
if (event.command == "open-designs") {
$(document).ready(function() {
$('a[href*="/Create/DesignProduct.aspx?"]').each(function() {
window.open($(this).attr('href'),'_blank');
});
});
}
}
</script>
</body>
</html>
Should this not work? I'm allowed to mix jQuery and JS write, as jQuery is JS? And isn't that how I'd target the links?
The problem is that your extensions Global page does not have direct access to the currently loaded page's DOM. To be able to achieve what you need, you'll have to use an Injected Script and use the messaging proxy to talk to the page.
For instance, your global would look like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<script>
$(document).ready(function() {
safari.application.addEventListener("command", performCommand, false);
});
function performCommand(event) {
if (event.command == "open-designs") {
safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("open-designs", "all");
}
}
</script>
</body>
</html>
And then, in Extension Builder, you'd need to add two "Start Scripts", one is jquery, the other, a new file that gets loaded into the page and looks similar to this:
function extensionname_openAll(event)
{
if (event.name == 'open-designs')
{
$('a[href*="/Create/DesignProduct.aspx?"]').each(function(index,elem) {
window.open($(elem).attr('href'),'_blank');
});
}
}
safari.self.addEventListener("message", extensionname_openAll, true);
One clear thing I'm seeing is that your $(document).ready() function is located within another function. This essentially alleviates the need for a $(document).ready() provided you only call that function once the DOM and jQuery are fully loaded.
Rearrange your code to only add the event listener once the DOM and jQuery are loaded. That is what you use the $(document).ready() callback for.
In addition there is one more issue I see with the callback function for .each(). That function needs to handle two parameters the index and the element that it references. A call to each() iterates over a collection of elements. For each element entering the callback function, its index is passed as a parameter and also the element itself that is located at that index. Check out the documentation for more info.
$(document).ready(function() {
safari.application.addEventListener("command", performCommand, false);
console.log("Document is ready to go!");
});
function performCommand(event) {
console.log("event recieved");
if (event.command == "open-designs") {
console.log("got 'open-designs' event");
$('a[href*="/Create/DesignProduct.aspx?"]').each(function(index,elem) {
console.log("opening window", index, elem);
window.open($(elem).attr('href'),'_blank');
});
}
}
You use the $(document).ready() callback as an indication that your DOM is ready and jQuery has been initialized. Once you know everything is ready, you can setup your event listener.
The function performCommand() can not be called before the listener is added (unless there is some other reference to it).

Long Press - ASP.NET

I am in the process of handling a Long Press event in the JavaScript of an ASPX page but since I don't have much experience with JavaScript having a couple issues. I am working of a question which was already asked here.
When I run the code I get the message "$ is not defined" and when I change $("Button1") to ("Button1") then I get the message stating the mouseup function doesn't exist. The primary problem I'm having is accessing the aspx control properly. Below is my code.
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
$(function () {
var pressTimer;
var longPress = 1000;
$("#<%= Label1.ClientID %>").bind("touchend", function (e) {
var d = new Date();
var timeDiff = d - pressTimer
if (timeDiff > longPress) {
document.getElementById("demo").innerHTML = "Mouse Up";
//actual logic here
}
return false;
});
$("#<%= Label1.ClientID %>").bind("touchstart", function (e) {
pressTimer = new Date();
return false;
});
});
</script>
<title>Long Press Testing</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:label ID="Label1" runat="server" text="Hold This Down" />
<br />
<p id="demo"></p>
</div>
</form>
</body>
</html>
Thanks for the help.
[EDIT] - Turns out I was missing the ready statement so the event is now firing as it should. This is the final version which is behaving properly. Also I wrote this to handle long press functionality on the iPad so if anyone is trying to do that this code is a good place to start.
You are missing jQuery script registration in head section like:
<script src="jquery.js"></script>
$ sign is jQuery's identifier, not JavaScript's.
Also, your buttons will not work, because you are referencing server button, but you must provide an id for JavaScript to work properly:
$("#<%= Button1.ClientID %>").mouseup(function () {
clearTimeout(pressTimer)
// Clear timeout
return false;
})
Looks like you are attempting to use jQuery (or another similar framework) without actually registering the appropriate script. You will need an <script/> block or some similar construct.
Looks like you havent included jquery in your project. you can include it by using the google hosting below, or go to jquery.com and download it and include it. your going to want to put in the Head tag above the other scripts you wrote. also, you might want to add a # before the id because it uses css selectors. Also, im not sure how much of the code will execute because thats a server button which will cause a post back.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

Facebook Open Graph - 'Like Button' - Hidden Content Revealed Upon 'Like'

I was wondering, I wish to have a landing page with Facebook's Open Graph (specifically the like button) and I wanted to basically have content set to display:none (can't remember the specific until a user likes a page. An example being a div on an e-commerce store that when a user likes the page, the div is set to display:block and users can redeem a coupon code for discount.
I would like to be able to do this with div displays.
I saw this little snippet of code on the Facebook developers forum:
| ( taken from http://fbrell.com/xfbml/fb:like )
(Note: The event that's fired when you click "like")
<script>
// this will fire when any of the like widgets are "liked" by the user
FB.Event.subscribe('edge.create', function(href, widget) {
Log.info('You liked ' + href, widget);
});
</script>
Can this be modified to effective set a div from display:none to display:block?
Thank you SO.
If you specifically want to update your div to display:block, use...
<script>
// this will fire when any of the like widgets are "liked" by the user
FB.Event.subscribe('edge.create', function(href, widget) {
$('#divid').css('display','block');
});
</script>
One caveat...
Your edge.create event WON'T fire unless the URL you use as part of your call is EXACTLY the same as the URL you're attempting to fire this from.
I had a site I was running on example.DEV (my local laptop dev env) which referenced a link on example.com (the live server) and anything in the FB.Event.subscribe() block wouldn't run until I uploaded the file, and fired it from the LIVE server.
That could be why you're having trouble if it's not working so far!
I found the following solution, but you will need jQuery to do it. (possibly not, but that's what I used to do it).
Here is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="facebook.js"></script>
<script src="jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div id="fb-root"></div>
<script type="text/javascript">
<!--
window.fbAsyncInit = function() {
FB.init({appId: '133387220039676', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('edge.create', function(href, widget) {
// Do something, e.g. track the click on the "Like" button here
$('#slidingDiv').show();
});
};
(function() {
var e = document.createElement('script');
e.type = 'text/javascript';
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
//-->
</script>
<fb:like href="http://www.facebook.com/TheRightMind" layout="standard" show-faces="false" width="450" action="like" colorscheme="light"></fb:like>
<div id="slidingDiv" style="display:none;">
Fill this space with really interesting content that you can
</div>
</body>
</html>
Just replace the Log.info() call with JavaScript that displays the div. In jQuery:
<script>
// this will fire when any of the like widgets are "liked" by the user
FB.Event.subscribe('edge.create', function(href, widget) {
$('#yourdiv').show();
});
</script>
After verifying that liking the page will trigger that code (try console.log("AOK!")), you can make a <div> appear using this code:
Plain Old JavaScript:
FB.Event.subscribe('edge.create', function(href, widget) {
document.getElementById("topsecret").style.display = "block";
});
The HTML:
<div id="topsecret" style="display:none;">
Content Goes Here
</div>
If you're using the jQuery library or something similar, you can use a show() function to make the box appear instead:
FB.Event.subscribe('edge.create', function(href, widget) {
$("#topsecret").show();
//$("#topsecret").slideDown("fast");
//$("#topsecret").fadeIn("fast");
});
You might also consider using an AJAX load command instead, because otherwise it's fairly easy to make the box appear when the content is only hidden.
FB.Event.subscribe('edge.create', function(href, widget) {
$("#topsecret").load("mycontent.html");
});

JavaScript: trouble assigning event handlers

I'm not sure what I'm doing wrong here:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
eventInit.js
window.onload = function () {
alert("check"); // works
var jsWarning = document.getElementById("javascriptWarning");
jsWarning.onclick = function () {
alert("hi"); // works
};
jsWarning.onload = function () {
alert("loaded"); // fails
};
}
And yet, nothing happens. What am I doing wrong? I've tried other events, like onmouseover and onload.
I'm doing this in Visual Studio, and intellisense isn't giving me options for setting any event handlers. Is that because I'm doing this wrong?
I have confirmed that JS is working on my setup; just putting alert("hi") in a script and including it does work.
It might be important to note that I'm doing this in JScript, since I'm using Visual Studio 2010, so perhaps event handling is different?
Updated to remove '-' from the ID name, but it still doesn't work.
Updated added the window.onload block. Now onclick works, but onload doesn't.
You are trying to set a load event on a paragraph. Only objects which load external data (window, frame, iframe, img, script, etc) have a load event.
Some JS libraries implement an available event (such as YUI) — but you know the paragraph is available, since you're setting an event on it, and you couldn't do that if it was unavailable.
maybe you forgot to have the code block inside a
window.onload = function() {
// btn click code here
}
You have to wait for the document to be parsed before you can go looking for elements by "id" value. Put your event handling setup into an "onload" function on the window object.
The browser won't fire an "onload" event on your <p> tag. You won't need that anyway if you do your work in the "onload" handler for the window as a whole.
[soapbox] Use a framework.
The script is executed before the desired element exists. Additionally, I don't think, p has an onload-Event. Windows, frames and images, yes, but paragraphs?
You should use <body onload="init();"> or window.onload=function(){ … } or a library function, if you use a library. Example:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
scripts/eventInit.js
window.onload=function(){
alert('JS is working!');}
Edit: Okay, I am very sure, p makes no use of an onload event handler. And it's no wonder, you don't need it. If you want to execute JS code just after the paragraph is finished, do this:
<p>
<!-- stuff -->
</p>
<script type="text/javascript">
/* stuff */
</script>
Instead of this:
jsWarning.onload = function () {
alert("loaded"); // fails
};
try this
if(jsWarning) alert("loaded");
I think someone above mentioned checking for the existence of the element. At this stage the element should be present but it does no harms to check for it.
I think you have to make sure your JavaScript is binding.
Is your javascript before or after your paragraph element, for some reason my brain is aiming towards that.
I would look into using something like jQuery, it will help.
using jQuery your code would be (with the relevant jQuery files included of course):
$(document).ready(function()
{
$("#javascript-warning").click(function(){
alert("HELLO");
});
});
I don't think hyphens are valid in class names when used in conjunction with JavaScript. Try an underscore instead.
onload is a window event.

Categories