I'm using Grails 1.3.7 and I use tinyMCE via richui. I'm trying to display a modal window which enables users to send a mail. However, if tinyMCE is correctly displayed, I can't use the text editor because of this error :
t.win.document is null
I finally found the reason here, at the end of the article :
http://blog.mirthlab.com/2008/11/13/dynamically-adding-and-removing-tinymce-instances-to-a-page/
It seems that when I call the page with the jquery script building the modal window, DOM isn't refreshed and doesn't create the corresponding textarea.
Anyway I don't know how to resolve this, so here is my code :
Jquery code :
function dialogSendFirstMail(id) {
var monurl = "/myApp/emailTemplate/writeFirstMail.gsp?id_for_mail="+id;
var titre = "Premier email"
//alert(monurl);
$("#dialogSendFirstMail").load(monurl, function() {
$(this).dialog({
height: 'auto',
width:'auto',
modal: true,
position: 'center',
overlay: {
backgroundColor: '#000',
opacity: 0.5
},
title:titre
});
});
}
GSP calling the script for the modal window :
<!-- ... -->
<g:if test="${params.sendFirstMail}" >
<div id="dialogSendFirstMail"></div>
<script>dialogSendFirstMail(${idProfil});</script>
</g:if>
</body>
modal window (only this for the moment) :
<richui:richTextEditor name="firstMail" value="%Email_de_bienvenue%"/>
In summary, if I detect that I have to send a first mail, the page creates a div in which is placed tinyMCE. This is what the user will see.
As you have mentioned, the reason that you the the error "t.win.document is null" is because the DOM isn't refreshed. So you will have to add the tinyMCE control explicitly when you load the modal dialog. You can use something like this in the gsp which renders the richUI editor (writeFirstMail.gsp in your case) :
jQuery(document).ready(function() {
//your tinyMCE settings here
tinyMCE.settings = {
mode : "textareas",
theme : "simple",
editor_selector : "mcesimple",
width: 400
};
tinyMCE.execCommand("mceAddControl", false, "yourTextareaId");
});
Once the dialog is closed, you can remove tinyMCE control from the textarea using this:
tinyMCE.execCommand("mceRemoveControl", false, "yourTextareaId");
Related
I am using jquery-ui and it's dialog functionality to display modal dialogs in my web app. It works ok.
At one use case, I have a colorbox popup window on a screen, and once user finishes his input I need to display a confirmation dialog.
Also here everything actually works thanks to error handling on all the major browsers I tried, but I worry what problems might some combination of javascript engine&browser could cause.
The error I get is call stack size overflow (Chrome shows it as Uncaught RangeError: Maximum call stack size exceeded.).
The code for the modal dialog is:
function modalDialog(dialogText, dialogTitle, okFunc, okLabel, cancelFunc, cancelLabel) {
var dialogButtons = {};
dialogButtons[okLabel] = function() {
if (typeof(okFunc) == 'function') {
setTimeout(okFunc, 50);
}
$(this).dialog('destroy');
};
dialogButtons[cancelLabel] = function() {
if (typeof(cancelFunc) == 'function') {
setTimeout(cancelFunc, 50);
}
$(this).dialog('destroy');
};
$('<div style="padding: 10px; max-width: 500px; word-wrap: break-word;">' + dialogText + '</div>').dialog({
draggable: true,
modal: true,
resizable: false,
width: 'auto',
title: dialogTitle || 'Confirm',
minHeight: 75,
buttons: dialogButtons
});
}
The colorbox is called in javascript, and it takes embedded div from the actual page as it's content:
$(function() {
$(".colorbox-load").colorbox({
inline: true,
overlayClose: false,
href: "#popupContents",
height: "320",
width: "300"
});
})
In the popup, I have a button which just opens up the confirmation dialog.
I apologize in advance as it's my first time using JSFiddle, and I wasn't able to get colorbox and dialog popup match exactly how it looks on my page (it actually pops up properly on top of the colorbox and not "in the background"). I'm not sure if this is because I had to use different versions of jquery and jquery-ui (I couldn't find same combination I am using from the pulldown) or something else.
A JSFiddle is here. If you click around the colorbox area once the "open dialog" button has been pressed you should get same error (firefox and Chrome seem to react slightly differently when to show the error).
Thank you for any suggestions!
It seems like the Dialog and Colorbox are fighting for the focus. Setting the trapFocus setting to false will resolve this issue. Of course it might have some side effects for your page depending on how you use it. Please consult the official documentation for details.
$(function() {
$(".colorbox-load").colorbox({
inline: true,
overlayClose: false,
href: "#popupContents",
height: "320",
width: "300",
trapFocus: false
});
})
I am upgrading Jquery version from jquery-1.6.4.min.js to jquery-1.10.2.js
and jquery ui version from jquery-ui-1.7.2.js to jquery-ui-1.10.3.js
I have included latest version jquery-ui.css also.
This is script tag i am using.
<script type="text/javascript" src="JS/jquery-1.10.2.js"></script>
<script type="text/javascript" src="JS/jquery-ui-1.10.3.js"></script>
and this way i am opening a dialog.
dialog = $('#dialog-modal-error');
dialog.html (l_str);
dialog.dialog(); /* if i am not using this then it is giving me this error msg. cannot call methods on dialog prior to initialization; attempted to call method 'option'*/
if (dialog.dialog ('option', 'disabled') == undefined) {
dialog.dialog (
{
autoOpen: true,
position : { my: 'center', at: 'center'},
modal : false,
bgiframe : true,
buttons: {},
close : minimizeMessages,
resizable : false,
draggable : false
}
);
} else {
dialog.dialog ('open');
}
as a result it is always opening my dialog at the right bottom of the page so just want to know why it is showing me this behavior.
I have already checked all the css it is not taking any inherited css.
Edit:
I used this also position : { my: 'center', at: 'center', collison: 'none'} but not working.
With the last version of jquery it is working fine.
NOTE: Dialog is always coming out of the screen(Left -Bottom)
Check out the jQuery UI docs (http://api.jqueryui.com/dialog/#option-position) it seems that you have left the of attribute out. The default value for position is { my: "center", at: "center", of: window }. So try specifying the of: window attribute.
Use the 'of' attribute to position it properly. Where would you like it positioned?
For example:
position:{ my: "center", at: "center", of: $("#aDiv")}
This can also be read as:
place the center of my dialog box, at the center of the div with the ID aDiv.
i want to populate the tinymce body with some content on trigger of onchange event of selectbox in javascript. I tried some stuff but it did
not work for me.Please guide me in right direction.
Here is the my code that appends the tinymce on textarea
$(function() {
appendTinyMCE();
function appendTinyMCE(){
tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
plugins : "preview",
// Theme options
theme_advanced_buttons1 : "forecolor,backcolor,|,justifyleft,justifycenter,justifyright,justifyfull,bullist,numlist,|,formatselect,fontselect,fontsizeselect,sub,sup,|,bold,italic,underline,strikethrough",
theme_advanced_buttons2 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true
});}
});
here is the html code
<td>
<textarea rows="15" name="MyTinymceContent" cols="90" >MyTestContent</textarea>
Now i want to populate the tinymce with new content , on change of select box in javascript. So i write the below code snippet on change
of select box
function populateMyTinyMCE() {
document.form.MyTinymceContent.value ="MyNewContent";
}
But it does not put the new content in tinymce body. I am not sure what i am missing here?
You can call any of following on some event trigger:
tinyMCE.get('your_editor').setContent("MyNewContent");
//OR
tinyMCE.activeEditor.setContent('MyNewContent');
See: Here for More
Tinymce is not equal the textarea. On initialization of the editor a contenteditable iframe get created. This iframe holds the editor content and gets written back into the editor source html element (in your case a textarea) from time to time. To set the editor content you need to use the tinymce setContent function. I will show the alternatives too:
function populateMyTinyMCE() {
var editor = tinymce.editors[0];
// other ways to get the editor instance
// editor = tinymce.get('my editor id');
// editor = tinymce.activeEditor;
editor.setContent('my new content');
// alternate way of setting the content
// editor.getBody().innerHTML = 'my new content';
}
Try
tinyMCE.activeEditor.setContent("MyNewContent");
Javascript and jQuery (Fancybox) question
I'm using the Javascript function below for Twitter sharing (as well as other services; the function code is simplified to just Twitter for this question) that grabs the to-be-shared page URL and title and it is invoked in the link with onclick. That results in the Twitter share page loading in a pop up browser window, i.e.<img src="/images/twitter_16.png" onclick="share.tw()" />
In order to be consistent with other design aspects of the site, what I'd like to be able to do is have the Twitter share page open not in a standard browser window but in a Fancybox (jQuery) window.
Fancybox can load an external page in an iFrame when the img or href link contains a class (in this case class="iframe" ) in the link and in the document ready function in the header.
Right now, of course, when I give the iframe class to the link that also has the onclick share.tw(), I get two popups: one browser window popup with the correct Twitter share page loaded, and a Fancybox jQuery popup that shows a site 404.
How can I change the function to use Fancybox to present the Twitter share page? Is that a correct way to approach it? Or is there a better way, such as implementing the share function in jQuery, too?
Thanks...
Javascript share function:
var share = {
tw:function(title,url) {
this.share('http://twitter.com/home?status=##URL##+##TITLE##',title,url);
},
share:function(tpl,title,url) {
if(!url) url = encodeURIComponent(window.location);
if(!title) title = encodeURIComponent(document.title);
tpl = tpl.replace("##URL##",url);
tpl = tpl.replace("##TITLE##",title);
window.open(tpl,"sharewindow"+tpl.substr(6,15),"width=640,height=480");
}
};
It is invoked, i.e.: <img src="/images/twitter_16.png" onclick="share.tw()" />
Fancybox function, invoked by adding class="iframe" in the img or href link
$(".iframe").fancybox({
'width' : '100%',
'height' : '100%',
'autoScale' : false,
'transitionIn' : 'none',
'transitionOut' : 'none',
'type' : 'iframe'
});
No matter how you change your design, using an iframe with Twitter isn't going to work.
If you replace the URL http://twitter.com with anything else eg http://www.godaddy.com - it will work. I tried something like below:
$('h1').click(function(e) {
$.fancybox({
href : 'http://www.godaddy.com', // http://twitter.com will not work here
title : 'twitter window',
width : 640,
height : 480,
type : 'iframe'
});
});
This is because Twitter uses javascript to "break" iframes on purpose for security reasons.
So your idea of showing a FancyBox iframe in this way cannot work if using Twitter.com. There is confirmation of this and some ideas on getting around it here: (like using API calls from an iframe) - http://groups.google.com/group/twitter-development-talk/browse_thread/thread/b1bca9ef074086c7
For your "other services" that hopefully don't have the same restrictions (I suspect some of them might) then the other answer further down the page from wajiw seems a good compliment.
My approach would be to remove the fancybox initialization and trigger it directly from your share function:
var share = {
tw:function(title,url) {
this.share('http://twitter.com/home?status=##URL##+##TITLE##',title,url);
},
share:function(tpl,title,url) {
if(!url) url = encodeURIComponent(window.location);
if(!title) title = encodeURIComponent(document.title);
tpl = tpl.replace("##URL##",url);
tpl = tpl.replace("##TITLE##",title);
$.fancybox({
'href' : tpl,
'title' : title,
'width' : '100%',
'height' : '100%',
'autoScale' : false,
'transitionIn' : 'none',
'transitionOut' : 'none',
'type' : 'iframe'
});
return false;
}
};
I'm not sure my syntax is correct, but something like that should work for you.
Another different attempt may be to use a dummy anchor, alter it's attributes, and trigger click on it:
jQuery(document).ready(function() {
$("#dummyLink").fancybox({
'width' : '100%',
'height' : '100%',
'autoScale' : false,
'transitionIn' : 'none',
'transitionOut' : 'none',
'type' : 'iframe'
});
return false;
}
};
});
var share = {
tw:function(title,url) {
this.share('http://twitter.com/home?status=##URL##+##TITLE##',title,url);
},
share:function(tpl,title,url) {
if(!url) url = encodeURIComponent(window.location);
if(!title) title = encodeURIComponent(document.title);
tpl = tpl.replace("##URL##",url);
tpl = tpl.replace("##TITLE##",title);
$("#dummyLink").attr('href', tpl);
$("#dummyLink").attr('title', title);
$("#dummyLink").trigger('click');
return false;
}
};
HTML:
What I see is that the window.open function, is responsible for opening the new browser window. This one should go. Instead you should be setting the href of a link like This goes to iframe, and then invoke the fancybox function.
It's been a while since I've used fancybox, I prefer using jquery-ui.dialog, so I could be wrong ..
I've run into this same exact issue using the jQuery Colorbox plugin. I was trying to make Share on Twitter and Share on Facebook links that would open up in the modal box. When you would open the links, the modal box would appear, however the iFrame would be blank and only a white box would be displayed.
Unfortunately, this is expected behavior. Both the Twitter sharing page and the Facebook sharing pages have instructions to break out of the frame when the link is followed, thus the blank box you're seeing. Since the content that is being delivered by the respective sites are not under your control, there is no way to stop this.
Its impossible with twitter as others noted.
If you View Source of Twitter homepage, you will see a small script like this just below the body tag.
<script>
if (window.top !== window.self) {
document.write = "";
window.top.location = window.self.location;
setTimeout(function() {
document.body.innerHTML = ""
}, 1);
window.self.onload = function() {
document.body.innerHTML = ""
}
};
</script>
Which means if you are in an iframe(self != top), pull out a blank page.
No workarounds are possible.
Perhaps take a look at http://platform.twitter.com/widgets.js and see how Twitter creates their popup, then figured out if you could stick that incide a widget.
I have a hidden div:
<div id="termSheetPrinted" style="visibility:hidden;">
</div>
that I am populating through the click of a button. After that population takes place, I would like to display the contents of this div on a separate popup window so the user can print it.
How would I do that with JQuery or Javascript or whatever is easiest.
slandau,
[edited] as per new information in your comment below.
using the jquery dialog (you must reference the jquery-ui js), create a 2nd div on the base html page and call it something like termSheetPrintedDialog.
<div id="termSheetPrintedDialog" style="visibility:hidden;"></div>
then in your document ready event, put:
$("#termSheetPrintedDialog").dialog({
autoOpen: false,
resizable: false,
height: 510,
width: 800,
position: 'center',
title: 'my snazzy popup window',
},
modal: true
});
then, in your button click event on your 1st modal form:
$('#yourbutton').click(function() {
// your div population code here ... etc
$('#termSheetPrintedDialog').html($('#termSheetPrinted').html());
$('#termSheetPrintedDialog').dialog('open');
});
it's not pretty, but it's an approach based on the constraints that you have.
You can use
var myWin = window.open('');
myWin.document.write(<html code>);
myWin.document.close();
Here is a link to read more about it:
window.open