Dynamically close dialog - jquery-mobile

In my jQM - Backbone app I add a dialog programmatically if a certain condition is true, like this
$('body').append('<div data-role="dialog" id="interlink" data-theme="b" data-close-btn="none" data-url="insignificant"></div> ');
// remove dialog from DOM on pagehide
$("#interlink").on('pagehide', function () {
$(this).remove();
// remove this views popup-containers
$('#interlink-video-popup-popup').remove();
});
Beside other content in the dialog there is a button to open a popup widget to play a video clip and a close button to close the dialog. The code for closing the dialog looks like this:
backBtnHandler: function(e) {
e.preventDefault();
$('#interlink').dialog('close');
$(this).remove(); // all DOM listeners get removed as well by jQuery
}
This works all well if the video clip is watched in full length, the popup widget closes on ended and the user clicks the dialog close button to close it.
A requirement is when the video clip is playing and the user scans another NFC tag the video should stop, trigger an ended event and close the popup. This is also working, however the dialog should also close. Here is a simplified code snippet with a timeout to simulate a NFC scan:
INTERPRETOUR.interlinkVideoPlayer = $('#interlink-video-player')[0];
// bind onended event to close the popup
$(INTERPRETOUR.interlinkVideoPlayer).on('ended', function() {
$('#interlink-video-popup').popup('close');
INTERPRETOUR.interlinkVideoPlayer = 'undefined';
$('#interlink-back-btn').trigger('click');
});
// play video
INTERPRETOUR.interlinkVideoPlayer.src = 'http://mydomain.ca' + this.model.get('video')[0].url;
INTERPRETOUR.interlinkVideoPlayer.play();
setTimeout(function() {
$.publish('item', '2479');
}, 5000);
The issue is that $('#interlink-back-btn').trigger('click'); invokes the backBtnHandler but pagehide is never triggered and so the dialog doesn't close.
Any help to resolve this issue would be much appreciated.

Instead of invoking a button using .trigger('click'), bind closing when popupafterclose event triggers.
Demo 1 / Demo 2
Static Popup
$('#popupID').on('popupafterclose', function () {
$('#dialogID').dialog('close');
});
Dynamically generated Popup
$(document).on('popupafterclose', '#popupID', function () {
$('#dialogID').dialog('close');
});

Related

Safari not firing touch events

I've got a small jsfiddle - http://jsfiddle.net/qhguktsn/5/. When you tap the text at the top of the link (iOS mobile Safari), you get only the mouse events- no touch events at all, not even on the body. If you tap it on the bottom of the text, you get touch events. We depend on touch events for handling 300ms delay.
How can we get touch events for tapping on the top of the text as well as the bottom?
HTML:
<div style="margin-left:200px;margin-top:200px">
<a style="vertical-align:center;height: 20px, width: 20px;font-size:100px" href="javascript: void 0">text</a>
</div>
JS:
jQuery("a").on("mousedown", function() { document.body.appendChild(document.createTextNode("mousedown ")); });
jQuery("a").on("mouseup", function() { document.body.appendChild(document.createTextNode("mouseup ")); });
jQuery("a").on("touchstart", function() { document.body.appendChild(document.createTextNode("touchstart ")); });
jQuery("a").on("touchend", function() { document.body.appendChild(document.createTextNode("touchend ")); });
jQuery("a").on("click", function() { document.body.appendChild(document.createTextNode("click ")); });
jQuery(document.body).on("touchstart", function() { document.body.appendChild(document.createTextNode("body touchstart ")); });
jQuery(document.body).on("touchend", function() { document.body.appendChild(document.createTextNode("body touchend ")); });
This is know bug in Mobile Safari. https://bugs.webkit.org/show_bug.cgi?id=105406
There is another one as well with adding node form different document. https://bugs.webkit.org/show_bug.cgi?id=135628
In order to fix them there are several ways.
The first one is to use a small library called fastclick, which supports many mobile devices and OS.
The second options is to add event.stopPropagation(); event.preventDefault(); like that. You need both of them.
jQuery("a").on("mousedown", function(event) {
event.stopPropagation();
event.preventDefault();
document.body.appendChild(document.createTextNode("mousedown "));
});
The third option is by using the viewport meta tag like that <meta name="viewport" content="width=device-width, user-scalable=no">. This will eliminate all touch delays, without any workarounds. But, again on Safari it may not act like in the other browsers, because hey Safari is the new IE
There is also touch-action, but it's not supported in most of the mobile browsers. :(
The touch events on the body are due to the body element being shifted down by the margin-top, putting an outline on the body element outlines the touch-target:
body { outline: 1px solid red; }
http://jsfiddle.net/qhguktsn/11/
The second part of the mystery seems to be that the click target expands outside the touch-target:
Touching the red outline will not trigger a touch event on the body element, but the click event seems to fire when tapped anywhere within the grey -webkit-tap-highlight-color region which expands outside the anchor itself. Taps at the very top will therefore trigger click events on the anchor, but not touch events on the body.
I found that the touch event is not fired when clicking on an element contained by a position:fixed element that extends beyond the window. I handled this by making the parent container shorter (used JS to get the exact window height).
This problem was in an app UIWebview using iOS 10. (Yes, still using UIWebview)

