Customizing Body Color in CKEditor for Dynamic Designs

I am facing an issue with CKEditor that I am hoping to find a solution for. My scenario involves using a jQuery color picker to set the background color of a DIV element, which is then edited by the user in CKEditor. However, I have observed that it is not straightforward to automatically apply the background color of the div element to CKEditor when it loads.

I have explored options like bodyClass and bodyId, but they don't seem to address my specific challenge. Instead of having a class assigned to the element, I have an inline style declaration like

<div class="tp-header" style="background-color:#CCCCCC;">content</div>

My CKEditor invocation looks like this:

var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color = $('.' + headerElementClass).css('background-color');
if (instance) { CKEDITOR.remove(instance); }
$('#' + editorId).ckeditor({ toolbar: 'BasicHtml', height: '100px', width: '500px', fullPage: false, bodyClass : 'background-color:' + color });
$('#' + editorId).val($('.' + headerElementClass).html());

As you can see, the attempt to use bodyClass has not been successful. Is there any other method to achieve this? I have searched extensively for solutions online but haven't come across one yet. Hopefully, someone here can provide some insights.

Answer №1

After some consideration, I have devised a simpler solution.
Since I am not using the CKEditor jQuery adapter, you may need to make adjustments based on your specific requirements.

I conducted tests using the standard JavaScript integration method.

Here is a brief summary:
Set the necessary variables.
Instantiate the editor.

Add this "addCss" function call:

CKEDITOR.instances[editorId].addCss( 'body { background-color: '+color+'; }' );

That's essentially all there is to it. Below is a sample implementation tailored to your code:

// Include the "id" attribute:
<div id="editor1" class="tp-header" style="background-color:#CCCCCC;">content</div>

// Define the variables, including "headerElementClass".
var headerElementClass = "tp-header";
var color = $('.' + headerElementClass).css('background-color');
var editorId = 'editor1';

// Initialize the instance.
var instanceOne = CKEDITOR.replace( editorId,
{
  toolbar: 'Basic',
  height: '100px',
  width: '500px',
  fullPage: false,
  customConfig : 'yourCustomConfigFileIfUsed.js'
 });

// Add the "addCss" function call:
instanceOne.addCss( 'body { background-color: '+color+'; }' );


If preferred, the addCss function call can be moved to your configuration file (place it outside the editorConfig function).

Best regards, Joe


Instead of opting for a more complex approach, others might find these concepts beneficial.

You could utilize ( bodyClass: 'nameOfClass' ) and assign a value to the background-color property of that class. However, this becomes challenging with a dynamic background color.

To dynamically assign the background color, consider the following extension of your existing code using jQuery:

var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color = $('.' + headerElementClass).css('background-color');

// Create a unique body id for this instance "editor1" ( bodyIdForEditor1 )
var idForBody = 'bodyIdFor' + editorId;

if (instance) { CKEDITOR.remove(instance); }

// Use bodyId instead of the original bodyClass assignment
$('#' + editorId).ckeditor({ 
  toolbar: 'BasicHtml', 
  height: '100px', 
  width: '500px', 
  fullPage: false, 
  bodyId : idForBody 
});

$('#' + editorId).val($('.' + headerElementClass).html());

// Set the background color to the body after both document and editor instance are ready

// Trigger the document ready event
$(document).ready(function(){

  // Wait for the instanceReady event to fire for this (editor1) instance
  CKEDITOR.instances.editor1.on( 'instanceReady', 
    function( instanceReadyEventObj )
    {
      var currentEditorInstance = instanceReadyEventObj.editor;
      var iframeDoc=null;

      // Utility function to streamline repetitive steps
      function setIframeBackground()
      {
        $("#cke_contents_editor1 iframe").attr("id", "cke_contents_iframe_editor1");
        $('#cke_iframe_editor1').each( 
          function(){ iframeDoc=this.contentWindow.document;}
        );

        $('#' + idForBody, iframeDoc).css("background-color", color);
      }

      // Call the function upon initial loading of the editor instance
      setIframeBackground();

      // Reapply the color when switching back from "source" view mode which destroys the iframe
      currentEditorInstance.on( 'mode', function()
      {
        if(currentEditorInstance.mode == 'wysiwyg')
          setIframeBackground();
      });
    }
  );
});

Best regards, Joe

Answer №2

An excellent suggestion from codewaggle is to apply inline styles directly to the editor's <body> element using:

editor.document.getBody().setStyle()

Alternatively, you can use:

editor.document.getBody().setStyles()

Keep in mind that you will need to reapply these styles every time after calling editor.setData() and switching between wysiwyg and source modes, as these actions recreate the editor iframe. To streamline this process, create a function like setEditorStyle, ensuring that editor.mode==='wysiwyg' before applying any styles (as editor.document would be null otherwise). Then, attach this function as an event listener for the instanceReady and mode events, and perhaps also the contentDom event if you call setData() without manually triggering it afterwards.

For more insights, refer to other relevant answers on StackOverflow here and here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to utilize mapping and filtering distinct values in an array using TypeScript?

