jQuery draggable does not work on elements added via ajax call - jquery-ui

I have a list of objects that I am up updating through a dialog. When the user clicks the refresh button it reloads the updated list and appends the same table with the list. However, when I reload the updated list, the draggable function for jQuery UI stops working. I have tried inserting a the $('draggable').draggable line inside the ajax success handler and after the ajax call occurs, and neither worked. I also have a jquyer live event handler for the draggable containers that did not work for when the list was refreshed.
Below is my code for initially loading the list, the live function for draggable containers and the function for when the user clicks the refresh button. In my code below I also tried to add the ui-draggable class to the objects and that did not work:
$.ajax({
async: false,
type: 'POST',
url: 'collection.php',
success: function(data) {
$("#collection").append(data);
}
});
$("#refresh_collection").click(function(){
$("#collection").html("");
$.ajax({
async: false,
type: 'POST',
url: 'collection.php',
success: function(data) {
$("#collection").append(data);
$('.draggable_container:not(.ui-draggable)').live("mouseover", function(){
$(".draggable_container").addClass("ui-draggable");
});
}
});
});
$('.draggable_container').live('mouseover',function(){
$(this).draggable({
cursor: "move",
cursorAt: { top: -5, left: -5 },
stop: function(){}
})
});
I was able to get the draggables to work using the on function rather than live, but now I realized that they do not work after I open a jquery UI dialog, close it and then click the refresh button. If I just click the refresh button without opening the dialog first, then everything works fine. However, the draggable turns off if I open the dialog, close it and then click the refresh button, but it does work if I just open the dialog and close it without pressing the refresh button. Any ideas on how to fix this? Will destroying the draggable and then reinitializing it when I close the dialog sound like the solution?
I ultimately want to have the ajax call happen when the dialog closes like this, but this code still was not working. Any help would be greatly appreaciated.
var $dialog = $("#upload_dialog").dialog({
autoOpen: false,
height: 375,
width: 500,
modal: false,
open: function() {
$("body").draggable("destroy");
$tab_title_input.focus();
},
close: function() {
$.ajax({
async: false,
type: 'POST',
url: 'collection.php',
success: function(data) {
$("#collection").html(data);
$("body").on("mouseover", ".draggable_container", function(){
$(".object_container").draggable({
cursor: "move",
cursorAt: { top: -5, left: -5 },
stop: function(){}
})
});
}
});
}
});

Remove the first .live call and change the second .live call to the following:
$('body').on('mouseover', '.draggable_container',
function(){
$(this).draggable({ cursor: "move", cursorAt: { top: -5, left: -5 }, stop: function(){} });
});

Related

Error: cannot call methods on dialog prior to initialization; attempted to call method 'open'