jQuery Mobile - preventDefault() on button (link)

I'm developing jQuery Mobile (jQm) app.
I wanna utilize taphold event to some crucial elements, such as remove button, to assure, that this element is secured from unwanted trigger.
I created Remove button on jQm popup and aded some JS to it, but I cannot force default action to quit, not with event.preventDefault() and event.stopImmediatePropagation(), nor with return false.
I prepared jsFiddle as duplicate of my code. The popup there contains simple progress bar as indicator of holded tap. You can try it here: jsFiddle (note: HTML5 data tag taphold="true" is not jQm default)
As a workaround, I'm currently replacing <a href="#" data-role="button"...></a> with <div>styled like button. This works well, since it doesn't have any default action, but I'm curious why the "proper" solution doesn't work?
$("a:jqmData(taphold='true')").bind("vmousedown vmouseup", function(event) {
event.preventDefault();
event.stopImmediatePropagation();
The event.preventDefault(); and event.stopImmediatePropagation(); used in the above piece of code, refer to the vmousedown and vmouseup events and not to every event which is bound to the selected element(s).
This means that the default behaviour for the click event still exists. So when you click the remove button, the click event is triggered and that's why the pop up closes immediately.
I hope this helps.

Using jQuery-mobile popup as context menu

I am using jQuery mobile popups as context menu fired on right click on desktops and taphold on mobile devices.
My problem: when I right click, the popup appears - it works fine. But when the popup is open and i right click outside of popup, the popup is closed and the standard browser context menu appears instead of new popup.
The popup create a new layer (its class is ".ui-popup-screen" ) under itself to catch events, but something like
$(".ui-popup-screen").on("click", function(event) {
event.preventDefault();
$('#myElementWithPopupContextMenu').contextmenu();
return false;
});
does not work.
Any ideas how to fix it?
i like to write like follow pattern.
// prevent default contextmenu and trigger as 'custom-contextmenu'
$(".ui-popup-screen")
.bind("contextmenu",function(e) {
e.preventDefault();
// create and show menu
$("#myElementWithPopupContextMenu").trigger( "custom-contextmenu" );
});
// context menu handler
$("#myElementWithPopupContextMenu").bind( "custom-contextmenu", function(e) {
// my context menu
}

MVC 4 jQuery modal dialog

Is there a way to get a jQuery modal dialog to be "truly" modal?
For example, if I create a confirmation dialog for a yes/no, how do I wait for the response from the user before processing anything else.
TIA
You have to place your logic for after the dialog into the dialog's button events. You can't use it to pause execution of a method mid stream. Only the native javascript alert/confirm boxes can do that.
$( ".selector" ).dialog({ buttons: [
{
text: "Ok",
click: function() {
// do whatever you want on OK.
}
}
] });
http://jqueryui.com/demos/dialog/

Prevent telerik window from Closing in onClose client event

I am trying to display a confirm dialog when a user tries to close a window by click the 'X' in the top right corner. If the user goes for 'OK' option, I would like to continue closing the window but if the user presses the 'Cancel' button I would like to prevent the window from closing. Is there a way to do that?
For Razor:
#(Html.Telerik().Window()
.Name("Window")
.ClientEvents(events =>
.OnClose("preventClose")))
<script type="text/javascript">
function preventClose(e)
{
var shouldClose = confirm("Are you sure you want to close?");
if (!shouldClose)
{
e.preventDefault();
}
}
</script>
Tested and working. Note that this function is called when they click on the X or if you call $("#Window").data("tWindow").close(); so unless you have some validation check like I demonstrated you won't be able to close the window. I don't see a way to distinguish between clicking on the X and calling $(window).close() manually.
I was able to figure out the solution to my problem on my own:
If you do e.preventDefualt(); in the onClose event it would prevent the window from closing. There is a mention in the documentation that the onClose event is cancellable but nowhere does it say how to cancel the onclose event.

Resources