Page becomes unresponsive after closing a modal - javascript

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.

Related

Bootstrap Modal and Jquery: [DOM] Found 2 elements with non-unique ids, however all IDs are unique

Okay so I use bootstrap 4, and I have two different modal types in a single page. I use Ajax to fill up the body of these modals. Both of these forms that each modal opens are different from each other but they have certain ID tags that are similar.
This is how I fire up my modals.
$('#modalForm').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
ajaxLoad(button.data('href'), 'modal_content');
});
$('#modalFormLG').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
ajaxLoad(button.data('href'), 'modal_content_lg');
});
The problem is when I open one modal, and then when I open the second one, I get the following error in the browser console.
[DOM] Found 2 elements with non-unique id #cashpaid: (More info: goo...)
However, I don't have any duplicates of IDs, it's just so that cashpaid ID is being used in both of those forms that each of these modals calls up into its body.
If I refresh the page and open the modal again, then I don't see this problem.
I have tried the following but it didn't have any effect on it
$("#myModal").on("hidden.bs.modal", function(event) {
$(this).removeData("bs.modal");
});
When I run the following two, then my modals becomes unresponsive for future use because they essentially delete that particular html data.
$("#myModal").on("hidden.bs.modal", function(event) {
$(this).empty();
});
AND
$("#myModal").on("hidden.bs.modal", function(event) {
$(this).remove();
});
After opening and submitting the first modal, in the browser console when I type, "cashpaid" for example, I see the following.
<input type="number" id="cashpaid" name="cashpaid" min="0">
However, when I open the second modal and submit that form and when I type "cashpaid" in the browser console, I see the following.
HTMLCollection(2) [input#cashpaid.valid, input#cashpaid, cashpaid: input#cashpaid.valid]
So is there any method for bootstrap 4 modals to purge the remote url form's data when it closes down?
Any help would be greatly appreciated. Thanks in advance.
$(document).on('hidden.bs.modal', '#modalForm', function (event) {
$('.modal-body', this).empty();
});
...will remove all child elements of #modalForm .modal-body after the closing modal animation ends.
Note 1: you only need to bind this once, not every time you open the modal.
Note 2: If you want this functionality on every modal (not only #modalForm), replace #modalForm with .modal. But keep in mind you can only do this with modals that get their contents generated upon reopening. A static modal will remain empty when reopened.

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.

opening jquery mobile popup on ajaxStart()

I want to show a revolving loader on ajaxStart. I've used a popup for this so that the background fades out and becomes inactive. That said, if there are other ways to achieve this (instead of using a popup), id be willing to try them out too.
The problem is, while the same function containing the AJAX call is executed on both page-load and a button click, the loader only shows up the first time - on page load. I put some console logs and verified that the ajaxStart and ajaxComplete do get triggered, but the pop-up fails to open when the AJAX call is made following the button click.
JavaScript :
$(document).ready(function(){
$( document ).ajaxStart(function() {
$("#loader").html("<img src='../images/ajax-loader.gif'/>").popup("open");
}).ajaxComplete(function() {
$("#loader").popup("close");
});
// do other stuff
loadData();
$("#button").click(function(){
loadData();
});
});
function loadData(){
//make an ajax call to fetch data
}
HTML:
<div data-role="popup" data-shadow="false" data-corners="false" class="loader1"
id="loader" data-overlay-theme="a" data-theme="none" data-dismissible="false" >
</div>
What could be the issue, or are there other solutions altogether to achieve the desired results?
First, the short answer: jQuery Mobile only supports one active popup at a time (for now). The documentation says:
Note: Chaining of popups not allowed
The framework does not currently
support chaining of popups so it's not possible to embed a link from
one popup to another popup. All links with a data-rel="popup" inside a
popup will not do anything at all.
I bumped against this issue a few times in the past and had to hack my way around it. The following code is the solution I'm currently using and works quite well so far (with jQuery Mobile 1.3.2):
$(document).on("mobileinit", function() {
$.widget("mobile.popup", $.mobile.popup, {
_trigger: function(type, event, data) {
return this._suspended ? undefined : this._super(type, event, data);
},
_openPrereqsComplete: function() {
this._super();
delete this._suspended;
},
open: function(options) {
var activePopup = $.mobile.popup.active;
if (activePopup) {
activePopup._suspended = true;
activePopup._close(true);
this.element.one("popupafterclose", function() {
activePopup.open();
});
}
this._super(options);
}
});
});
In a nutshell, that code extends the popup widget in-place to introduce a "suspended" state. All events are muted if a popup widget is in that state.
Then, the open() method is overloaded to detect if another popup is already active. If that's the case, it suspends and closes that popup (without performing any animation, so it is closed right away), then opens the new one and schedules the un-suspending and re-opening of the previous popup when the new one is closed.
Note that code binds to the mobileinit event, so it has to run after jQuery is included but before jQuery Mobile is included. Otherwise, it will be too late to extend the popup widgets that were instantiated during page initialization.

Closing jquery modal window conditionally from ASP.net code-behind

I have an ASP.net page with a link to open a jquery-based modal window (that uses colobox jquery plugin). The content of that window in loaded from another aspx file (it loads an iframe). I want to close that window when the user presses an asp:button and if some condition in my code-behind went well.
I tried many ways to close that window from code-behind like these ways:
Page.RegisterStartupScript("X", #"$(this).dialog('close');");
Page.RegisterStartupScript("X", #"var win = window.open('','_self'); win.close();");
btnDone.Attributes.Add("onclick", #"var win = window.open('','_self'); win.close();");
btnDone.Attributes.Add("onclick", #"window.open('../px/nsk.aspx', '_self', null); window.close(); ");
System.Web.HttpContext.Current.Response.Write("<SCRIPT LANGUAGE='JavaScript'>");
System.Web.HttpContext.Current.Response.Write("self.close();");
System.Web.HttpContext.Current.Response.Write("</SCRIPT>");
but non of them can close that modal window. I'm testing on latest version of firefox.
the code behind can be supposed as sth like this:
// do some database works
if (condition)
{
// close this modal window
}
I also tried methods from jquery but none of them were a success.
Can you please telling me how can I close this window?
The other answers given provide specifics; this 'answer' attempts to be more conceptual/consultative.
Closing the Window
Closing the colorbox window is done on the client side. Both #KennyZ and #Farshid provide details on how to do this. By default, ColorBox is going to close on the press of ESC or its EXIT ui element (if used.) It's also possible to close the box programmatically, which sounds like what you need to do.
Where is the Close Action Invoked?
#KennyZ proposes an Ajax call to determine if "some condition in my code-behind went well"; that presumes you cannot tolerate a full page refresh (which seems reasonable to me) but it's something for you to decide.
If the determination of "went well" can only be done on the server, then you're looking at Ajax or a full page refresh.
Alternatively, if there is a way to make the determination on the client side, you won't need to reach back to the back end at all. Just close the colorbox window using js.
If you can provide more details about what the action is that controls closing/not closing the ColorBox window, maybe the community can help even more.
The problem seams to be solved this way:
Page.ClientScript.RegisterStartupScript(GetType(),
"CloseKey", "parent.$.colorbox.close();", true);
Use jQuery dialog with a div instead of an iframe.
Then you can use an Ajax post to run the serverside code and look at the results to decide what to do with the dialog.
Declare the dialog:
$(document).ready(function () {
jQuery("#MyDialog").dialog(
{
bgiframe: true,
autoOpen: false,
modal: true,
width: 800,
position: ['center', 100]
}
);
});
Populate the dialog and open it:
$('#OpenMyDialog').click(function () {
$.post($('url_for_dialog_contents'), function (data) {
$("#MyDialog").empty();
$("#MyDialog").append(data);
}, null, "html");
$('#MyDialog').dialog('open');
return false;
});
Submit the dialog:
$('#SubmitMyDialog').click(function () {
$.post($('url_for_dialog_action'), function (data) {
if (data.success == true) { $('#MyDialog').dialog('close'); }
}, null, "json");
});
I'm sure you'll need a lot more code in the submit dialog, but this is the general idea.

jQuery Dialog not appearing when called

I am trying to get a modal loading dialog to pop up while I make an ajax call but it is not showing up in the onClick function. If I slow it down with firebug and step through the loading panel will show up. Is this just javascript running ahead of itself? Is there a better way to do this?
$(function(){
$("#loading_panel").dialog({
modal:true,
position:'center',
minHeight:40
});
$("a.view-in-frame").click(function(){
$("#loading_panel").dialog('open');
$("#tabs").hide();
var blog = $(document.createElement('div')).attr('id', 'blog').load(('blog_reader.php?blog='+this.href)), $("#loading_panel").dialog('close'));
$("#content_wrap").append(blog);
return false;
});
})
Just an idea, try setting the 'autoOpen' to false when creating the dialog:
$("#loading_panel").dialog({
modal:true,
position:'center',
minHeight:40,
autoOpen:false
});
At the moment you are telling the dialog to open when it is created. This should prevent that behaviour.
#ErsatzRyan
Have you tried set your javascript function to load after your document is ready?
Like this:
$(document).ready(function(){
//Your functions
});
And as #Nat Ryall said, you must set your autoOpen to false, otherwise your dialog won't open twice.
And another thing, try to call your $(".selector").dialog("open") after you done everything. You're telling your function to call your dialog before it has loaded it's content.

Categories

Resources