What is the best way to filter and map distinct elements from an array into another array? I've experimented with various methods but keep encountering a syntax error stating "Illegal return statement". My objective is to display only unique items f ...

Angular custom filter with FabricJS

I am working with a binary/grayscale image and my objective is to filter the image so that all white color becomes transparent and all dark colors change to a specific user-defined color. I am facing challenges in creating a custom filter in Angular. I ha ...

Retrieving information from an openDatabase using AngularJS

Encountering an issue while trying to retrieve data from openDatabase and display it in a listview. Following advice from a thread, I added $scope.$apply(); after $scope.items = $data;, but this resulted in an error: [$rootScope:inprog] $apply already in p ...

When adding my Angular web app to the home screen on iOS Safari, the icon appears as a screenshot instead of the specified apple-touch-icon

Despite adding an apple-touch-icon link to my index.html with a 150x150 PNG image, when I try to add my Angular web app as a shortcut to my iOS home screen from Safari, it only appears as a screenshot of the app page. Below is my HTML code: <!doctype ...

employ varying XSL stylesheets to display an XML document in a separate window

My issue involves an XML file being transformed by a specific XSL file (XSLT 1.0), which in turn includes multiple other XSL files with various templates. The challenge is to add a button to the rendered XML that, when clicked, opens the same XML in a ...

Trouble with table class functionality persists following insertion of SQL database

After successfully setting up the table layout and connecting it to a database, I encountered an issue with the class not working as expected. Despite being able to retrieve records and display them in the table, the desired layout was missing. <bo ...

Is it possible to use cakephp and AJAX to determine if a table is empty?

Is there a way to determine if a table is empty using CakePHP and AJAX? In my index.ctp, I have included an image that, when clicked, will notify the user about the status of the table. If the table is empty, an alert box will pop up; otherwise, the user w ...

Differences in typography across Mozilla Firefox and Internet Explorer

I have come across a question that seems quite common, yet unsolvable. However, I will give it a try anyway. Take a look at this image: To view a larger version of the image, visit the following URL: https://i.stack.imgur.com/dddNm.jpg HTML code: <d ...

Invoke a directive's function on a page by utilizing ng-click in AngularJS

Is there a way to call a function from a directive in an HTML page like index using ng-click? Below is the code for my directive: $scope.moreText = function() { $(".showMore").append(lastPart); }; html: <a ng ...

Receive live feedback from shell_exec command as it runs

I have been working on a PHP-scripted web page that takes the filename of a previously uploaded JFFS2 image on the server. The goal is to flash a partition with this image and display the results. Previously, I had used the following code: $tmp = shell_ex ...

Steps to extract selected values from the MUI data grid

Can values be retrieved from a mui DataGrid? I have a table and I would like to create a custom export that takes into account user filters and the display status of columns. However, I need to access these filtered values. Is there a way to achieve this ...

Issue with a responsive CSS circle element that holds an image

I'm struggling to figure out how to create 9 responsive CSS circles in a row, with each circle containing an img tag rather than a background image. The goal is to center the img and resize it based on the size of its parent circle div. These 9 circle ...

What is the mechanism by which nodes handle multiple requests simultaneously?

Lately, I've delved into the world of NodeJs, trying to grasp how it handles multiple concurrent requests. It's fascinating that NodeJs operates on a single-threaded event loop architecture, where only one statement executes at a time on the main ...

Changing the size of a responsive navigation bar with React and adjusting it based on the window.scrollY position switches between collapsed and un

I'm struggling to create a responsive navbar that automatically adjusts its size once it surpasses the height of the navbar (currently set at 80px). However, when I scroll to around the 80px mark, it starts flickering between the collapsed and expande ...

What is a more effective method for linking values with variables in an object?

Can you suggest a more efficient way to write this in JavaScript? let foo; if(bar) { foo = bar.value; } I am attempting to prevent a react error from occurring when `bar` is null if I were to use const foo = bar.value. ...

The error occurs when Facebook and Twitter iframes are attempting to access and set 'document.domain'

When attempting to add Tweet and Facebook Like buttons to the project I'm working on, everything appears to be functioning properly. However, upon clicking the buttons, a JavaScript error occurs: Unsafe JavaScript attempt to access frame with URL htt ...

Deciphering the Essence of Promise Sequences

In my NodeJS project, I am utilizing Promises and aiming to gain a better understanding of Promise.chains. Within the project, there is one exposed function: This main library function returns a promise and it is intended for users to call. After calling ...

Creating a Full Page Background Image That Fits Perfectly Without Resizing or Cropping

Can someone help me achieve the same effect as the website linked below, where the background image fades instead of being a slideshow? The image should be 100% in width and height without any cropping. I have managed to set this up with the codes provided ...

I'm experiencing an issue where my drum app element does not refresh after performing an action dispatch

Struggling with my React/Redux drum app, I'm at a roadblock with the final component that should update with the selected object's ID through an action dispatch. It baffles me why the element won't reflect the changes even though I've c ...

Tips for sending props to Material UI components

Hey there! I'm currently working on a progressbar component that utilizes animations to animate the progress. I've styled the component using Material UI classes and integrated it into another component where I pass props to customize the progres ...