JqueryMobile loading external script in body does not solve my ajax navigation issue - jquery-ui

I see some others (e.g. this post) have had trouble using external javascript scripts in JQuery Mobile - as of today I have joined their ranks.
I have a single external js script (controllers.js) which contains code that affects several pages on the site. It is loaded on every page of the site. I put the js file just before the tag it works fine on the initial page load. However when I navigate thereafter (using the JQM Ajax methods) all functions in the script stop working. I would have thought the script would remain in cache - but heyho. Anyhow there's an FAQ which answers this question and I've implemented their suggestion which is: "...to reference the same set of stylesheets and scripts in the head of every page." I have done this but when I do even on the first page load the js doesn't fire. There aren't page specific scripts - so the remainder of that FAQ does not apply.
My cut down html looks like this:
<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="/static/jquery-ui-1.10.3.custom.min.css">
<link rel="stylesheet" href="/static/jquery-mobile/css/themes/default/jquery.mobile-1.3.2.min.css">
<script src="/static/jquery-1.9.1.min.js"></script>
<script src="/static/jquery-ui/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js"></script>
<script src="/static/jquery-mobile/js/jquery.mobile-1.3.2.min.js"></script>
<!-- CSS: implied media="all" -->
</head>
<body>
<div data-role="page" id = "main-page">
<div data-role="header" style="overflow:hidden;">
</div>
<div id = "home" data-role="content">
<input type ='button' id = "some_btn" value="press me">
</div>
</div>
<script type="text/javascript" src="/static/js/controllers.js"></script>
</body>
</html>
and within the javascript file
controllers.js
$('#some_btn').click(function()
{
alert('button pressed');
});
Any ideas on what I may be doing wrong here?

Since the content in the #page is loaded dynamically via ajax, click will not work, since it only works on elements that are on the page when the script is called.
You need to use the .on() method:
$('body').on('click','#some_btn',function()
{
alert('button pressed');
});

Related

angular.dart seems to be slow

I am trying angular.dart and saw that its slow. When am html page is loaded containing angular, angular directive is seen first, which are then converted appropriately. Shouldn't it be converted instantaneously and the user should not see whether we are using angular ?
<!DOCTYPE html>
<html ng-app>
<head>
<title>Hello, World!</title>
</head>
<body>
<h3>Hello {{name}}!</h3>
name: <input type="text" ng-model="name">
<script type="application/dart" src="main.dart"></script>
<script type="text/javascript" src="packages/browser/dart.js"></script>
</body>
</html>
Surround {{name}} with a tag having class="ng-cloak". I used span tag. Keep it hidden by specifying css rule .ng-cloak{ display:none; }.
When angular is loaded, it will remove class="ng-cloak" from the span tag and everything will work as expected.
<!DOCTYPE html>
<html ng-app>
<head>
<title>Hello, World!</title>
<style>
.ng-cloak{ display:none;}
</style>
</head>
<body>
<h3>Hello <span class="ng-cloak">{{name}}</span>!</h3>
name: <input type="text" ng-model="name">
<script type="application/dart" src="main.dart"></script>
</body>
</html>
An alternative way is to use ng-bind as demonstrated in this youtube video: AngularJS MTV Meetup: Best Practices (2012/12/11) (after about 12 minutes)
Quoted from the API doc of NgBindDirective class
Typically, you don't use ngBind directly, but instead you use the
double curly markup like {{ expression }} which is similar but less
verbose.
It is preferrable to use ngBind instead of {{ expression }} when a
template is momentarily displayed by the browser in its raw state
before Angular compiles it. Since ngBind is an element attribute, it
makes the bindings invisible to the user while the page is loading.
This way you can display default content that get's replaced when Angular is ready
instead of showing a blank page or a progress icon.

jQuery Mobile vclick fired twice

