I am new to ckeditor, I have hard time figuring this issue out.
due to my html design; if I try to use the link editor dialog while my ckeditor is maximized, it just doesn't show up, I understand that ckeditor is the top most object in my html page and the link dialog comes underneath it. if now I bring ckeditor to its normal state I will be able to see and use the link dialog.
my idea is to slightly override the link button click event as follows:
if the editor is in full screen mode, bring it back to the normal state. and keep a flag somewhere so that when I close the link dialog, I can decide whether to bring back the ckeditor to a maximized mode again. now this is easy logic except that I do not know how to override the click event of the link button and keep it work as expected.
here's what I have:
$().ready(function () {
var editor = $('#txa').ckeditor();
CKEDITOR.plugins.registered['link']=
{
init : function( editor )
{
var command = editor.addCommand( 'link',
{
modes : { wysiwyg:1, source:1 },
exec : function( editor ) {
if(editor.commands.maximize.state == 1 ){
alert("maximized");
//....here bring back the editor to UN-maximized state and let the link button event click do the default behavior
}
else
{
alert("normal state");
}
//2 is normal state
//1 is maximized
}
}
);
editor.ui.addButton( 'link',{label : 'YOUR LABEL',command : 'link'});
}
}
});
html part to make the exemple work:
<div>
<textarea id="txa">
</textarea>
</div>
TO BE SHORT:
http://jsfiddle.net/Q43QP/
if the editor is maximized, bring it to normal state then show the link dialog.
Use editor.execCommand('maximize') to toggle the state of the editor window.
http://jsfiddle.net/Q43QP/2/
Related
I'm building a gmail extension that extends the compose view with an extra toolbar, using inboxSDK and content-scripts. Everything is working fine, I've injected everything, and I'm using gmail's style sheets and classes to make it flow more with the gmail UI. There is a class called "J-Z-M-I-Kq" (default gmail stylesheet) which when applied to a button-like div, gives the button the appearance of being pressed.
The issue comes when I close one compose view, and open another. Because the html for the new compose view is generated when the compose button is clicked, I have to re-inject all the toolbar things again. Everything works perfectly fine, except this class won't add to my button. I've tried making my own class and applying it in the exact same way, using the exact same jQuery selectors, and that works. In the dev tools, when I click the button, the element flashes like it would if the class was about to be added, but it just doesn't. I'm so confused as to why this might be happening.
This is the click handler:
$(dropdownContainer).click(function (e) {
let senderElement = $(e.target);
let checkTarget = senderElement.is("form") || senderElement.is("input") || senderElement.is("p");
if (checkTarget) {
return;
}
let wasOpen = false;
if (!($(dropdownContent).is(":hidden"))) {
wasOpen = true;
}
// Remove all dropdown content and un-highlight all buttons
$(".dropdown-content").hide();
$(".dropdown-btn").removeClass("J-Z-M-I-Kq");
// If the clicked button was already open, then do nothing (it has been closed). Else
// open the dropdown
if (!wasOpen) {
console.log("it wasn't open");
forceShow($(dropdownContent));
console.log(button);
$(button).addClass("red");
}
});
The ID_NUMBER is so that I can have unique ids when re-generating the tool bar.
button is the button that is clicked, and is defined earlier - console.logging this shows that the selector isn't the issue.
If I were to do button.addClass("red"), where red is an injected stylesheet - it works perfectly. All the other classes (such as one which does a similar effect but on hover) work fine, even when a second compose view is open. If I run the code in console, the effect works. Removing the class by clicking off even works when manually adding the class in console! I'm really stumped here, any help would be appreciated.
We currently have an app (sails/node js), where the user is displayed a set of items which are dynamically produced. The user has the option to produce more dynamic items (using a button) or can preview one item (new page). Currently, the more items button is implemented as a jquery add-on implementing a post request.
The issue is, when the user clicks the more items button and selects one item for preview, and then presses the browser back button, the dynamic content is lost.
We see different options:
1. Implement pagination and infinite scroll and use history js to manage back button
2. Use history with the current set up and combine with jquery to manage back button.
Are there any other approach? Any help appreciated. We are totally new to this development environment.
You can leverage a History API:
var stateObj = { lastItemId: 456 }; // or { page: 3 }
history.pushState(stateObj, "page 2", "bar.html");
The easiest way I found was to "disable" back button clicks. Ok, technically, there's no way to disable it, but you can give the end user the appearance that the back button has been disabled. I originally developed my code based on this blog post. It's a good read as he explains the approach in detail. Since then, I've refined his code as detailed below.
So I define preventBackButton () like this.
function preventBackButton () {
// Triggered when the back button is pressed, it will detect if the url hash changes from #rms to #no-back. If it does, then
// it harmlessly changes the url hash forward again by going from "#no-back" to "#rms".
// On initial page load, pushes states "#no-back" and "#rms" onto the history, making it the most recent "page" to detect future "back" button presses.
var history_api = typeof history.pushState !== 'undefined';
if ( history_api ) {
history.pushState(null, '', '#no-back');
history.pushState(null, '', '#rms');
} else {
location.hash = '#no-back';
location.hash = '#rms';
}
// This function creates an event handler on hash changes. This is coded to detect back button clicks.
window.onhashchange = function() {
// location.hash becomes "#no-back" when the user clicks back button
if ( location.hash === '#no-back' ) {
if ( history_api ) {
history.pushState(null, '', '#rms');
} else {
location.hash = '#rms';
}
}
};
} // function preventBackButton ()
Then I call it in $(document).ready()
$(document).ready(function() {
preventBackButton();
// Do other stuff...
});
I have created a ionic popup window, instead of the default two buttons at the bottom, I would like to add a button in the body of the popup window. Actually does it really possible to do so? If not, another other method / suggestion?
I have tried to insert some html code in the template but it didn't work.
I would like to add a button like the grey button as shown in the diagram. Thank you for your time for reading my question.
Yes, you can add a customized button to the body of an ionic popup by injecting it into the template. Below is based off of Ionics Popup nightly build with no logic.
Please visit the codepen at the bottom so you can see it in action. If you want to customize the popup, as well, you can apply a custom css class to it too.
angular.module('mySuperApp', ['ionic'])
.controller('PopupCtrl',function($scope, $ionicPopup) {
// Triggered on a button click, or some other target
$scope.showPopup = function() {
$scope.data = {}
var myPopup = $ionicPopup.show({
title: 'Title',
template: '<p>Customer Detail</p> <button type="button">Print</button>',
scope: $scope,
cssClass:'customPopupClass',
buttons: [
{text: 'Back' },
{text: '<b>Submit</b>', type: 'button-dark',},
]
});
};
});
cssClass example to customize popup even more:
.customPopupClass{
.popup{
//style for popup
}
.popup-title{
//style for title
}
}
List of CSS classes to override and customize popup even further
.popup
.popup-head
.popup-title
.popup-sub-title
.popup-body
.popup-buttons.row
.popup-buttons .button
Here is the codepen so you can play around with it.
If by create you mean you actually created/designed this dialog box you can customize it any way you like. You can use http://jqueryui.com/dialog/.
You can use these libraries to create HTML elements that look and behave like a dialog box/popup window, allowing you to put anything you want (including buttons) in the dialog.
The scenario I'm trying to solve is to disable that the escape-button closes the dialog AFTER the modal has been instaniated (the dialog is set to a loading state). So in other words after I have instaniated my modal like this:
(this.$el).modal("show");
The user presses a submit button and the dialog is set to a loading state and I want to disable the escape-button since the user should not be able to close the dialog in this state.
I have tried this:
(this.$el).modal({ keyboard: false });
But it does not work, it seems that Bootstrap only reads those options when it instaniates the modal dialog...
So my question is if it is possible to get a hold of the actual bootstrap modal-instance to be able to change the options-object? According to the documentation it should be possible (or have I misunderstood the docs?), but I cannot figure out how.
Here is what it says in the documentation (http://getbootstrap.com/javascript/):
If you'd like to get a particular plugin instance, retrieve it directly from an element:
$('[rel="popover"]').data('popover').
Any ideas?
Ok, I figured out how to get ahold of the modal dialog instance after some experimentation:
var bootstrapModalInstance = this.$el.data("bs.modal");
And then I could set the options on the instance like this:
bootstrapModalInstance.options.keyboard = !this.model.isSyncing;
Sadly enough, this did not solve the problem since the escape-key-event-listener is setup during the modal instaniation like this:
From bootstrap.js
Modal.prototype.escape = function () {
if (this.isShown && this.options.keyboard) { // The event listener is setup on initalization
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide() // !!! Does not check the instance options.keyboard flag status, so I had to add && this.options.keyboard here
}, this))
} else if (!this.isShown) {
this.$element.off('keydown.dismiss.bs.modal')
}
}
And as I wrote in the code comment above adding the instance options.keyboard check in the event listener solved the issue.
CKEditor 4 or above
I have form > textarea with CKEditor enabled and functioning.
I have iframe in modal dialog and inside iframe is button with insert_media() javascript function.
function insert_media( element ) {
// get element html decode
element = htmlspecialchars_decode( element, 'ENT_QUOTES' );
// htmlspecialchars_decode is external function.
// CKEditor insert element ---------------------------------------------
// use .insertElement()
var CKEDITOR = window.parent.CKEDITOR;
var element = CKEDITOR.dom.element.createFromHtml(element);
// body_value is name of textarea
// this code only works with specific textarea NOT current active textarea
//CKEDITOR.instances.body_value.insertElement(element);
var current_instance_ckeditor = window.parent.test_current();
// CKEditor insert element ---------------------------------------------
// close modal dialog at parent window
window.parent.close_dialog();
// done
return false;
}// insert_media
and this is javascript in main page html
function close_dialog() {
$('#media-modal').modal('hide');
}// close_dialog
function test_current() {
console.log( CKEDITOR.currentInstance.name );
}
The problem is i cannot get current active CKEditor to insert element with insertElement command.
CKEDITOR.currentInstance is undefined or null
window.parent.CKEDITOR.currentInstance is undefined or null
How to get current active CKEditor from iframe?
file for test: http://www.megafileupload.com/en/file/420060/test-ckeditor-zip.html
If CKEDITOR.currentInstance is null/undefined, then none editor instance is active. It means that you moved focus out of editor to the place which is not recognised as its part.
However, if you're using CKEditor's dialogs (do you?) editor instance should always be active, when this dialog is opened for it. If this is your case, then you need to provide us a working example, because it's hard to guess what can be wrong.
Second option is that you don't use CKEditor's dialogs and then you have to take care of registering that iframe to the CKEditor's focusManager, although this is tricky so you rather should not use 3rd party's dialogs with CKEditor.
Edit The test_current function works fine when I click "test" button, but editor has to be focused. But after 200ms from the moment you click button editor will be blurred and you won't be able to get it from currentInstance. To avoid blurring editor when clicking button you need to register it in focusManagers (of both editors if it will be used with both).
I'd do it like this
var ck_instance_name = false;
for ( var ck_instance in CKEDITOR.instances ){
if (CKEDITOR.instances[ck_instance].focusManager.hasFocus){
ck_instance_name = ck_instance;
return ck_instance_name;
}
}
CKEditor is null/undefined as Reinmar said.
Now i can find the way to work with current instance even if you clicked outside CKEditor.
Here is sample files for test.
http://www.megafileupload.com/en/file/448409/test-ckeditor-zip.html
What i do is ...
Add global variable for current instance in javascript (in html)
On click button for open modal dialog, get current instance and set to global variable in choice 1.
On click insert button in iframe in modal dialog, get window.parent.current_instance variable and use as texteditor id. (var parent_cke_current_id = window.parent.current_instance_id;)
Now do what ever you want with clicked CKEditor instance. for example (CKEDITOR.instances[parent_cke_current_id].insertElement(element);)
Thank you Reinmar.