jQuery UI dialog not obeying position option on open - javascript

My code used to work, but I recently updated jQuery UI to 1.8 and jQuery to 1.4 because some things weren't working. Once I did that, those things started working, however, now I notice this one dialog is positioning itself top-center, instead of middle-center.
Let me explain the code a bit first. The code queries an Ajax request every x minutes to see the last time the session was hit. If it's been 10 minutes since they last hit their session, a jQuery UI dialog div appears, with a warning that their session is about to expire, and there is a button that lets you re-hit your session via a separate in-line Ajax GET request without reloading the whole page.
Here's the actual trouble. After 15 minutes or more, it's supposed to close the warning dialog (it checks if it's already open, which in this situation it 'likely is') and then creates a new dialog with an in-line login form that lets you re validate your log-in without reloading the page (and losing any unsaved, half-way filled out forms).
Here is the function that is supposed to close the warning, create the re-login div:
function renderReLogin() {
if ($("#logOutWarning").dialog("isOpen")) {
$("#logOutWarning").dialog("close"); // Close warning dialog as session has already expired
}
if ($("#logOutReLogin").dialog("isOpen") != true)
{
$('#noticeContainers').html('<div id="logOutReLogin" title="You\'ve been logged out!"><div id="logOutReLoginText"></div></div>');
}
$('#logOutReLoginText').html("This session has expired. In order to protect the integrity of you and your clients, we must limit sessions. To resume this session (and not lose any unsaved work) you must revalidate your credentials by logging in below.<br />" +
'<br /><div style="color:red;text-align:center;" id="loginFeedback"></div>'+
'<form id="reloginForm">'+
'<table width="40%" align="center"><tr><td>E-mail:</td>'+
'<td><input id="username" type="edit"></td></tr>'+
'<tr><td>Password</td>'+
'<td><input id="password" type="password"></td></tr>'+
'</table></form>'
);
$('#logOutReLogin').dialog(
{
width: '50%',
modal: true,
show: 'scale',
hide: 'scale',
draggable: false,
resizable: false,
position: 'center',
buttons: {
"Re-Login": function() { retryLogin(); },
}
}
);
}
Now like I said above, the warning opens fine, and then closes fine. But the re-login dialog snaps to the very top-center of the view-port, rather than the middle-center.
When I manually call $("#logOutReLogin").dialog("option", "position", "center" ); via Firebug in Firefox after it's already opened, it does go to where it should be. It just seems to be the open behavior within the function above.

After trial and error I believe I found the cause why it was not working. It seems that the hide animation on the warning dialog was conflicting with the show animation of the re-login dialog.
I moved around a lot of stuff and noticed the most desirable outcome after commenting out the animations settings, so I'm assuming that was it -- but it could have been a combination of things I changed while experimenting.
I am not sure if this is a known no-no to have things set up the way I did/do. But I suppose having animations for this isn't really needed as the likely reason they popup is the user is not looking at the tab.

Related

Show confirmation box depending on a hidden field value in Javascript

So a bit of background, I basically have a form where users can change stuff. This form is a bootstrap modal form. I want to display a warning or something when users close the form down if they have made changes to the form. So I thought I would add a hidden field and when things changes on the form (multiple ways this can happen) then I will mark the hidden field with a true value.
I have this working but now all that is left is to create something that will look at the hidden value then show a confirmation box to say something in the realm of "You have made changes and will loose all changes you have made. Would you like to continue?" with a yes, no or ok, cancel buttons.
I though this would be rather simple but for some reason I am struggling and I am not sure why.
My button is create like this
<asp:Button ID="btnX" runat="server" CssClass="close" Text="×" OnClientClick="return confirmClick();" />
I have a server onclick function done in vb.net/c# language is no issue for me I can always translate it like this
Public Sub btnX_Click(sender As Object, e As EventArgs) Handles btnX.Click
CloseModalForm()
End Sub
I also have javascript which would ideally call before the server code
function confirmClick() {
var _changed = document.getElementById('<%=hiddenField.ClientID %>').value;
if (_changed == true) {
alert(_changed);
}
}
However this does not work, I know this is an alert box, I ended up changing it to an alert while trying to get this to work and seeing if i could get a popup message to say true when hidden field is true and for it not to appear when the hidden field is false. I have messed around a lot on this hence why i ended up with alert. But nothing seems to work if i try just
if (alert(_changed)) {
alert(_changed);
}
Then it shows the alert box regardless if the value is a true or false
This seems very simple to me, but I cannot get it to work, which must mean I am missing something which I have not thought about. I have googled how to do if statements with Booleans in case I got that wrong but I cannot see anything wrong in what I am doing. The only other thing is maybe I have completely negated something or miss interpreted the way JS works. Ideally this would be client side rather than server side as this is just a case of asking users if they want to continue. I still need the server side procedure as many more things happen while the modal form closes down.
Any help will be much appreciated.
Ok, first, I assume you have some kind of dialog system you are using. You can try to use bootstrap ones, but they look fantatic, but the markup and really easy way to pop such a dialog with code beyond sucks. So, I suggest using jQuery.UI dialogs. (only issue with jQuery.UI dialogs is the don't look all that great. But, for this example, that's what we going to use.
next up:
We all know that when you drop in a server side button, you can can ALSO add that client side click, and if the routine returns true, then server side click code behind will run. if the js routine returns false, then the server side click button code does not run. This is rather clear, and even your posted code shows this knowledge.
so, for super quick and dirty, and in a hurry, we can, and often do this:
<asp:Button id="cmdDelete2" runat="server" class="btn myshadow" style="margin-left:15px"
type="button"
onclick="cmdDelete_ServerClick"
onclientclick="return confirm('Really delete?')" >
</asp:Button>
Of course for above, we get/see the web browser dialog, and those look REALLY poor!
but, it does work. And thus you get this:
(I am editing a single record in a popup dialog in above)
So, the above use of js confirm() will work. But as you can see, the position and how ugly that dialog box is? Well, its just ugly.
so, we can adopt jQuery.UI dialog. They are much better looking. Of course there are bootstrap ones, and I see quite a few people using sweetAlert (very very nice).
Anyway, ONE BIG HUGE issue with all of these so called "dialog" libraries that look great, function great, and even allow you to set the position of the dialog?
Well, first lets change above to use a jQuery.UI dialog (and I show how in a bit).
So, that rather ugly built in browser dialog now becomes this:
The above is now much nicer. And even better is when you click on that button, the dialog pops RIGHT below and to the right of the dialog.(where you eyes are current looking since you just looked to click on that button!
You can try the above and play with a working demo here:
(it is vb.net + web forms).
Ok, so the next issue to tackle?
All of the current JavaScript (js) frameworks operation on NON BLOCKING code! That means that while confirm() does halt the code, does wait, and then continue when you hit ok (or cancel)? Such blocking code, or halt js code is not allowed anymore. About the only exception is alert() and confirm(). But, they can lock up and freeze the browser code, so they are not recommended anymore.
So, all such 3rd party - and even in the future? Non blocking code is to be used. That means the code is asynchronous.
so, if we call code to pop a dialog? The function will run, display the dialog AND THEN RETURN and EXIT!!!!
but now, that means we can't wait to return the true/false value to the button click (client side).
But, you can use a neat-o little trick!!!
You now (have to) do this:
You run the client side code - return false (server side button click does not run). then when the user makes their choice in the pop dialog, you then set a flag to return true and CLICK the button again!!! This time, the client side routine fires again, but returns true (assuming you hit ok!!!).
So, the code will look like this:
The button looks like this:
<button id="cmdDelete" runat="server" class="btn myshadow" style="margin-left:15px"
type="button"
onserverclick="cmdDelete_ServerClick"
onclick="if (!MyConfirmDel(this)) {return false};" >
<span aria-hidden="true" class="glyphicon glyphicon-trash"> Delete</span>
</button>
Note in above, I did not use a asp:Button, since I wanted the fancy looking bootstrap icon in the button (trash). But, how this works for a button, or asp.net button is the same. But I had to change the comfirm routine a bit, and use the above !MyConfirmDel(this) (the button combines both onclick and onserverclick - and they actually run as one js routine - we can't change that. If you using plain jane asp.net button, then the first markup will work the same.
and the js code now looks like this:
var MyConfirmDelOK = false
function MyConfirmDel(Btn) {
if (MyConfirmDelOK) {
MyConfirmDelOK = false
return true
}
var myDialog = $("#mydelpop");
myDialog.dialog({
title: "Delete Hotel",
width: "26em",
modal: true,
dialogClass: 'ui-widget-shadow',
position: { my: "left top", at: "right bottom", of: Btn },
buttons: {
Delete: function () {
myDialog.dialog('close')
MyConfirmDelOK= true
$(Btn).click()
},
cancel: function () {
myDialog.dialog('close')
}
}
});
Note careful in above. We passed the button, pop the dialog. User makes choice from dialog, and if ok/yes clicked, we set flag = true, and THEN click the button again. The button click runs the client side code again, but this time, it returns true, and thus the server side click code will now run.
If you are using a plain jane asp.net, then this:
<asp:Button id="cmdDelete2" runat="server" class="btn myshadow" style="margin-left:15px"
type="button"
onclick="cmdDelete_ServerClick"
OnClientClick="return MyConfirmDel(this)" >
</asp:Button>
You can try and play with a working demo here for above:
http://www.kallal.ca/WebSite11/WebForm2
Your next idea?
I want to "confirm" or "warn" or have some dialog if they actually changed things?
Don't!!! - just don't!!! If you do that, then EVERY place where you have edits, then for the sake of a consistant UI experiance, then you have to do that.
And it just becomes a "nag" for the users. (and you going to have to write quite a bit of extra client side code to make this work). When you pop a dialog, give them a save button, and a cancel button. Users will then make a habit of hitting the cancel button to go back. They will not care if they accident edit, since they can learn to always hit cancel if they did not mean to edit.
(you can see this UI in action in the above link).
You can have such a confirm dialog - but the less dialogs, the more enjoyable the software becomes. Give the users a cancel or un-do button. Let them decide if they want to bail out - not nag them all day long.

Truly Refresh/Reload a jQuery mobile page div

I'm currently working with a file that contains several jQM page divs (single page approach).
I have a refresh button in the header of these pages that I'm trying to get to refresh individual page divs based on "getActivePage". The reason for this interactivity is there is a running list of items that users will be needing to refresh to see new content coming in to listview(s).
I've had various visual refreshes altering the following function, but none seem to totally refresh the DOM or the contents of a desired pagecontainer or jQM page div. With the following code, I'm able to see a visual transition and I arrive at the desired/same jQM page div that I'm trying to refresh. The problem is, the contents aren't really being reloaded it seems. (I have a way in the test environment of changing the listviews to test the refreshes and I'm not seeing those changes take effect) I'm wondering if I'm not passing in "id_urlNav" properly or if this is even possible with .pagecontainer("change"...).
When all was lost, I ended up inserting window.location.reload();, but this seems to be bad form for pagecontainer manipulation. If anyone has any idea why this isn't working, please let me know. Thanks in advance for reviewing!
// script to reload/refresh jQM pages
// scoped to internal page hashes vs. overall window
// "change" is used vs. "load" for internal reloads vs. AJAX content
function refreshPages() {
// the camel casing on the first part of the pageContainer object below
// is important
var id_url = $.mobile.pageContainer.pagecontainer("getActivePage")[0].id;
var id_urlNav = "#" + id_url;
console.log("id_urlNav" + " =" + " " + id_urlNav );
// window.location.reload();
// keeping the below in case 1.5 finally arives with proven solution
$.mobile.pageContainer.pagecontainer( "change", id_urlNav,
{
allowSamePageTransition : true,
showLoadMsg : true,
// reloadPage reloads entire jQM set of pages, forgetting the getActivePage
// reloadPage is deprecated
// reload "reloads" the getActivePage, but doesn't show new content
reload : true,
transition : 'fade',
changeHash : 'true'
}
);
}
// /refresh code
I read some on the jQuery forums about there being a bug related to reload: vs. the now deprecated reloadPage:, but I don't know if that is some of the cause of the malfunction or not.

jquery dirty record, would like the jquery ui modal

I'm using this to test if a form is dirty.
It defaults to the standard browser confirmation asking if you are sure you want to navigate away from this page. On the jquery dirtyforms site it has a section that says you can use the jquery ui modal form.
So I tried adding a section (a div) like so:
<div id="unsavedChanges" title="Save Changes?">
<p>You've made changes to this page. Do you want to leave this page without saving?</p>
</div>
And then I added what their code looked like:
$.DirtyForms.dialog = {
selector: '#unsavedChanges',
fire: function(message, dlgTitle) {
$('#unsavedChanges').dialog({ title: dlgTitle, width: 350, modal: true });
$('#unsavedChanges').html(message);
},
bind: function() {
$('#unsavedChanges').dialog('option', 'buttons',
[
{
text: "Stay Here",
click: function(e) {
$.DirtyForms.choiceContinue = false;
$(this).dialog('close');
}
},
{
text: "Leave This Page",
click: function(e) {
$.DirtyForms.choiceContinue = true;
$(this).dialog('close');
}
}
]
).bind('dialogclose', function(e) {
// Execute the choice after the modal dialog closes
$.DirtyForms.choiceCommit(e);
});
},
refire: function(content) {
return false;
},
stash: function() {
return false;
}
};
Although I am not sure where they want me to place that (I originally placed it outside of document.ready. However, after running this and making a change to my form and navigating away I see that it still is using the browser confirmation instead of jquery ui dialog box. What am I doing wrong here?
You can only popup a custom dialog if the user is trying to leave by clicking an anchor or other element on your page.
Then you could just intercept the click on all anchors etc, prevent it, pop up a custom dialog to confirm. In other words, when someone is clicking an element on your page, you're in control and can do pretty much whatever you want.
However, when the user is trying to leave by closing the tab or browser, you can not stop them with javascript, as it would be extraordinary annoying if websites could do that.
The only way to prompt a user that is leaving by closing the tab/browser window is to use the onbeforeunload event, and that event can only be used with the native confirm dialog, there is no way to use a custom dialog or stop the user or do anything else really, as that could lead to certain websites creating systems where you could never really leave the site.
From the README:
Dirty Forms will alert a user when they attempt to leave a page without submitting a form they have entered data into. It alerts them in a modal popup box, and also falls back to the browser's default onBeforeUnload handler for events outside the scope of the document such as, but not limited to, page refreshes and browser navigation buttons.
(emphasis mine)
If you want to show a modal for this kind of things, well, you simply can't. (The reason why is security: it's easy to imagine a page preventing the user to close it whatever they attempt, short of killing the browser instance.)
Additionally, the "but not limited to" bit is intriguing: I would ask the plugin's author for details on what exactly this covers, as it might overlap with your use-case.

Page becomes unresponsive after closing a modal

I am creating a system for hotel management that manages guests and checkins.
I am having trouble with the response time of my modals.
I have a cancel button inside the modal which closes the modal BUT DOESN'T reload the page. Here's what I got in the cancel button:
$("#cancel").click(function(event) {
event.preventDefault();
jQuery(".ui-dialog").dialog().dialog('close');
jQuery(".ui-widget-overlay").dialog().dialog('close');
});
Here's the problem:
When the modal appears (by clicking another button), I click cancel and the code above is to be executed. I did this numerous times (Open modal and cancel) and the page became unresponsive. You have to wait minutes before it closes the modal after doing it for over 5 times. You can't even close the tab of the browser.
Any ideas would be very much welcome. Thank you.
PS.
I uploaded the system to the web for you to see.
http://greenenergiesllc.com/temp
Login: joel
Password: 1234
PHP file that creates some of my modals: https://www.dropbox.com/s/azi51w0pzp69kgh/checkin.php
Code snippet on how I create a modal:
jQuery( "#ex4").dialog({
height: 'auto',
width: 450,
modal: true,
closeOnEscape: false,
open: function(event, ui) {
jQuery(this).parent().children().children('.ui-dialog-titlebar-close').hide();
}, position: ["center", 100],
resizable: false
});
EDIT:
This is what I've done so far. I solved the DOM problem of creating too many objects by adding .remove after the close call.
$("#cancel").click(function(event) {
event.preventDefault();
jQuery(".ui-dialog").dialog().dialog('close').remove();
jQuery(".ui-widget-overlay").dialog().dialog('close').remove;
});
However, after closing the modal for the first time, it won't open for the second time and I got this error.
--> UPDATE: Using remove won't bring the modal back when called. I am completely confused now what to do. I need to remove those DOM elements when called by using .remove() but I need to bring them back when called.
Uncaught TypeError: Cannot call method '_focusTabbable' of undefined
Dont need to use like that way. Try
$(".ui-dialog").dialog( "close" );
$("#cancel").click(function(event) {
event.preventDefault();
$(".ui-dialog").dialog( "close" );
$(".ui-widget-overlay").dialog('close');
});
It's not appear to be a problem with the close function.
When you click on link, the modal appears. In this moment, you create one modal in the DOM. See:
If you click many times, you have created many others modals in the DOM. See:
The problem is in your function that trigger this modal. With many HTML in your DOM, more slower the "close" function will be.

Twice refreshed in p:commandButton, race condtition with oncomplete

I'm executing the server action with p:commandButton. After those action is completed, I'm refreshing the form (to show hidden fields) and I show dialog. I've tried also to refresh only the panels with hidden buttons, but the effect was the same:
There is second refresh launched, after I call dialog.show(). The problem is, that the widgets defined inside the dialog and the dialog itself is not existing in the moment! So, when my JavaScript code runs too fast, before the post with update of the dialog finishes, I'm getting an exception, because the object I want to modify doesn't exist in DOM tree.
So my first question, is it possible to avoid such situation and second refresh, can't the dialog be refreshed along with page?
And second, if the first can't be answered, how can I launch my code after those second post finishes? I need simply a callback when refreshing of the dialog component will be completed, and than run my operations.
<p:commandButton id="doTask" value="Do task" widgetVar="doTaskButton"
action="#{service.doTask}" update="#form"
onclick="disableMainButtons()"
oncomplete="async.showAsyncDialog()" />
The HTTP sequence:
// button click
POST http://localhost:9080/myapp/order.xhtml 200 OK
// oncomplete launches dialog.show()
// I receive answer from COMET before the dialog to display it is shown
POST http://localhost:9080/myapp/channel/async 200 OK
// refresh triggered by dialog.show(), only now the dialog is shown and it's widgets are rendered
POST http://localhost:9080/myapp/order.xhtml 200 OK
The workaround, that isn't beautiful from programming point of view is to check if the dialog is rendered and if not, delay my procedure. In case the dialog is still not rendered, delay once again etc.
waitForDialogRendered: function() {
var visible = asyncDialog.jq.css('visibility') == 'visible';
if (!visible) {
setTimeout(waitForDialogRendered, 250);
return;
}
runComet();
}
Not that asyncDialog.jq.is(':visible') returns true even if dialog is not visible for user!
Still, I'd be happier without the need to write such code.

Categories

Resources