JQuery Mobile slider not working - jquery-mobile

I'm trying to get a slider to work in with JQuery Mobile 1.4.2.
What I would like to do is to use the slidestop event to update a value elsewhere. However, the slidestop event does not fire. I created a test file and tested in Safari and Firefox. Nothing happens when I stop sliding the slider. Could someone please tell me what tutorial I missed?
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/jquery.mobile.css" />
<script src="js/jquery.min.js">
</script>
<script src="js/jquery.mobile.js">
</script>
<title>Concertzender</title>
</head>
<body>
<label for="slider-step">Input slider:</label>
<input type="range" name="slider-step" id="slider-step" value="150" min="0" max="500" step="10" />
</body>
<script>
$( "#slider-step" ).on('slidestop',function( event ) { alert("slidestop event fired"); });
</script>
</html>
EDIT:
I tried the answer suggested below, but I have a slightly more complicated setup than the example above and, therefore, it doesn't work out.
I am trying to avoid the page structure of JQuery Mobile and just use it for the slider. The thing is, when I change to another page, a pagecreate or pageshow is not present, so I cannot wait for those events. What I want is to create a new slider (or rather replace an empty div with another already existing div and then change the id of the formerly empty div's input id. So what I am left with is a unique newly ID'ed input (with corresponding label).
How would I go about and use the slidestop to interact with the new slider? I tried this:
$('newslider').slider();
$('newslider').on('slidestop', function(){alert("slidestop");});
But that gives me two sliders in Safari, of which one does the slidestop and the other is unresponsive. In iOS, however, I get one slider that slides, but does not fire a slidestop event. Omitting the first line gives me an unresponsive slider in Safari and one that doesn't fire in iOS.
So my question is pretty simple: How to enable the slidestop event for a new slider without using JQuery Mobile's pages?

You need to wrap all events/bindings in pagecreate.
$(document).on("pagecreate", function () {
$("#slider-step").on('slidestop', function (event) {
console.log("slidestop event fired");
});
});
Demo

Related

jQuery click event not firing in jQueryMobile

Using jQuery jquery-1.9.1.js and jQueryMobile 1.3.1 (Chrome 26/Windows 7) I cannot see why one of these 'click' events bound to #one1 fires and the other doesn't:
HTML:
<div data-role="page" id="one" data-theme="a">
<div data-role="header" data-position="inline">
<h1>One</h1>
</div>
<div data-role="content" data-theme="a">
[one]
two
three
</div>
</div>
JavaScript:
<script>
$(document).on( "mobileinit", function() {
$(document).on('click', '#one1', function(e){
console.log('firing');
});
$('#one1').on("click", function() {
console.log('not firing');
});
});
</script>
When I run it in JSFiddle both events fire when not wrapped in the "mobileinit" event:
http://jsfiddle.net/9NRwa/
What am I missing here?
Intro
First thing first, mobileinit event should not be used for event binding. While it CAN be used like that mobileinit was not created for that purpose. It was created for jQuery Mobile parameter auto-initialization, so it should not be used for event binding.
Correct way is to use proper page events like pageinit. For more information about page events take a look at my other answer that covers various jQuery Mobile page events and their difference towards usual jQuery document ready paradigm: jQuery Mobile: document ready vs page events.
Not let me answer this question. Events like click can be bound in a few different ways.
Lets look at examples you have used:
Various ways of event binding with jQuery
First example
$(document).on('click', '#one1', function(e){
console.log('firing');
});
This first example is something new that came to use first with now deprecated method live.
Basically it's an event delegation mechanism that allows you to bind event handlers not just to all existing instances of a given node type, but also to any future instances of a given node type (by "type" I mean a set of DOM nodes matched by a given jQuery selector). What I want to say here is, during the event binding that element don't need to exist in a DOM, basically this method works by binding event handlers to the document itself and then reacting to all the events that bubble up through the DOM. So it doesn't matter if element #one1 exist or not during the event binding. You can create it dynamically later and it will still work.
Second example
$('#one1').on("click", function() {
console.log('not firing');
});
This is on old way of event binding. It requires that event exists in the DOM before event can be bind. In your case you were trying to bind this click event to the element that didn't exist in a DOM at that point in time. It doesn't matter it was loaded after the binding process.
Working example
jsFiddle example: http://jsfiddle.net/Gajotres/QmNsa/
Take a look at this example. There you will see 5 different ways of click event binding in jQuery Mobile:
2 click event are bound in HEAD, before page is initialized into the DOM
2 click events are bound in HEAD in pagebeforeshow event, basically this is also a delegation of binding because event are bound when page is about to be shown and already inside a DOM
1 click event is bound in a BODY after all page content. Because all content is loaded inside a DOM at this point this click event will work.
HTML :
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<script>
$(document).on('click', '#one1', function(e){
// This example will work because it was bind with event delegation process
console.log('Firing 1');
});
$('#one1').on("click", function() {
// This example will not work because event do not exist in this moment
console.log('Not firing');
});
$(document).on( "pagebeforeshow", function() {
// This example will work because it was bind with event delegation process
$(document).on('click', '#one1', function(e){
console.log('Firing 2');
});
// This example will work because element exist in a DOM during the pagebeforeshow event
$('#one1').on("click", function() {
console.log('Firing 3');
});
});
</script>
</head>
<body>
<div data-role="page" id="index">
<div data-theme="b" data-role="header">
<h1>Index page</h1>
</div>
<div data-role="content">
[one]
</div>
</div>
<script>
$('#one1').on("click", function() {
// This example will work because we are binding it when element is already loaded into the DOM
console.log('Firing 4');
});
</script>
</body>
</html>
Conclusion
Do not use mobileinit event for event binding, it will trigger before page is loaded into the DOM and only events bind with delegation will work.
Bind your events in a correct jQuery Mobile page events.
Usefull links regarding this topic:
jQuery Live() Method And Event Bubbling
While live method is deprecated on method should be used instead. In some benchmarks on method is 2x faster.
jQuery Mobile: document ready vs page events
Various jQuery Mobile page events
What does “event bubbling” mean?
As the docs stated:
Because the mobileinit event is triggered immediately, you'll need to
bind your event handler before jQuery Mobile is loaded
Currently, your mobileinit event are running after jQuery Mobile is loaded since jsFiddle will execute your javascript code after finish loaded any libraries you've chosen from the sidebar. To make it works, your structure should look like this:
<script src="jQuery library include first"></script>
<script>
$(document).on("mobileinit", function() {
// Your code here
});
</script>
<script src="jQuery Mobile include last"></script>

Why jQuery UI Dialog has no minimize, maximize buttons?

I am using jQuery-1.9.1 and jQuery-ui-1.10.2 to popup a dialog, my code is below:
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/jqueryUI/theme/redmond/jquery-ui- 1.10.2.custom.min.css" />
<script type="text/javascript">
$(function(){
$("#dialog").dialog();
});
</script>
</head>
<body>
<div id="dialog">
hello, this is a dialog
</div>
</body>
the dialog has only close button, no minimize and maximize buttons, but I want to show them. I find in this page, its dialog has minimize and maximize buttons, I don't find any special settings about dialog in author's javascript code, and the jQuery-ui version s/he used is 1.8.16, does jQuery-ui of my version has removed this functionality?
PS: my jQuery-1.9.1.min.js and jQuery-ui-1.10.2.min,js are downloaded from official website, no any customization change.
Looking at the source of jQuery UI in that example it looks like the guy that runs that blog site added customization for minimize and maximize support. You can find the following comment in the code.
/*
* jQuery UI Dialog 1.8.16
* w/ Minimize & Maximize Support
* by Elijah Horton (fieryprophet#yahoo.com)
*/
You will need to add customization's for the dialog to support this or include a library that extends the jQuery UI dialog. It looks like this site has a plugin called jquery-dialogextend that will do what you are asking for.
If you look towards the middle of the jquery-ui.js file linked in that page there is a section of unminified code from line 366 up to around line 1429 where he has added custom code to handle the minimize/maximize functionality.
Just note that there is no guarantee that section of code will work correctly (or at all) in any version of jQuery UI other than 1.8.16.
Also Check out jQuery Dialogr. I think this can help.
I made a little plugin with the widget factory that extends the jquery ui dialog.
I use the jquery widget factory to add new functionnalities
$.widget('fq-ui.extendeddialog', $.ui.dialog, {
...
})(jQuery);
In the Jquery UI dialog code, there is a _createTitlebar method.
I override it and add a maximize and minimize button
_createTitlebar: function () {
this._super();
// Add the new buttons
...
},
jquery-extendeddialog
sample page

jquery mobile + phonegap onclick

I've been trying to figure this out but still stuck.
so I'm using PhoneGap for iOS and JQueryMobile.
I'm trying to show alert when a button is clicked.
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here -->
<script type="text/javascript" charset="utf-8" src="cordova-1.6.1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js">
</script>
and I have
this
Login
$(document).ready("#button").click(function() {
alert('button clicked');
});
when I tried to launch this in chrome, this works fine.
however, when I used iphone simulator, it doesnt show anything.
For a normal web application you would use dom ready i.e.
$(function(){ // <-- this is a shortcut for $(document).ready(function(){ ... });
$('#button').click(function(){
alert('button clicked');
});
});
However in a JQM application it is much more useful to bind to 'pageinit' i.e.
$(document).on('pageinit','[data-role=page]',function(){
$('#button').click(function(){
alert('button clicked');
});
});
Binding to pageinit works better because JQM inserts new pages into the same dom as the first page. Because of this all of your code in dom ready doesn't get called again. So that first bit of code i put above will only work for that first page in your JQM application. The second will work no matter what page your button is in. Let me know if I can clarify this further for you.

How to initialize pages in jquery mobile? pageinit not firing

What's the right way to initialize objects on a jquery mobile page? The events docs say to use "pageInit()" with no examples of that function, but give examples of binding to the "pageinit" method (note case difference). However, I don't see the event firing at all in this simple test page:
<html>
<body>
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8" src="http://code.jquery.com/mobile/1.0b3/jquery.mobile-1.0b3.min.js"></script>
<div data-role="page" id="myPage">
test
</div>
<script>
$("#myPage").live('pageinit',function() {
alert("This never happens");
});
</script>
</body>
</html>
What am I missing? I should add that if you change pageinit to another event like pagecreate this code works.
---- UPDATE ----
This bug is marked as "closed" in the JQM issue tracker. Apparently opinions differ about whether this is working properly or not.
It started working when I embedded script within page div:
<body>
<div id="indexPage" data-role="page">
<script type="text/javascript">
$("#indexPage").live('pageinit', function() {
// do something here...
});
</script>
</div>
</body>
Used jQuery Mobile 1.0RC1
.live() is deprecated, suggestion is to use .on() in jQuery 1.7+ :
<script type="text/javascript">
$(document).on('pageinit', '#indexPage', function(){
// code
});
</script>
Check the online doc for more information about .on(): http://api.jquery.com/on/
Turns out this is a bug in 1.0b3 that is fixed in the current head. So if you want a fix now, you gotta grab the latest from git. Or wait for the next release.
jQuery(document).live('pageinit',function(event){
centerHeaderDiv();
updateOrientation();
settingsMenu.init();
menu();
hideMenuPopupOnBodyClick();
})
This is working now. Now all page transitions and all JQM AJAX functionality would work along with your defined javascript functions! Enjoy!
pageinit will not fire in case it is on secondary pages ( NOT MAIN page ) if it is written in common <script> tag...
I have such a problem - on secondary pages that are not loaded with 'rel="external"', the code in the common <script> tag is never executed...
really this code is always executed...
<body>
<div id="indexPage" data-role="page">
<script type="text/javascript">
$("#indexPage").live('pageinit', function() {
// do something here...
});
</script>
</div>
</body>
althrough if you made "tabbed interface", using of "pageshow" is better
I had to put the script in the HTML page section which to me is a bug. It is loaded normally in a browser (not via AJAX) and all on a single page including javascript. We're not supposed to have to use document ready.
The easiest way I found to deal with this was to use JQM + Steal. It works like a charm as long as you put:
<script type='text/javascript' src='../steal/steal.js?mypage'></script>
Inside of the data-role='page' div.
Then use AJAX to connect anything that can use the same mypage.js and use an external link (by using the rel="external" tag) to anything that requires a different steal page.
#Wojciech Bańcer
From the jQuery docs:
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
Try this:
$('div.page').live('pageinit', function(e) {
console.log("Event Fired");
});
$(document).on("pageinit", "#myPage", function(event) {
alert("This page was just enhanced by jQuery Mobile!");
});
The events don't fire on the initial page, only on pages you load via Ajax. In the above case you can just:
<script>
$(document).ready(function() {
alert("This happens");
});
</script>

Jquery UI button gets disabled on refresh

I asked about this on the jquery forum a few weeks ago without luck, so I will try again here :)
I've made a simple widget for a project I'm working on, but I have encountered an odd problem.
It is easiest to explain it with an example implementation.
http://decko.dk/buttontest
On the page there are 3 button. The first one is my drop down widget. The next one is a regular disabled button (A) and the last one a regular enabled button (B).
If you then refresh the page (press F5 or whatever) the enabled button is mysteriously now disabled.
I have no clue why this happens, but if button A is not disabled to begin with, button B will not be disabled when refreshing. Also, if I remove the call to insertAfter in my widget-code, the button will not be disabled.
Can anyone shed light on why this strange behavior occurs?
By the way, I have only been able to reproduce this in Firefox.
I believe this is a bug in how Firefox remembers form field/control values and states:
After the first page load, there are three <button> elements in the document, and <button id="button_a"> is disabled. (When the jQuery UI styled button is enabled or disabled, it sets the underlying element to the same state.)
Firefox remembers that the second <button> is disabled.
After a page refresh, before any scripts are run, Firefox restores form fields and controls. It disables the second <button>, but since no script has been run, the second button is <button id="button_b">.
When jQuery UI creates the styled button for <button id="button_b">, it sees that it is disabled and continues to style it as disabled.
There are two issues here:
How Firefox remembers which elements are disabled. It's not taking into account dynamic elements. I suggest filing a bug with Mozilla for this.
Form elements stay disabled after a page refresh. I'm not sure if this is the correct behaviour, but there are two bugzilla reports on this.
The test case can simplify down to just adding a <button> element dynamically and disabling <button id="button_a">, no jQuery / jQuery UI necessary:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>disabled button test</title>
<script type="text/javascript">
window.onload = function () {
var a = document.getElementById('button_a'),
menu = document.createElement('button');
menu.appendChild(document.createTextNode('Menu'));
document.body.insertBefore(menu, a);
a.disabled = true;
};
</script>
</head>
<body>
<button id="button_a">A</button>
<button id="button_b">B</button>
</body>
</html>
I've been getting this problem also and worked out it was down to silly behaviour in firefox, my fix was as so:
before:
//set up the buttons
$("button").button();
after:
//set up the buttons (and make sure firefox behaves)
$("button").button().attr("autocomplete", "off");
Setting the Expires HTTP header to a date in the past, solved the problem for me in Firefox 6.0.
Here is the solution I found works really well in all browsers...
I give each button (that can be disabled) a class 'js_submit'
I then re-enable any disabled buttons with class 'js_submit' on the pagehide event that fires when a page is unloaded.
I wrap the event assignment inside a try catch to prevent browsers that don't support this event from throwing an error (such as IE).
Here is the code:
<input id="button" type="button" value="Submit" class="js_submit" />
// Fix for firefox bfcache:
try {
window.addEventListener('pagehide', PageHideHandler, false);
} catch (e) { }
//Fires when a page is unloaded:
function PageHideHandler() {
//re-enable disabled submit buttons:
$('.js_submit').attr('disabled', false);
}
In my case it was a Bootstrap bug
<input id="appointmentBtn" type="button"
ng-click="addAppointment()" class="btn btn-primary btn-xs
disabled" value="Add Appointment">
Instead it should have been
<input id="appointmentBtn" type="button"
ng-click="addAppointment()" class="btn-primary btn-xs
disabled" value="Add Appointment">

Resources