$(":mobile-pagecontainer") is not working. I have to use $(document).
Anything wrong with the following code?
<div data-role="page" id="page1">
<div data-role="header" >
<h1>Page 1</h1>
</div>
<div role="main" class="ui-content">
This is Page1.
<a id="gotoPage2" href="#page2" class="ui-btn ui-corner-all ui-shadow ui-btn-a">Go to Page 2</a>
<script>
// not working
$( ":mobile-pagecontainer").on( "pagecontainerhide", function( event, ui ) {
alert( "page hide ");
});
// working
$( document).on( "pagecontainerhide", function( event, ui ) {
alert( "page hide " );
});
</script>
</div>
</page>
<page data-role="page" id="page2">
....
</page>
But it works for changing page as followings:
$(":mobile-pagecontainer").pagecontainer("change", "#page2", { } );
Thanks.
$(":mobile-pagecontainer") is a selector that refers to wrapper of all pages, internal or external. By default body is :mobile-pagecontainer and .pagecontainer() is a widget used to emit jQuery Mobile's special events and used for navigation.
jQuery Mobile events bubble up to document so you can use to capture those events.
$(document).on("pagecontainershow", function (e, data) {
console.log(data.toPage); /* current active page */
console.log(data.prevPage); /* previous page */
});
If you want to attach events to pageconatiner, you have to wrap them in .ready() in order to make them work.
$(function () {
$(":mobile-pagecontainer").on("pagecontainerhide", function (e, data) {
console.log(data.toPage); /* page navigating to */
console.log(data.prevPage); /* page that was just hidden */
});
});
It is possible also to use the widget .pagecontainer().
$(":mobile-pagecontainer").pagecontainer({
hide: function (e, data) {
/* code */
},
show: function (e, data) {
/* code */
}
});
Related
I've converted a multi-page app intro single pages and now the swipes keep using the first page's targets.
On my first page I have:
$(document).on('pageshow', '#firstPage', function() {
$(document).on("swipeleft", function(event) {
$("body").pagecontainer("change", "secondPage.html", {
transition: "fade"
});
event.stopImmediatePropagation();
});
$(document).on("swiperight", function(event) {
$("body").pagecontainer("change", "lastPage.html", {
transition: "fade"
});
event.stopImmediatePropagation();
});
});
With HTML:
<div data-role="page" id="firstPage" data-dom-cache="false">
<!--CONTENT -->
<!-- PAGE JS -->
</div>
It works on the firstpage, but when I get to the second page it uses the first targets - secondPage.html and lastPage.html
my secondPage has this:
$(document).on('pageshow', '#secondPage', function() {
console.log('showing tags');
$(document).on("swipeleft", function(event) {
$("body").pagecontainer("change", "thirdPage.html", {
transition: "fade"
});
event.stopImmediatePropagation();
});
$(document).on("swiperight", function(event) {
$("body").pagecontainer("change", "firstPage.html", {
transition: "fade"
});
event.stopImmediatePropagation();
});
});
and HTML:
<div data-role="page" id="secondPage" data-dom-cache="false">
<!--CONTENT -->
<!-- PAGE JS -->
</div>
Etc etc...
I must add that my js code on each page is before the closing </div> of the page...so is being loaded by AJAX.
I did have this working on multi-page template, but the app has become quite big and for simplicity I decided to split it into separate pages.
I've integrated reCAPTCHA and it is working fine, except for when the users are too quick to click the Submit button right after checking the "I'm not a robot" checkbox. It takes quite some time for reCAPTCHA to register the user action via Ajax, and if they click on Submit too quickly, the g-recaptcha-response is missing, and the validation fails.
Hence my question: how to I grey out the Submit button until g-recaptcha-response value is available?
<form id="capform" action="/captchaverify" method="POST">
<div class="g-recaptcha" data-sitekey="..."></div>
<p>
<input id="capsubmit" type="submit" value="Submit">
</form>
I ended up using the data-callback attribute as described in the documentation:
<form action="/captchaverify" method="POST">
<div class="g-recaptcha" data-sitekey="..." data-callback="capenable" data-expired-callback="capdisable"></div>
<p>
<input id="capsubmit" type="submit" value="Submit">
</form>
JavaScript (mootools-based, but the general idea should be clear):
function capenable() {
$('capsubmit').set('disabled', false);
}
function capdisable() {
$('capsubmit').set('disabled', true);
}
window.addEvent('domready', function(){
capdisable();
});
Here's an example that begins with the submit button disabled, and enables it once the callback is received from reCaptcha. It also uses jquery validate to ensure the form is valid before submitting.
var UserSubmitted = {
$form: null,
recaptcha: null,
init: function () {
this.$form = $("#form").submit(this.onSubmit);
},
onSubmit: function (e) {
if ($(this).valid()) {
var response = grecaptcha.getResponse();
if (!response) {
e.preventDefault();
alert("Please verify that you're a human!");
}
}
},
setupRecaptcha: function (key) {
UserSubmitted.recaptcha = grecaptcha.render('recaptcha', {
'sitekey': key,
'callback': UserSubmitted.verifyCallback
//'theme': 'light'//,
//'type': 'image'
});
},
verifyCallback: function (response) {
if (response) {
$(".visible-unverified").addClass("hidden");
$(".hidden-unverified").removeClass("hidden");
}
}
};
I call setupRecaptcha from the page with a named function that's part of the js include.
<script>
var recaptchaLoader = function () {
UserSubmitted.setupRecaptcha("yourkey");
};
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoader&render=explicit" async defer></script>
You could simplify this. I use it in a multi-tenant application with different keys, and UserSubmitted is actually part of a larger library. You can't usenamespaces (UserSubmitted.somefunction) as the onload param either (to my knowledge).
I used #Html.RenderAction("_DisplayImages") to render a partial view.
#model List<Univems4.Models.ImageViewModel>
#foreach (var image in Model)
{
<div class="set">
<div class="header invisible">
<label class="edit">#image.Name</label>
<button class="close btnDeleteImage" title="Delete">×</button>
</div>
<img class="img-thumbnail edit" src="data:image/bmp;base64,#image.base64string" id="#image.Id" />
</div>
}
Upon button click, I want to refresh this partial view. The approach I tried is by using jQuery ajax get method.
$.get("/VmsMessage/_DisplayImages", null, function (data) {
//success
$('#bit').html(data);
}, "html");
The partial view was refreshed. but it no longer responds to the events. Why?
$(".set").hover(function (e) {
// do something
});
$(".edit").click(function (e) {
// do something
});
As the html will be genrated dynamically so events are not binded on DOM load you need to do event delegation:
$(document).on("mouseover",".set",function (e) {
// do something
});
$(document).on("click",".edit",function (e) {
// do something
});
I have a mobile app that will allow a user to tap on an item in a list, which will then populate a 'details' page, and navigate to that page.
When the user taps the back button, and selects another item in the list, the details page is updated with the new content, but the markup loses all kendo-ui-mobile styling.
Is there a way to trigger the enhanced content after the markup has been updated?
Here is my code (the relevant bits):
index.html
<div id="details" data-role="view" data-title="Details" data-layout="default">
<header data-role="header">
<div data-role="navbar">
<a id="back-button" class="nav-button" data-align="left" data-role="backbutton">Back</a>
<span data-role="view-title"></span>
</div>
</header>
<div id="details_body"></div>
</div>
router.js
$('.listItemLink').live('click', function(e) {
require(['views/companyDetailsView'], function (companyDetailsView) {
var view = new companyDetailsView({
model: companyDetails,
el: $('#details_body')
}).render(function(el) {
app.navigate('#details');
app.hideLoading();
}).el;
});
});
companyDetailsView.js
define([
'backbone',
'underscore',
'models/companyModel',
'text!templates/companyDetails.html'
], function (Backbone, _, companyModel, tmpl) {
'use strict';
return Backbone.View.extend({
tagName: 'li',
template: _.template(tmpl),
render: function (callback) {
this.$el.html(this.template(this.model.toJSON()));
callback(this.$el);
return this;
}
});
});
I've got multiple HTML pages that use the JQMobile framework; within these pages I'm using iScroll to create a native scrolling effect, all works fine.
I run into problems when using the JQM page transitions with iScroll, since it's loaded via ajax I know that I need to refresh iScroll on the new page so that it can correctly calculate the height and width after the DOM has changed.
I've looked into this and experimented with code (tried refresh() and destroying and recreating) but can't see to get it work, the iScroll works it's just not getting refreshed on page change (therefore not working), any ideas?
Code below!
<div data-role="page">
<div data-role="header">
</div><!-- /header -->
<div data-role="content">
<div id="wrapper">
<div id="scroller">
<p>Page content goes here.</p>
Page 2
</div>
</div>
</div><!-- /content -->
<div data-role="footer">
<div data-role="navbar">
<ul>
<li><a data-ajax="false" href="javascript:void(0);" onClick="homepage();"><img width="34px" height="34px" src="images/home_IMG_v2.png" /><!--<span class="nav">Home</span>--></a></li>
<li><a data-ajax="false" href="Guide.html" class="ui-btn-active ui-state-persist"><img width="35px" height="33px" src="images/guide_IMG_v2.png"><!--<span class="nav">Guide</span>--></a></li>
<li><a data-ajax="false" href="TaxCalculator.html" /><img width="76px" height="34px" src="images/calculator_IMG_v2.png" /><!--<span id="calc" class="nav">Calculator</span>--></a></li>
</ul>
</div>
</div><!-- /footer -->
</div><!-- /page -->
Using refresh()
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper', { hScrollbar: false, vScrollbar: false, checkDOMChanges: true});
setTimeout(function() {
myScroll.refresh();
}, 100);
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
Destroying iScroll and recreating
var myScroll;
function loaded() {
myScroll = new iScroll('wrapper', { hScrollbar: false, vScrollbar: false, checkDOMChanges: true});
setTimeout(function() {
myScroll.destroy();
myScroll = null;
myScroll = new iScroll('wrapper', { hScrollbar: false, vScrollbar: false, checkDOMChanges: true});
}, 100);
}
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
Try calling initialising iScroll when the jqm pageshow event fires e.g. in jqm 1.3.1:
$(document).on('pageshow', function (event, ui) {
myScroll = new iScroll('wrapper', { hScrollbar: false, vScrollbar: false, checkDOMChanges: true});
});
after domchanges you need refreshing iscroll
$('#videotagisc').iscrollview("refresh");
this not working means use setTimeout
setTimeout(function(){
$('#videotagisc').iscrollview("refresh");
},100);
var width = $( window ).width();
var height = $( window ).height();
var delay = 200;
var doit;
function keop() {
$("#wrapper").css({"height":height+"px","width":width+"px"});
setTimeout( function(){
myScroll.refresh() ;
} , 200 ) ;
}
/* < JQuery 1.8*/
window.addEventListener("load", function(){
clearTimeout(doit);
doit = setTimeout(keop, delay);
});
/* > JQuery 1.8*/
window.on("load", function(){
clearTimeout(doit);
doit = setTimeout(keop, delay);
});