jQuery UI Dialog Will Not Close - asp.net-mvc

Given the following script:
$(function () {
$(".editLink").button();
$('#editPersonDialog').dialog({
autoOpen: false,
width: 800,
resizable: false,
title: 'Edit Person',
modal: true,
buttons: {
"Save": function () {
$("#update-message").html('');
$("#updatePersonForm").submit();
},
"Close": function () {
$(this).dialog('close');
}
},
close: function (event, ui) {
$(this).dialog('close');
}
});
$(".editLink").click(function () {
var dialogDiv = $('#editPersonDialog');
var linkObj = $(this);
var viewUrl = linkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
//validation
var $form = $("#updatePersonForm");
// unbind existing validation
$form.unbind();
$form.data("validator", null);
// check document for changes
$.validator.unobtrusive.parse(document);
// re-add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
// open dialog
dialogDiv.dialog('open');
});
return false;
});
});
function updateSuccess() {
if ($("#update-message").html() == "True") {
$('#editPersonDialog').dialog('close');
$("#commonMessage").html("Update Complete");
$("#commonMessage").delay(400).slideDown(400).delay(3000).slideUp(400);
}
else {
$("#update-message").show();
}
}
If I click the "X" button on the dialog the form closes fine. If I click the "Close" button then it does not close. I have verified that the code for the "Close" button is being called.
Both the "X" button and the "Close" button are both running the same statement: '$(this).dialog('close');'. Why would one work and the other not work?
As an aside the dialog will not open a second time unless I refresh the page. I imagine that these 2 problems may be related.
I have found many people with similar problems and a number of different solutions that worked for them. Unfortunately none of them worked for me.
Further Info:
The dialog displays a partial view in an Ajax form:
#using (Ajax.BeginForm("Edit", "Person", null,
new AjaxOptions
{
UpdateTargetId = "update-message",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updateSuccess"
},
new { #id = "updatePersonForm" }))
{
#Html.ValidationSummary(true)
<div id="update-message" class="hiddenDiv"></div>
<div class="blockGraygradient">
#Html.Partial("_CreateEditCommon")
#Html.HiddenFor(model => model.SelectedPerson.Id)
#Html.HiddenFor(model => model.SelectedPerson.RowVersion)
#Html.HiddenFor(model => model.SelectedPerson.CreateTime)
</div><p/>
}

Try using this instead.
$(this).dialog('destroy');
We had exactly the same problem. In the end, every time you re-opened the dialog it was actually re-injecting the dialog markup into the DOM. Then, when you click close (for the second time) it only closes the first occurrence of the dialog, but not necessarily the one that's open. You can check this using a run-time DOM inspector like FireBug or Chrome's built-in developer tools.

I found out that the cause of both problems (the close button not working and being unable to show the dialog more than once without refreshing the page) was that I had included references to my script files in both my main page and the partial view being displayed by the dialog. Once I removed the script references from the partial view the problems disappeared.
(As an aside this has now raised another problem to do with an Ajax update back onto the main page when the dialog is closed. I think this is the reason that I put the scripts into the partial view in the first place).

You have too much recursion. You don't need to subscribe to the close event of your jQuery dialog and invoke $(this).dialog('close'); inside it. Simply comment this line or remove completely the close event subscription:
$('#editPersonDialog').dialog({
autoOpen: false,
width: 800,
resizable: false,
title: 'Edit Person',
modal: true,
buttons: {
"Save": function () {
$("#update-message").html('');
$("#updatePersonForm").submit();
},
"Close": function () {
$(this).dialog('close');
}
}
});

Related

Open jQuery UI Dialogs One After Another

I have multiple jQuery UI dialogs that I would like to show one after another (one closes, the next in line opens). Currently, they all display modal, but one of the back ones is larger, and it looks bad/confusing in my opinion.
I would normally have the close functions of one dialog open the next, but these dialogs are called from separate functions, and they are kind of dynamic in the sense that not all of them are always displayed based on certain criteria.
I am contemplating a way to use $.Deferred, but am unsure if this would work as my understanding is it works more for things like AJAX calls.
Here is an (extremely) simplified example of how the code could be structured as-is.
<script>
function displayAlert1(){
$('<div/>', {text: 'Alert 1!'}).dialog({
modal: true,
autoOpen: true,
width: 400,
buttons: { OK: function(event, ui){ $(this).dialog('close'); } }
});
}
function displayAlert2(){
$('<div />', {text: 'Alert 2!'}).dialog({
modal: true,
autoOpen: true,
width: 200,
buttons: { OK: function(event, ui){ $(this).dialog('close'); } }
});
}
$(function(){
// These are actually met from data passed by AJAX
var condition1 = true;
var condition2 = true;
$('a').live('click', function(event, ui){
if(condition1) displayAlert1();
if(condition2) displayAlert2();
}
});
</script>
<!-- The links are actually dynamically produced from AJAX, thus the live() event handler -->
<a>Click Me!</a>
jsFiddle
My thinking is maybe I can have each alert function return a reference to the dialog element, or a $.Deferred object, but I'm not sure how to implement chaining from the main execution part (where the conditions are checked and the functions are called).
I would also like to make sure it chains to the next dialog no matter how the dialog before it is closed; whether by the X, by the 'close' method, or 'destroy' method.
Thank you for any input.
After thinking about the situation, I came up with the simplified method of using a stacked queue. I imagine I could have used the $.Deferred object, but it would be a little more complicated, and it essentially would be a stack in the end.
Below is my code. I basically initialized an array to use as my stack, and I will have each function push the dialog element into the stack. I bind into the close event of all future dialogs, and have it open the next one in the queue.
There are some obvious optimizations to do, but this is the barebones that works as I want.
function displayAlert1(){
return $('<div/>', {'class': 'alerts', text: 'Alert 1!'}).dialog({
modal: true,
autoOpen: false,
width: 400,
buttons: { OK: function(event, ui){ $(this).dialog('close'); } }
});
}
function displayAlert2(){
return $('<div/>', {'class': 'alerts', text: 'Alert 2!'}).dialog({
modal: true,
autoOpen: false,
width: 200,
buttons: { OK: function(event, ui){ $(this).dialog('close'); } }
});
}
$(function(){
// These are actually met from data passed by AJAX
condition1 = true;
condition2 = true;
// Dialog stack
dialogs = [];
$('a').live('click', function(event, ui){
if(condition1) dialogs.push(displayAlert1());
if(condition2) dialogs.push(displayAlert2());
// Grab the next dialog in queue
d = dialogs.shift();
// Check if it is valid, and open it
if(d && d.dialog){
d.dialog('open');
}
});
$('.alerts').live('dialogclose', function(event, ui){
// Grab the next dialog in queue
d = dialogs.shift();
// Check if it is valid, and open it
if(d && d.dialog){
d.dialog('open');
}
// Return false, or the close button (X) will glitch and re-create dialogs
return false;
});
});
jsFiddle
There are 2 things you can use to implement this:
1) have an identifier for each dialog ( you can add it as a 'id' attribute on the div)
2) listen to 'close' event on the dialog ( http://api.jqueryui.com/dialog/)
So, on the 'close' handler, you can check the current state, and based on that open/close the other dialogs.
Current State would be: which dialogs are currently open, and other params that you were using for condition1,condition2,etc.
http://jsbin.com/iwovob/1/

Update jquery ui dialog from another jquery ui dialog

I have a jquery dialog and from this one, i open another dialog, where user insert some data. How can I update this user data from the second dialog to the first one, without closing them?
Is this possible? Are some examples in the web?
Thanks in advance
ok so this is my script, which opens the second dialog. I open this dialog with a link, which calls a function in my mvc controller, and this returns the partial view with the datas...
<script type="text/javascript">
$(document).ready(function () {
$("#dialog2").dialog({
bgiframe: false,
autoOpen: false,
height: 200,
resizable: false,
modal: true,
buttons: {
OK: function () {
$("#dialog2 > form").submit();
$(this).dialog('close');
},
Abbrechen: function () {
$(this).dialog('close');
}
}
});
$('#changePW').click(function () {
$('#dialog1').dialog('open')
});
});
</script>
#Roysvork: then I have to but this in the buttons OK function?
As a dialog is simply an html element underneath, you can still access said element using jQuery in the usual fashion:
var dialog1 = $("#dialog1");
var dialog2 = $("#dialog2");
dialog1.dialog("show");
dialog2.dialog("show");
So in your event handler for dialog 1 you can just do :
var value = dialog2.find("#inputbox").val();
dialog2.find("#textbox").val(value) ;
etc...

jQuery UI dialogs: how to close dialog when click outside?

In docs I didn't see such information.
There are options to close dialog in such cases:
1) push Esc;
2) click on "OK" or "Close" buttons in the dialog.
But how to close dialog if click outside?
Thanks!
Here are 2 other solutions for non-modal dialogs:
If dialog is non-modal Method 1:
method 1: http://jsfiddle.net/jasonday/xpkFf/
// Close Pop-in If the user clicks anywhere else on the page
jQuery('body')
.bind(
'click',
function(e){
if(
jQuery('#dialog').dialog('isOpen')
&& !jQuery(e.target).is('.ui-dialog, a')
&& !jQuery(e.target).closest('.ui-dialog').length
){
jQuery('#dialog').dialog('close');
}
}
);
Non-Modal dialog Method 2:
http://jsfiddle.net/jasonday/eccKr/
$(function() {
$( "#dialog" ).dialog({
autoOpen: false,
minHeight: 100,
width: 342,
draggable: true,
resizable: false,
modal: false,
closeText: 'Close',
open: function() {
closedialog = 1;
$(document).bind('click', overlayclickclose);
},
focus: function() {
closedialog = 0;
},
close: function() {
$(document).unbind('click');
}
});
$('#linkID').click(function() {
$('#dialog').dialog('open');
closedialog = 0;
});
var closedialog;
function overlayclickclose() {
if (closedialog) {
$('#dialog').dialog('close');
}
//set to one because click on dialog box sets to zero
closedialog = 1;
}
});
I found solution on ryanjeffords.com:
<script type="text/javascript">
$(document).ready(function() {
$("#dialog").dialog();
$('.ui-widget-overlay').live("click",function(){
$("#dialog").dialog("close");
});
});
</script>
If dialog is modal, then paste these 3 lines of code in the open function when you create your dialog options:
open: function(event,ui) {
$('.ui-widget-overlay').bind('click', function(event,ui) {
$('#myModal').dialog('close');
});
}
Facing the same problem, I have created a small plugin that enables to close a dialog when clicking outside of it whether it a modal or non-modal dialog. It supports one or multiple dialogs on the same page.
More information on my website here: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside
The plugin is also on github: https://github.com/coheractio/jQuery-UI-Dialog-ClickOutside
Laurent
This is my solution.
I have, for example
<div id="dialog1">Some content in here</div>
<div id="dialog2">Different content in here</div>
<div id="dialog3">And so on...</div>
Each div gets opened as a dialog depending on what the user interacts with. So being able to close the currently active one, I do this.
// This closes the dialog when the user clicks outside of it.
$("body").on('click', '.ui-widget-overlay', function() {
if( $("div.ui-dialog").is(":visible") )
{
var openDialogId = $(".ui-dialog").find(".ui-dialog-content:visible").attr("id");
if ($("#"+openDialogId).dialog("isOpen"))
{
$("#"+openDialogId).dialog('close');
}
}
});

