Using ASP.NET MVC 4, jQuery 1.6.2, jQuery UI 1.8.11. Currently debugging in Firefox 16.0.2.
I am trying to make this thing work so I have a reusable jQuery UI modal dialog with autoOpen: false which gets opened from the main page. So far so good. That reusable jQuery UI dialog will open a new modal dialog which is later destroyed and created again whenever needed (I tried to make the other one reusable too but I failed, it kept appearing as a div on the first dialog, not as a new separate dialog as it should so eventually I decided to create it every time I need it).
When I first open the first dialog, I can open and close the second dialog without problems. However the problem occurs when I close the first dialog and open it again. It behaves as it has as many dialog placeholder divs as the number of times I have opened the first dialog. Although I am pretty sure I destroy the second dialog AND remove the placeholder div every time I close it.
I have put the dialog code into the /Views/Shared/_Layout.cshtml file and that layout file is referenced by the main page. For those who are not familiar with ASP.NET MVC, the layout file is a shared file which contains header, footer and other html elements which define the layout of the web page, so that you can reference it from any View in your web site. So the layout is infact rendered along with any View which references that layout.
Here is the (pseudo) code in my layout file:
<html>
<head>
<script type="text/javascript">
$.ajaxSetup({ cache: false });
$(document).ready(function () {
$("#veliki").dialog({
close: function () {
$("#veliki").html("");
$("#maleni").dialog("destroy");
$("body").find("#maleni").remove(); /* a desperate attempt to remove ALL divs which hold the 2nd dialog, was just: $("#maleni").remove(); */
},
modal: true,
height: 600,
width: 800,
left: 0,
autoOpen: false
});
$(".openDialog").live("click", function (e) {
e.preventDefault();
$("#veliki").load($(this).attr('data-url'));
$("#veliki").dialog("open");
});
});
</script>
</head>
<body>
<div id="veliki"></div>
#RenderBody(); <!-- The ASP.NET MVC view gets rendered here -->
</body>
</html>
The code related to the second dialog is placed in one of the views which reference another layout (the layout which does not contain any jQuery code). The code in that View looks like this:
<script type="text/javascript">
$(document).ready(function () {
$(".openSubDialog").live("click", function (e) {
e.preventDefault();
$('<div id="maleni"></div>')
.appendTo("body")
.dialog({
close: function () {
$("#maleni").dialog("destroy");
$("#maleni").remove();
$("body").find("#maleni").remove(); /* delete them all. but where did "they" appear from?! */
},
modal: true,
height: 450,
width: 600,
left: 0
})
.load($(this).attr('data-url'));
});
});
</script>
To sum it up:
I open the #veliki dialog by clicking a link in the main page.
I create and open the #maleni dialog by clicking a link in the first dialog.
I close the #maleni dialog, destroying it and removing the #maleni div.
I close the #veliki dialog.
I open #veliki dialog by clicking another link in the main page.
I create and open the #maleni dialog which magically appears two times now (as seen in FireBug).
I slam the wall with my head which doesn't solve anything.
Anyone with an idea?
Why don't you use already existing window but with varying content? I have created a fiddle with this functionality : http://jsfiddle.net/scaillerie/wEX42/ .
The main point is that you don't have to handle the close event of your #maleni window : you only close it with $("#maleni").dialog("close"); and when you again need it, you re-open it : $("#maleni").dialog("open");.
An example of implementation in your case can be the following :
Layout page :
<html>
<head>
<script type="text/javascript">
$.ajaxSetup({ cache: false });
$(document).ready(function () {
$("#veliki").dialog({
close: function () {
$("#maleni").dialog("close");
},
modal: true,
height: 600,
width: 800,
left: 0,
autoOpen: false
});
$("body").delegate(".openDialog", "click", function (e) {
$("#veliki").dialog("open").load($(this).attr('data-url'));
});
$("#veliki").delegate(".openSubDialog", "click", function (e) {
$("#maleni").dialog("open").load($(this).attr('data-url'));
});
});
</script>
</head>
<body>
<div id="veliki"></div>
#RenderBody(); <!-- The ASP.NET MVC view gets rendered here -->
</body>
</html>
Sub-page :
<div id="maleni"></div>
<script type="text/javascript">
$(document).ready(function () {
$("#maleni").dialog({
modal: true,
height: 450,
width: 600,
left: 0,
autoOpen: false
})
.load($(this).attr('data-url'));
});
});
</script>
Related
I have the following code that I call on page load:
$('#postcodes-link').fancybox({
type: 'ajax',
minWidth: 800,
minHeight: 400,
afterShow: function () {
$('table.data-table > tbody > tr').on('click', function () {
$.fancybox.close();
});
}
});
Now this works fine to open the fancybox (fiddle example), but when I click on the row, it doesn't close the fancybox and just throws the following error:
Uncaught TypeError: Cannot read property 'close' of undefined
yet if I make the above into a jQuery function:
(function ($) {
$.fn.setUp = function () {
return $(this).each(function () {
$(this).fancybox({
type: 'ajax',
minWidth: 800,
minHeight: 400,
afterShow: function () {
$('table.data-table > tbody > tr').on('click', function () {
$.fancybox.close();
});
}
});
});
};
})(jQuery);
and call the following in the same place as I called the top code
$('#postcodes-link').setUp();
The fancybox will now close (fiddle example). My question is why does the first one not work whereas the second one does, and how can I make the first one work? I figure it is something to do with the scope of fancybox but then I would have expected the second one not to work as it is wrapped inside a further function
Please note I have tried various version of trying to close the fancybox:
$.fn.fancybox.close()
jQuery.fancybox.close()
parent.$.fn.fancybox.close()
$('.fancybox-close').trigger('click') //tried this one as a dirty hack but didn't work either
Ok, so I found out what the problem was when trying to get the fiddle to replicate the error:
On the table page, I was using the jQuery data-table plugin so I included all the scripts need to load that. As I was ajax loading the page into the modal, it meant jQuery was being loaded for a second time on the current page. This caused the error I was seeing.
Removing the jquery script made the fancybox work as I wanted or another workaround (if you want the target page to still work if it is not opened in a modal - eg if you have other links to that page) then you will have to use a fancybox iframe instead of the fancybox ajax modal
I'm using the AlloyUI modal "Real World Example" directly from their website at: http://alloyui.com/examples/modal/real-world/
Using the example verbatim and changing the following line from:
visible: true,
to
visible: false,
So that the modal appears only after clicking the button instead of when the page loads, as one would expect a dialog box to do. When I click the button to "show modal" the modal loads however the body of the dialog doesn't fill it's space properly, and the toolbar is mashed up against it. Upon resize everything jumps back into place nicely.
I'm looking for a clean fix, so far I figure a hacky fix might be to load the modal with a zIndex that puts it behind the page body, and alter the z-index via CSS with the button click (but this seems really hackish). I could probably also programatically resize the modal after the button fires modal.show() but that would cause a visible jump in the layout which I would like to avoid.
Any suggestions? I know AlloyUI has tons of hidden goodies, as their documentation is sparse, perhaps the visible attribute is not the one I should be using?
After some research I found an answer to my own question, this still may be a hacky fix but until someone comes up with something better here is the solution.
Step 1:
Leave visible: true intact.
Step 2:
Invoke .hide() after setting up the modal
The complete code.
YUI().use('aui-modal', function(Y) {
var modal = new Y.Modal({
bodyContent: '<div id="dialogBody"><div id="myTab"></div></div>',
centered: true,
headerContent: '<h3>Modal Goodness</h3>',
height: 600,
modal: true,
render: '#modal',
width: 900
}).render();
modal.addToolbar([
{
label: 'Save',
on: {
click: function() {
alert('You clicked save!');
}
}
},
{
label: 'Close',
on: {
click: function() {
modal.hide();
}
}
}
]);
modal.hide();
Y.one('#showModal').on(
'click',
function() {
modal.show();
}
);
});
I've done it nearly as you, just a little difference
modal = new Y.Modal(
{
centered: true,
contentBox: '#contentBox',
destroyOnHide: false,
headerContent: '<h3>Informations to your Orders</h3>',
height: 400,
modal: true,
render: '#modal',
resizable: {
handles: 'b, r'
},
visible: true,
width: 450
}
).hide();
I replaced .render() with hide(), by clicking a button this lines of codes are called:
Y.all('#showModal').on(
'click',
function() {
modal.show();
}
);
Can't find a method or parameter on YUI API Docs to stop auto render, so that seems to be the 'usual' way. I thought it might be the attribute render, but setting it to false or deleting the attribute don't make any changes to the auto init behaviour.
I have a form with drop-down hierarchical fields with functionality derived from a JavaScript plugin called mcDropdown jQuery Plug-in.
The actual form is on a secondary page (Test.php) and set up to display on the main page through a Colorbox popup with the results also displayed in the Colorbox upon form submission.
The form submits and displays correctly in the Colorbox in its native HTML format when the JavaScript is removed (i.e. just using plain drop-down boxes).
However, when the Javascript is implemented in the form allowing the hierarchial drop-down structure of the fields there is no JS functionality when rendered through Colorbox.
Since the actual page that the form is on (Test.php) works fine by itself with the Javascript, there appears to be some issue rendering the JS through the Colorbox.
My research has indicated that this may be due to trying to access an element before it has been loaded into the document.
The Colorbox website states that this can be resolved by moving the JavaScript into ColorBox's onComplete callback; however, even with the example given, I cannot figure out how to do this correctly as I am a complete novice when it comes to JS.
Here is the drop-down script on the secondary page that has the form and ties into the external plugin (note that there are three fields in this form that use this JS hierarchical configuration):
<script type="text/javascript">
$(document).ready(function (){
$("#category").mcDropdown("#categorymenu",
{
targetColumnSize: 3,
}
);
$("#category1").mcDropdown("#categorymenu1",
{
targetColumnSize: 3,
}
);
$("#category2").mcDropdown("#categorymenu2",
{
targetColumnSize: 3,
}
);
});
</script>
Here is the Colorbox script on the main page that opens the secondary page in the Colorbox window:
<script type="text/javascript"> <!--<Check-Out Colorbox Script>-->
jQuery(function(){
jQuery('#link_content').colorbox({opacity:0.3, height:"100%", scrolling: false, onComplete: function(){
link_content_submit();
}});
});
function link_content_submit()
{
jQuery("#pre-process").submit(function(){
jQuery.post(
jQuery(this).attr('action'),
jQuery(this).serialize(),
function(data){
jQuery().colorbox({html: data, onComplete: function(){
link_content_submit();
}});
}
);
return false;
});
}
</script>
The three external files are: jquery.mcdropdown.js, jquery-1.2.6.min.js and jquery.bgiframe.js.
How can this Colorbox script on the main page be modified so the JS functionality of the form is preserved when displayed through Colorbox?
Thank you in advance for any detailed answers for this beginner.
Here is the answer:
<script type="text/javascript"> <!--<Check-Out Colorbox Script>-->
jQuery(function(){
jQuery('#link_content').colorbox({opacity:0.3, height:"100%", scrolling: false, onComplete: function(){
link_content_submit(), $('#category').mcDropdown('#categorymenu'),$('#category1').mcDropdown('#categorymenu1'),$('#category2').mcDropdown('#categorymenu2');
}});
});
function link_content_submit()
{
jQuery("#pre-process").submit(function(){
jQuery.post(
jQuery(this).attr('action'),
jQuery(this).serialize(),
function(data){
jQuery().colorbox({html: data, onComplete: function(){
link_content_submit();
}});
}
);
return false;
});
}
</script>
The respective JavaScript functions for each drop-down box in the JS form are integrated into the Colorbox onComplete: function() so each of these form elements is loaded before it is accessed through Colorbox.
I've got the following code on my editRecords.php page. This page is a table of records and when I cick the view link it opens a dialog box with the displayRecord.php page in it. The problem is if I open the last record in the table instead of the dialog box opening/closing and the editRecords.php page remaining as is, it appears to reload which takes me back to the top of the page.
$(document).ready(function() {
//creating a dialog box
var dlg=$('#ticketDetails').dialog({
title: 'Ticket Details',
resizable: false,
autoOpen:false,
modal: true,
hide: 'fade',
width: 1300
});
//loading dialog box with record
$('a.view').click(
function(e)
{
dlg.load('displayRecord.php?id='+this.id, function(){
dlg.dialog('open');
});
});
});
I have tried using e.preventDefault() but this causes the dialog box to load with focus in the middle instead of the top.
function(e)
{
//tested here e.preventDefault();
dlg.load('displayRecord.php?id='+this.id, function(){
dlg.dialog('open');
});
//tested here e.preventDefault();
How can fix/adjust this behaviour?
Thanks.
CLARIFICATION:
e.preventDefault() works but the problem is it causes the dialog to load with the focus in the middle. I have no problem opening or closing the dialog. I just want to stop the base page(editRecords.php) from reloading (or what appears to be like a page reload) so that when I close the dialog I see the record I clicked instead of having to scroll down again.
Let us see how to load content dynamically inside this Dialog
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Load Page Dynamically inside a jQuery UI Dialog</title>
<link rel="Stylesheet" type="text/css" href="
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css
" />
<script type="text/javascript" src="
http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js">
</script>
<script type="text/javascript" src="
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js">
</script>
<script type="text/javascript">
$(function () {
$('<div>').dialog({
modal: true,
open: function ()
{
$(this).load('Sample.htm');
},
height: 400,
width: 400,
title: 'Dynamically Loaded Page'
});
});
</script>
</head>
<body>
</body>
</html>
As you can see, we are creating a div element on the fly and specifying a callback for the open event, which loads the content of the page ‘Sample.htm’ dynamically.
Opening and closing the dialog multiple times will not remove the dialog from the page. If you want to implement the close event, use this code in the dialog options (untested code):
close: function(e, i) { $(this).close(); }
That’s all!
We have a image that calls a script function that should show a jquery modal dialog popup. The dialog loads once with the data and then when we close it and try to click on the img again it does not load the data, sometimes the dialog will appear but be blank. If we take the link from the img tag and put it in a new browser it pulls the data fine so the link should be ok.
Below is the script in the head section of the page:
function ShowReportDialog(reporturl){
jQuery("#reportdialog").dialog({
title: 'Hello World',
modal: true,
width: 915,
height: 670}).show();
jQuery("#reportdialog").load(reporturl);
}
Image Tag that calls the script:
<img style="border:0;" onclick="ShowReportDialog('Service/REPORT?ARCHIVE=102127');" src="/Images/rerun.png"
Anyone see anything I missed or a better way?
Thanks
jQuery is probably caching your AJAX request. Check out this other thread for ways to prevent this from happening.
Edit: I'm by no means a jQuery expert, but I believe you should only show your dialog after the AJAX request has been responded. So I'm guessing something like this:
function ShowReportDialog(reporturl){
jQuery("#reportdialog").load(reporturl, function(){
jQuery("#reportdialog").dialog({
title: 'Hello World',
modal: true,
width: 915,
height: 670
}).show();
});
}