How to define own list styles for ckeditor? - javascript

Is there a way to define own list styles for ckeditor. I have found the plugin http://ckeditor.com/addon/liststyle but it lets me choose only things like circle or square.
I want to define own css classes for ol or ul in my application that i can use. For example a class to define more space between list elements. the users of the editor should pick the list class via a context menu like in the nice "liststyle" plugin.
Is there a way to do this?

Confirmed the approach mentioned above works, I am using Drupal, Ckeditor List Style (plugin) and the Ckeditor List Style module (Drupal module).
I needed to make a change to the lang > en.js file to add the appropriate Title in instead of the function as the OP.
cute: 'Cute',
Once that was done, inside the liststyle.js file I updated the existing code to this:
Existing code in liststyle.js file:
commit: function(element) {
var value = this.getValue();
if (value)
element.setStyle('list-style-type', value);
else
element.removeStyle('list-style-type');
}
New code:
commit: function(element) {
var value = this.getValue();
if (value) {
if (value == 'cute') {
element.setAttribute("class", 'cute');
element.removeStyle('list-style-type');
} else {
element.setStyle('list-style-type', value);
}
} else {
element.removeStyle('list-style-type');
}
}

I am dealing with CKEditor to add custom list styling to the liststyle plugin.
I added one new style (you can add more if you like) using the CSS class.
Here's how: in liststyle.js (after de-obfuscating) I insert my .logo class:
..........
function e(c,e){
c.lang.liststyle.logo="My bullet"; // BBoyanov - adding 'My bullet' as title in dropdown list (in current language), otherwise it stay "empty" title
var b=c.lang.liststyle;
........
style:"width:150px",
items:[[b.notset,""],[b.circle,"circle"],[b.disc,"disc"],[b.square,"square"],
[b.logo,"logo"]],//BBoyanov - css class 'logo' as Bullet \,[b.logo,"logo"]\
........
commit:function(a){
var b=this.getValue();b?a.setStyle("list-style-type",b):a.removeStyle("list-style-type");
"logo"==b?a.setAttribute("class",'logo'):a.removeAttribute("class");//BBoyanv set 'logo' as CSS class
........
h={a:"lower-alpha",A:"upper-alpha",i:"lower-roman",I:"upper-roman",
1:"decimal", disc:"disc", circle:"circle", square:"square",logo:"logo"};//BBoyanov \,logo:"logo"\
........
You define the CSS class in ckeditor.css (to be visualised in CKEditor) and in your own CSS file.
If you prefer different titles for different languages, you must put translation in the corresponding language .js file of CKEditor.
It worked for me.
However, probably this is injection because it takes over the allowedContent - need tests and confirmation.

Related

Adding a class (related to tailwind) using javascript doens't work

I have a button with a PLUS svg image in it. On click, I what that Plus svg to disappear. I checked in console and the function works fine, the class "visible" is removed and the class "invisible" is added. But in the UI the Plus svg doesn't disappear.
"Invisible" is a class in Tailwind that should make an item to be hidden.
const BtnAddEle = document.querySelector(".addEle");
const plusSvg = document.querySelector(".addElePlus");
BtnAddEle.addEventListener("click", function () {
plusSvg.classList.remove("visible");
plusSvg.classList.add("invisible");
});
This is happening because tailwind only adds class styles which you have used in the final CSS file
So you can do something like this
const BtnAddEle = document.querySelector(".addEle");
const plusSvg = document.querySelector(".addElePlus");
BtnAddEle.addEventListener("click", function () {
plusSvg.style.visibility = "hidden"
});
The reason why it is not working for you is that-
To have tailwind classes to work from JS file you have to define the path of js file in the content portion of tailwind.config.js file.
Example:
content: ["./*.{html,js}", "./src/**/*.{html,js}"]
Using this, your tailwind compiler will know that you are trying to add a css class from your JS file and that class will appear in the output css file.
Content Configuration is mentioned and explained in details - Here [Official Documentation]

Proper way to author Jquery plugins with style rules

I have been long battling this, and I would like to know if any others have feedback. I am about to make a customized library for building web apps quickly, and I want to make sure I use the right approach. I WANT to use this method:
$.fn.someSlider = function(){
var coreStyle = '.slider ul { white-space: nowrap; } .slider ul li {display: inline-block}', coreStyleTemplate = '<style><\/style>';
}
But I feel like hard coding the base CSS into the widget is always frowned upon - instead I see SO users recommending the use of CSS style rules instead of this option. I really really really want that 'it just works' feel, and having to force my users to use a separate style sheet just to get my plugins working... well is annoying!
Just to clarify: I would like to include all base style rules needed for the widgets proper/base functionality to be included inside the script. The user would easily modify the base look of the widget by writing a style rule in their own style sheet.
Example:
Instead of having to look through all the base styles trying to find the font color like this... .slider {display: inline-block; color: #000; someotherconfusingrule : blahblah; }
The user simply starts a new rule with the classes name/selector being used - and then just write the changes to make to the default script styles
They would just write
.slider {color: #000};
Thanks for the help in advance SO!
Nice question! Although I'm not sure what the preferred solution to this would be, I was thinking of the following approach:
Use a IIFE to define your jQuery plugin and enable you to define some private, global variables and functions.
$.fn.pluginName = (function() {
return function() {
...your regular plugins code...
};
}();
Define your plugins CSS as a list of style rules in your plugins code
var rules = [
'.box {' +
' width: 100px;' +
' background-color: #f99;' +
' margin: 10px;' +
' padding: 10px;' +
' font-family: Helvetica, Arial;' +
' text-align: center;' +
'}'
];
Create a private variable that remembers if your stylesheet has already been added to the document
var styleSheetExists = false;
Create a private function that creates a stylesheet using the style rules above and that adds it as the first <style> element in the <head> allowing the user to override styles in their own CSS. See http://davidwalsh.name/add-rules-stylesheets for a good tutorial on how to do this properly
var createStyleSheet = function() {
var style = document.createElement("style");
style.appendChild(document.createTextNode(""));
$('head').prepend(style);
for (var i = 0; i < rules.length; i++) {
style.sheet.insertRule(rules[i], i);
}
};
The first time your plugin is applied to an element check if the stylesheet has already been created and if not create the stylesheet.
var $elements = $(this);
if (!styleSheetExists) {
createStyleSheet();
styleSheetExists = true;
}
$elements.each(function() {
$(this).addClass('box');
});
return $elements;
See http://codepen.io/ckuijjer/pen/FkgsJ for this example. It creates a jQuery plugin called box which simply adds the class box to an element. The class box has a default pink background color defined in its stylesheet which gets overridden by a user defined blue background color.
But please do make this configurable in your jQuery plugin. You want to enable developers to bundle all their css, including your plugins, to optimize resource delivery to the client. Plus injecting stylesheets might be a small performance hit.
It may seem annoying but separating the model, view, and controller is the correct way. You're using jQuery so why not consider how jQuery would approach the situation: a jQuery UI widget like the Accordion comes with several stylesheets, the most important being the base stylesheet and a separate 'theme' stylesheet that (if done correctly) is nondestructive and can be modified without risking the integrity of the widget. You may also want to consider how your favorite plugins are authored and what makes them appeal to you. It's my personal opinion CSS should never be present in JavaScript files however if you've made up your mind, the solution #ckuijjer provided is sound. Hope this helps!

have element change appreance with only javascript and CSS

attempting to have my webpage be a bit more dynamic by having the background change on some elements when a checkbox is clicked. I am trying to do this via class change and a CSS sheet. I have the following which is kicking out an error that my onclick function ins not defined (in IE9). More importantly will the webpage update if I only change the class of the object which would have a different class in the CSS file. Whats a better alternative if this does not work?
my elemenet and function
UPDATE
I made updates to both my HTML and CSS file as suggested by many. I am still getting no change in my webpage but the console is claiming that my function called from the onclick event is not defined which is a bit odd since it is. Also does this type for scripting belong in the HTML or should I pull it out and put in a seperate file. I figured since it was creating elements it belongs in the main html. Is there a cleaner more compact way of accomplishing this and not making my home screen html huge?
<tr class= 'tr.notchosen'><td><input type='checkbox' onclick='handleClick(this.id)'/></td></tr>
function handleClick(cb) {
var currentColumn = cb.parentNode
var currentRow = currentColumn.parentNode
if (currentRow.className === "chosen")
{
currentRow.className = "notchosen";
}
else
{
currentRow.className = "chosen";
}
}
and my css file is the following
tr.chosen
{
background-color:rgba(255,223,0,0.75);
}
tr.notchosen
{
background-color:rgba(255,223,0,0);
}
There are a couple of things going on here. First, your css selector is not quite right. In fact, I would suggest making the class name just "chosen" or "not chosen" and then selecting tr elements with that class.
<tr class='notchosen'>
And then you can target it from css (which was probably the original intention)
tr.notchosen
{
background-color:rgba(255,223,0,0);
}
Further, although I would not suggest using inline javascript, using your example, you should pass this if you want to work with the element and not this.id which would pass a string.
onclick='handleClick(this)'
The last part would be to sync up your javascript with the class name change
if (currentRow.className == "chosen")
{
currentRow.className = "notchosen";
}
else
{
currentRow.className = "chosen";
}

turn off css sheet on specific page

I'm new to jquery and I'm trying to turn off a specific css sheet when a specific page loads. This is the code that I've been using and I'm not sure that it is correct.
if(location.pathname=="/mycart") >= 0){
$('link[rel=stylesheet][src~="/media/css/responsive.css"]').remove();
}
The problem might be that path name check... also, instead of removing, try disabling the stylesheet:
if (location.pathname.indexOf('/mycart') >= 0) {
$('link[href*="/media/css/responsive.css"]').prop('disable', true);
}
Edit: The ~= selector looks for a space deliminated word, so use the *= selector instead.
Update (full code)
<script>
$(function () {
if (location.pathname.indexOf('/mycart') >= 0) {
$('link[href*="/media/css/responsive.css"]').prop('disable', true);
}
});
</script>
Instead of complicating things with on the fly style-sheets "canceling" why don't you simply create a wrapper class around objects that change on your page and define two sets of selectors that apply in case the wrapper does or does not have a specific class.
Lets say this is your HTML code.
<div class="my_cart">
<!-- Lots of shiny elements defined inside your cart... -->
</div>
Now you simply add two sets of stylesheets depending on how you actually want to style your cart in different situations.
.my_cart input {
...
}
.my_cart p {
...
}
/* The following two selectors will be applied to .my_cart ONLY if it also has the .disabled class assigned to it. */
.my_cart.disabled input {
...
}
.my_cart.disabled p {
...
}
Now all you have to do is following.
$(document).ready(function(){
if(location.pathname == "/mycart"){
$('.my_cart').addClass('.disabled');
}
});
Simple as that.

Changing content CSS on the run in TinyMCE or CKEditor

I have a form in which I want to edit a HTML template. It has 2 textareas, one for the HTML and another one for the CSS.
I'd like to use either TinyMCE or CKEditor for the HTML textarea.
Is there any way to change the content CSS in either of them to match the CSS in the CSS textarea on the run, so when I change the CSS it is automatically loaded into the editor?
Thanks.
I have no experience with CKEditor, but i know that it is possible with TinyMce. What you need to do is to write an own plugin which will provide the necessary functionality.
OnNodeChange in the 2nd textarea (the one with your css) you need to update the head of the first editors iframe. This code snippet to be executed on a special action (for example onNodeChange) should point you into the right direction:
var DEBUG = false;
var css_code = tinymce.editors[1].getContent(); // get content of 2nd editorinstance on page (your css)
iframe_id = tinymce.editors[0].id+'_ifr';
with(document.getElementById(iframe_id).contentWindow){
var h=document.getElementsByTagName("head");
if (!h.length) {
if (DEBUG) console.log('length of h is null');
return;
}
var newStyleSheet=document.createElement("style");
newStyleSheet.type="text/css";
h[0].appendChild(newStyleSheet);
try{
if (typeof newStyleSheet.styleSheet !== "undefined") {
newStyleSheet.styleSheet.cssText = css_code;
}
else {
newStyleSheet.appendChild(document.createTextNode(css_code));
newStyleSheet.innerHTML=css_code;
}
}
Be aware that this code will add a new style sheet everytime it is called - yielding in increasing the editor iframes head. So i think best practice is to clean up the last inserted style before appliing the new one. Removing the last Node of the head shozld be sufficient.

Categories