How would I reference a dynamically created jQuery dialog box so I can close it programatically?

When I began using jQuery a little over a year ago, I needed to load remote content into a pop-up dialog box. After scouring the internet and trying out several suggested methods for doing this, I came upon a function that worked exactly as I needed it to. However, one problem I've never solved is how to reference the dynamic dialog box so it can be closed from an outside function.
Here's the function that creates the dialog box, appends it to the body, and then loads a page into it:
function openDynamicDialog() {
var url = 'mypage.cfm';
var dialog = $('`<div style="display:hidden"></div>`').appendTo('body');
$(dialog).dialog({
autoOpen: true,
title: 'My Title',
resizable: true,
modal: true,
width: 250,
height: 100,
close: function(ev, ui) {
$(this).remove(); // ensures any form variables are reset.
},
buttons: {
"Close": function(){
$(this).dialog("close");
}
}
});
// load remote content
dialog.load(
url,
{},
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog();
}
);
//prevent the browser from following the link
return false; };
I've considered giving that hidden div a hard-coded id value, but I'm not sure if there are drawbacks to that approach.
Any suggestions would be most appreciated.
I would use a hard-coded id value for the <div> element.
No there shouldn't be any drawback giving it an ID. If you fear of some kind of conflicts then you can give it a class instead, or save a reference to the div object in a global variable.
Well im not sure what the return false is at the end. so if you don't need that, do this:
function openDynamicDialog() {
var url = 'mypage.cfm';
var dialog = $('<div>').css('display','none').appendTo('body');
$(dialog).dialog({
autoOpen: true,
title: 'My Title',
resizable: true,
modal: true,
width: 250,
height: 100,
close: function(ev, ui) {
$(this).remove(); // ensures any form variables are reset.
},
buttons: {
"Close": function() {
$(this).dialog("close");
}
}
});
// load remote content
dialog.load(
url, {}, function(responseText, textStatus, XMLHttpRequest) {
dialog.dialog();
});
return dialog;
}
//call it like this:
var dialog = openDynamicDialog();
//..code
//close it:
dialog.dialog('close');
OR
if you still need that return false, you can do this on the var dialog line of the function:
var dialog = $('<div>', {id: 'dialog_id'}).css('display','none').appendTo('body');
and then reference it from the outside:
var dialog = $('#dialog_id');