I have an issue with vclick (or click) events when fired.
This is my html code:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Document</title>
<link rel="stylesheet" href="css/jquery.mobile-1.3.1.css">
<link rel="stylesheet" href="css/estilo.css">
<script src="js/cordova-2.6.0.js"></script>
<script src="js/jquery-2.0.0.js"></script>
<script src="js/functions.js"></script>
<script src="js/jquery.mobile-1.3.1.js"></script>
</head>
<body>
<div data-role="page" id="page">
<div data-role="header" position="fixed">
<h1>Data</h1>
</div>
<div data-role="content">
<div id="btn_comentar">
</div>
</div>
</div>
</body>
</html>
And this is my functions.js
$(document ).bind("mobileinit", function(){
$(document).bind("pageinit",function(){
$("#btn_comentar").bind("vclick",function(e){
console.log(e.isDefaultPrevented());
console.log(e.result);
console.log(e.relatedTarget);
alert("buttooon");
list_comments();
});
});
}
When I click my #btn_comentar, the data that I want to retrieve from function list_comments (sending via ajax) is duplicated; I realized that it was sending twice, and finally that it was something about when I clicked on my button.
This is the output from the console (twice):
false
undefined
null
and also the alert message box (twice) "buttoon";
I have tried some solutions like:
jQuery Mobile : replace click event by vclick event
but without success, please need some help
This is my new code and how it is now working, but it seems that without jQuery Mobile's default configuration
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Document</title>
<link rel="stylesheet" href="css/jquery.mobile-1.3.1.css">
<link rel="stylesheet" href="css/estilo.css">
<script src="js/cordova-2.6.0.js"></script>
<script src="js/jquery-2.0.0.js"></script>
<script src="js/custom-mobile.js"></script>
<script src="js/jquery.mobile-1.3.1.js"></script>
<script src="js/functions.js"></script>
</head>
<body>
<div data-role="page" id="page">
<div data-role="header" position="fixed">
<h1>Data</h1>
</div>
<div data-role="content">
<div id="btn_comentar">
</div>
</div>
</div>
</body>
</html>
custom-mobile.js
$(document ).bind("mobileinit", function(){
//$.mobile.allowCrossDomainPages = true;
});
functions.js
$(document).on("ready",function(){
$("#btn_comentar").bind("vclick",function(){
list_comments();
});
});
According to docs,
These enhancements are applied based on jQuery Mobile's default configuration, which is designed to work with common scenarios, but may or may not match your particular needs. Fortunately, these settings are easy to configure using the mobileinit event.
So that's what you need to use mobileinit for. For setting defaults like this :
$(document).bind('mobileinit', function(){
$.mobile.defaultTransition = 'slideup';
});
If my understanding is right, mobileinit is included/fired before jQuery Mobile's js is included. Assuming you done that, your script order must look like this :
<script src="jquery.js"></script>
<script src="custom-scripting.js"></script> <!-- This script must have mobileinit -->
<script src="jquery-mobile.js"></script>
At this point of time (when custom-scripting.js is loaded), pageinit wouldnt be defined.
It would be wise to add your pageinit event AFTER jQM script.
<script src="jquery.js"></script>
<script src="custom-scripting.js"></script> <!-- This script must have mobileinit -->
<script src="jquery-mobile.js"></script>
<script>
$(document).bind("pageinit", function(){
$(document).bind("vclick", "#btn_comentar" ,function(e){
console.log(e.isDefaultPrevented());
console.log(e.result);
console.log(e.relatedTarget);
alert("buttooon");
list_comments();
});
});
</script>
use once on pageinit:
$(document).on('pageinit') {
$("#btn_comentar").on("vclick",function(e){
console.log(e.isDefaultPrevented());
console.log(e.result);
console.log(e.relatedTarget);
alert("buttooon");
list_comments();
});
}
this should work
Another cause of double-vclicks I've encountered is due to Chromium synthesizing both touch events in addition to mouse events. I confirmed this cause by running the app in desktop Chrome's developer "device mode" (where the mouse cursor changes into a circle), confirming the problem exists, then toggling off device mode, and confirming the problem is "fixed".
jblas discusses it, partial excerpt:
Note that vclick does NOT suppress the synthesized mouse/click events that are generated by the browser because it does not know what context it is being used in, AND form input elements require the mouse/click events to function normally.
If you use a joystick or mouse (desktop), the alert will fire on the normal mouse click event.
If you want to suppress the click event while using touch, you have to call event.preventDefault() in your vclick handler. This will queue the request to kill the click event that follows but due to the differences in the way device vendors implement their events, and some bugs within different android OS versions, this turns out to be very hard to do. We try a couple of methods to figure out whether or not to kill a click event ... one is based on the element the touch event was triggered, on, and another is the position of the touch event. This is necessary because The browser does not necessarily dispatch the mouse events to the same element that it used for the touch event.

Facebook helper not appearing in MVC4

I created a new test project in MVC4 to test if I could use Facebook Helper from the Nuget gallery. I followed the instructions which are very simple, point and click to install the Facebook helper from Nuget, edit your page, and insert like button.
When I run the project I can actually see the facebook likebutton being generated when I view it through firebug, but it does not appear on the page.
Here is my default index page
#{
ViewBag.Title = "Home Page";
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<p>
To learn more about ASP.NET MVC visit
http://asp.net/mvc.
The page features <mark>videos, tutorials, and samples</mark> to help you get the most from ASP.NET MVC.
If you have any questions about ASP.NET MVC visit
our forums.
</p>
</div>
</section>
}
<h3>We suggest the following:</h3>
<div>
#Facebook.LikeButton()
</div>
I´ve gone through several pages regarding Facebook helper and they all describe the process in the same way. Does anyone know if I should config any files before using this library?
Edited:
I will paste my html code that is loaded into the markup after execution. I will abbreviate some scripts and stuff since it has many hundreds of line of code :)
<html id="facebook" class="" lang="en">
<head>
<meta charset="utf-8">
<script>
<script>
<noscript><meta http-equiv="refresh" content="0; URL=/plugins/like.php?href=http%3A%2F%2Flocalhost%3A13876%2F&layout=standard&show_faces=src&width=450&action=like&colorscheme=light&height=80&font&locale=en_US&ref&_fb_noscript=1" /></noscript>
<meta content="noodp, noydir" name="robots">
<meta id="meta_referrer" content="default" name="referrer">
<meta content="Facebook is a social utility that connects people with friends and others who work, study and live around them. People use Facebook to keep up with friends, upload an unlimited number of photos, post links and videos, and learn more about the people they meet." name="description">
<link href="https://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flocalhost%3A13876%2F&layout=standard&show_faces=src&width=450&action=like&colorscheme=light&height=80&font&locale=en_US&ref" media="handheld" rel="alternate">
<title>Facebook</title>
<link href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yc/r/-WUN6qLbp5n.css" rel="stylesheet">
<link href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yf/r/gd49XKRAMNQ.css" rel="stylesheet">
<link href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yc/r/XaOowWd9_Aq.css" rel="stylesheet">
<link href="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yH/r/Dpn1SKTH3-z.css" rel="stylesheet">
<script src="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yB/r/Vm1JnKckidu.js">
<script src="https://fbstatic-a.akamaihd.net/rsrc.php/v2/y-/r/ARN_8tuLdws.js">
<script src="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yq/r/XboiPeV3jQI.js">
<script>
<script>
<script src="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yP/r/eTzqwp1jxjF.js" async="">
<script src="https://fbstatic-a.akamaihd.net/rsrc.php/v2/yh/r/aTzvHAZI_Jd.js" async="">
</head>
<body class="plugin ff4 win Locale_en_US">
<div id="FB_HiddenContainer" style="position:absolute; top:-10000px; width:0px; height:0px;"></div>
<script>
<script>
<script>
</body>
</html>
See where in the Url it generates (link href="https://www.facebook...) it says "&show_faces=src"
That causes the problem; it should be "&show_faces=true"
Even though true is supposed to be the default, if you have this issue try changing it to: #Facebook.LikeButton(showFaces: false)
EDIT: this only helps if you set it to false. Same issue with LikeBox and all boolean properties.
If the HTML is being rendered I can only assume the problem it's a CSS problem, check the styling of the elements in FireBug and make sure they aren't being hidden e.g. check for display: none or visibility: hidden or make sure there isn't float applied which is taking it off the screen.

Phone Gap with Jquery Mobile won't open internal links

I have a phone gap application with jquery mobile and I can get external links to work and single page navigation working but I cannot open another file in my application. All the files are located in the www folder. The error message is "Failed to load webpage with error: The requested URL was not found on this server. If i comment out the jquery-1.6.4.min.js file it will work but that's not a good solution. I've tried rel="external" and several other things I've seen by googling but nothing seems to work
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,
user-scalable=no;" />
<meta charset="utf-8">
<link rel="stylesheet" href="include/jquery.mobile-1.0.min.css" />
<script src="include/jquery-1.6.4.min.js"></script>
<script src="include/jquery.mobile-1.0.min.js"></script>
<script type="text/javascript" charset="utf-8" src="phonegap-1.3.0.js"></script>
<script type="text/javascript">
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady()
{
//do something
}
</script>
</head>
<body onload="onBodyLoad()">
<div data-role="page" id="manage">
<div data-role="content" id="inputs">
About
</div>
</div>
</body>
</html>
Make sure that you update your PhoneGap manifest. Look for PhoneGap.plist, open it and look for ExternalHosts. You need to add the urls one by one, or you can simply add "*". This will allow the use of all urls within the application. PhoneGap blocks all urls by default.

Disabling Ajax in JQueryMobile

I'm trying to use JQueryMobile for an POC and it seems even though I use #using (Html.BeginForm()) instead of #using (Ajax.BeginForm()), ajax is enabled by default. It is being injected from one of the script files [ ~/Scripts/jquery.mobile-1.0a2.js ].
So what I want is to simply disable the Ajax for certain forms and do full form posts. This might be pretty abvious, but i simply cant get my head around it.
Any help is appreciated.
/BB
You have to set up the jquery mobile framework correctly to disable its auto - ajax
Here it's documented:
http://jquerymobile.com/demos/1.0a3/#docs/api/globalconfig.html
You could do something like this.
<html lang="en-us">
<head>
<title>#ViewBag.Title</title>
<link href="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.css" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.min.js")" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
$(document).bind("mobileinit", function () {
$.mobile.ajaxFormsEnabled = #ViewBag.EnableAjax;
});
</script>
<script src="http://code.jquery.com/mobile/1.0a3/jquery.mobile-1.0a3.min.js" type="text/javascript"></script>
</head>
<body>
<div data-role="page" data-cache="never">
<div data-role="header">
<h1>#ViewBag.HeaderString</h1>
</div>
<div data-role="content">
#RenderBody()
</div>
<div data-role="footer">
<h1>HTDE</h1>
</div>
</div>
</body>
</html>
Just add the following line to your page, obviously you have too add this under the document.Ready() function:
$.mobile.ajaxEnabled = false;
Note: If you are using Jquery Mobile beta, the configuration parameter for disabling ajax has changed.
http://jquerymobile.com/blog/2011/06/20/jquery-mobile-beta-1-released/
"Use ajaxEnabled to globally set auto-ajax handling."
Here's a link to the documentation for beta configs:
http://jquerymobile.com/demos/1.0b2/#/demos/1.0b2/docs/api/globalconfig.html
It took me way to long to figure this one out.
there is an easier way.. just figured it out from JqueryMobile documentation
http://jquerymobile.com/demos/1.0a3/#docs/api/globalconfig.html
all you have to do is,
ajaxFormsEnabled :false

Resources