Just a little preface... I am fairly new to jQuery so if something looks wrong or redundant please feel free to offer any helpful suggestions.
Now for the issue. I have 2 modals that are initiated from 2 separate links on the page.
The first modal was fairly problem free. It is a simple form that posts back to the same page. If you are wondering what the items in the "close:" section are, they are form fields that I want to clear the values on when the dialog is closed.
Once I added the second one I have had problems. This modal calls a coldfusion page into a modal to display pictures. The problems occur after opening up the second one. I can not close the second modal from the "close" button. I get the following error.
Error: cannot call methods on dialog prior to initialization; attempted to call method 'close'
I have to close it from the "x" in the upper right hand corner of the modal. After I close it, I get an error when trying to open up the first on.
Error: cannot call methods on dialog prior to initialization; attempted to call method 'open'
Here is the code for it.
$(document).ready(function() {
$(".dig").click(function() {
//based on which we click, get the current values
var cItemName = $("#checklistItemName").attr( "title");
var c2id = $("#check2id").attr( "title");
$("#ItemName").html(cItemName);
$("#ItemID").html(c2id);
$("#objCheckItemName").val(cItemName);
$("#objCheck2ID").val(c2id);
console.log(cItemName);
console.log(c2id);
});
$( "#image-form" ).dialog({
autoOpen: false,
height: 450,
width: 650,
modal: true,
buttons: {
"Submit": function() {
$('#mForm').submit();
return true;
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
close: function() {
$('#defaultSectionName')
.val('');
$('#defaultSectionDesc_hidden')
.val('');
$('#Photo')
.val('');
$('#objCheck2ID')
.val('');
$('#Check21')
.val('');
},
zIndex: 500
});
The next piece of code is where I believe the problems are occurring.
$( "#image_trigger" )
.click(function() {
$( "#image-form" ).dialog( "open" );
});
var dlg=$('#register').dialog({
title: 'Case Pictures',
resizable: true,
autoOpen:false,
modal: true,
hide: 'fade',
width:650,
height:450,
buttons: {
close: function() {
$( this ).dialog( "close" );
}
},
zIndex: 500
});
$('#reg_link').click(function(e) {
e.preventDefault();
var linkurl=('assets/includes/modalPictures.cfm' + '?'
+ 'id=' + $("#objCheck2ID").val()
);
dlg.load(linkurl, function(){
dlg.dialog('open');
});
});
jQuery UI: 1.10.1
jQuery: 1.9.1
Server Side: Coldfusion
The HTML is pretty extensive. If you need to see any part of it please let me know. Thanks for your help!
Upper case?
Close: function() {
You have to initialize your jquery dialog before calling the open function.
<script type="text/javascript">
$(document).ready(function () {
initializeDialog();
});
</script>
And change your js file to have the dialog code in initializeDialog() function.
function initializeDialog(){
$("#your-dialog-id").dialog({
autoOpen: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
}
},
modal: true,
resizable: false,
width: 600px,
height: 400px
});
}
Thanks #bpjoshi

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/

jquery ui dialog not vertically centered after load

I using jquery ui dialog with dynamic height. When it opens it’s centered, but when it loads the content it’s expanding toward the bottom of the page.
Here is my function:
$(this.document).ready(function () {
$(".openDialog").live("click", function (e) {
e.preventDefault();
$("<div></div>")
.addClass("dialog")
.attr("id", $(this)
.attr("dialog-id"))
.dialog({
autoOpen: false,
title: $(this).attr("dialog-title"),
close: function () { $(this).remove() },
modal: true,
width: $(this).attr("dialog-width"),
heith: 'auto',
resizable: false,
draggable: false,
show: 'scale',
hide: 'puff',
position: ['center', 'middle']
})
.load(this.href).dialog("open");
});
$(".close").live("click", function (e) {
e.preventDefault();
$(this).closest(".dialog").dialog("close");
});
});
I was able to fix this by setting autoOpen:false and creating the dialog content with my ajax call in the create method. Once that returned, and the content created, I called open on the dialog. Works great!
Above ans not work for me.
$(document).live("ajaxStop", function (e) {
$("#myDiagDiv").dialog("option", "position", "center");
});

reopen jquery ui dialog, empty and refresh

This jquery ui dialog is filled with html and form values from an ajax call (works). I want to close or submit it and then reopen and reuse it just the same. I can close and reopen fine but it has the old values still there and then the new ones are added. It keeps adding the html values after each close and reopen. There are many questions about this on SO but I don't see a clear answer. I have tried close, empty, destroy but the combination isn't working the way I need it. Any ideas?
$("#StoreForm").dialog({
autoOpen:false,
width:500,
height:900,
modal:true,
buttons: {
OK: function() {
$('#StoreForm').dialog('close');
$(this).dialog('hide');
$(this).dialog('empty');
},
'Save': function() {
$(this).dialog('empty');
}
}
});
//additional code to click and open the dialog
$(".sel").unbind('click');
$(".sel").on("click", function(e){
e.preventDefault();
$("#StoreForm").dialog('open');
var valueSelected = $(this).closest('tr').children('td.item').text();
$.ajax({
url: 'query/categories.cfc',
dataType: 'json',
cache: false,
data: {method: 'getProductInfo',
queryFormat: 'column',
returnFormat: 'JSON',
productID: valueSelected
},
success: function(response, status, options){
$("#PROD_SUPER_ID").val(response.DATA.PROD_SUPER_ID[0]);
$("#color").val(response.DATA.COLOR_ATTRIB);
$("#SIZE_ATTRIB").val(response.DATA.SIZE_ATTRIB);
$("#price").val(response.DATA.PRICE);
var w = [];
w.push("<p>", response.DATA.ICON[0], "</p>", "<p>",
response.DATA.FULL_DESCRIPTION [0], "</p>")
$("#StoreForm").prepend(w.join(""));
What I found was you can close the dialog and empty the html and it will clear this type of dialog set-up. For reopening I nested the 2nd ajax call in the success response of the initial one..
//set up dialog with options
$("#StoreForm").dialog({
autoOpen: false,
width: 500,
height: 500,
modal: true,
buttons: {
Cancel: function(){
$('#StoreForm').dialog('close');
$('#StoreForm').html("");
},
//pop-up individual items
"Add to Cart": function(){
$.ajax({
url: $("#storeCart").attr('action'),
data: $("#storeCart").serializeArray(),
type: 'POST',
success: function(response){
var name = $( "#name" ),
email = $( "#email" ),
password = $( "#password" ),
allFields = $( [] ).add( name ).add( email ).add( password ),
tips = $( ".validateTips" );
if you have any questions please respond. Thanks

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');

Resources