jQueryUI Modal open event & MVC.NET causing error ".dialog is not a function"

I hope someone can help as I'm at my wits end with this. What I'm trying to do is this.
"Draggable" Item is Dropped into a "Droppable" area (this works)
This posts the id of the item to my controller which returns the type of item it is (this works)
I pass the returned item name to a function which opens a modal and renders a partial view in the modal depending on the particular item.
The last bit is where the issue is. All the steps above work fine, the modal is popped and the partial view is rendered to the modal. But the button to close the dialog throws the error ".dialog is not a function" and after closing the modal using the 'x' in the corner subsequent attempts to open the modal will not work throwing a similar error.
Here's the example I'm working with to try get this working.
$(function () {
$('.draggable').draggable({ containment: '#imageboundry', revert: 'valid' });
$('#droppable').droppable({
drop: function (event, ui) {
$.ajax({
type: "POST",
url: '/Home/AddToCart/' + $(ui.draggable).attr("id"),
success: function (data) {
getItemType(data);
}
});
}
});
});
function getItemType(itemName) {
$('#dialogs').dialog({
open: function () {
$(this).load("AdditionalContent", { itemName: itemName }, function () {
alert("This happened");
});
},
modal: true,
resizable: false,
title: itemName,
width: 400,
autoOpen: false,
buttons: {
"Confirm": function () {
$(this).dialog('close');
}
}
});
}
This is my controller which returns the partial view to the modal
public PartialViewResult AdditionalContent(string itemName)
{
return PartialView("_" + itemName + "Attributes");
}
The close button works once I take out the open: function () { ... } bit and I can reopen the modal again and again but once I put this back in the error gets thrown. This is obviously the cause but cannot for the life of me figure out why.
Thanks in advance for your help and sorry for the very long post.
UPDATE:
I've attempted initializing the modal in document.ready and call it from my "drop" function in the first main function. From doing this I've narrowed it down to this line of code which loads the partial view from my controller. Without this line the functionality works. Any ideas on what is wrong with this.
$(this).load("AdditionalContent", { itemName: itemName }
I figured it out. Included in the partial views was a second call to the jQuery library which was added automatically when the view was created. Plus it was version 1.4.4 while I was using 1.5.1 straight from Google in the _Layout page. The second jQuery library was obviously breaking the functionality as there was a conflict between the two versions. It wasn't until I watched the FireBug console that I noticed the second loading of the 1.4.4 library.
Thanks to all for your help, feel like a bit of an idiot but lesson learned..... for now
could try this but i am not sure
$('#dialogs').dialog({
var self = this;
open: function () {
$(self).load("AdditionalContent", { itemName: itemName }, function () {
alert("This happened");
});
},

Resources