I have a two radio controls that are designed as buttons. When I click the first radio button, then second one's background color should change and vice versa.
HTML:
<input type="radio" id="boo1" name="boo" value="boo1"><label for="boo1"><span></span>boo1</label>
<input type="radio" id="boo2" name="boo" value="boo2"><label for="boo2"><span></span>boo2</label>
CSS:
body {
font-family: open sans, arial, sans-serif;
color: #ffffff;
margin: 0;
background: #3894db;
}
input[type="radio"] {
display: none;
}
input[type="radio"] + label {
cursor: pointer;
width: 50%;
height: auto;
font-size: 22px;
margin-top: 10px;
float: left;
color: #ffffff;
text-align: center;
vertical-align: middle;
padding-top: 2px;
padding-bottom: 2px;
}
/* boo1 */
#boo1 + label {
background: #e74c3c;
}
#boo1:checked + label {
background: #c0392b;
}
/* boo2 */
#boo2 + label {
background: #f1c40f;
}
#boo2:checked + label {
background: #f39c12;
}
JavaScript?
$(document).ready(function() {
$("#boo1").click(function () {
});
});
if($('#boo1').is(':checked'))
{
$('#boo2').css('color','#ff0000');
}
If you want the buttons to have different background colors when "inactive", you can use jQuery's css() function, like this:
$(document).ready(function () {
$("#boo1").click(function () {
$("#boo1 + label").css("background-color", "#c0392b");
$("#boo2 + label").css("background-color", "green");
});
$("#boo2").click(function () {
$("#boo2 + label").css("background-color", "#f39c12");
$("#boo1 + label").css("background-color", "blue");
});
});
See working jsFiddle.
try the following code
$("#boo1").click(function (event) {
$("#boo2").prop( "checked",true );
});
$("#boo2").click(function (event) {
$("#boo1").prop( "checked",true );
});
Try to use this javascript code
$(document).ready(function () {
$("input[name='boo']").click(function () {
$(this).next().removeAttr('style');
$("input[name='boo']").not(this).next().css('background-color', 'green');
});
});
try this way
HTML CODE:
<label for="boo1"><span><input type="radio" id="boo1" name="boo" value="boo1" /></span>boo1</label>
<label for="boo2"><span><input type="radio" id="boo2" name="boo" value="boo2" /></span>boo2</label>
JQUERY CODE:
$('input[type=radio]').on('click', function () {
$('input[type=radio]').not(this).closest('label').css('background', 'blue');
$(this).closest('label').css('background', 'red');
});
LIVE DEMO:
Happy Coding :)
http://jsfiddle.net/dreamweiver/py2BM/14/
You can achieve that with pure CSS
/* boo1 */
#boo1 + label {
background: #e74c3c;
}
#boo1:checked ~ label[for="boo2"] {
background: #c0392b;
}
#boo1:checked ~ label[for="boo1"]{
background: #f39c12;
}
/* boo2 */
#boo2 + label {
background: #f1c40f;
}
#boo2:checked ~ label[for="boo1"] {
background: #f39c12;
}
working demo:http://jsfiddle.net/HarishBoke/S6z8Z/
Hope this is what you are looking for!
Simple and optimized solution:
HTML Code:
<!-- Fieldset Wrap: begins -->
<div class="fieldset-wrap">
<!-- Fieldset: begins -->
<span class="fieldset orange">
Label 1
</span>
<!-- Fieldset: ends -->
<!-- Fieldset: begins -->
<span class="fieldset green">
Label 2
</span>
<!-- Fieldset: ends -->
</div>
<!-- Fieldset Wrap: ends -->
CSS:
.fieldset-wrap {
overflow: hidden;
font-size:0px;
}
.fieldset {
display: inline-block;
width: 200px;
padding: 5px 0;
text-align: center;
cursor: pointer;
font-family: verdana;
font-size: 14px;
}
.fieldset { margin-left: 1px; }
.fieldset:first-child { margin-left: 0px; }
.orange,
.green,
.checked{ color: #fff; }
.orange { background-color : orange; }
.green { background-color : green; }
.checked { background-color : blue; }
jQuery:
$('.fieldset').on('click', function(){
$(this)
.addClass('checked')
.siblings()
.removeClass('checked');
});
DEMO
Related
I am trying to change the background color of my webpage using a hamburger menu. There are 4 color options on my hamburger menu. I managed to get a change on the background when clicking on the color of my choice. But that change only happens once. When I clicked another color and come back to click that same color from earlier on, it doesn't respond. The color seems to change only once, and not more than that.
The repository to my GitHub code is here: https://github.com/tand100b/Winc_Academy
const changeColorButton1 = document.getElementById("color1");
changeColorButton1.addEventListener("click", function() {
changeClassRedBackground();
});
const changeColorButton2 = document.getElementById("color2");
changeColorButton2.addEventListener("click", function() {
changeClassOrangeBackground();
});
const changeColorButton3 = document.getElementById("color3");
changeColorButton3.addEventListener("click", function() {
changeClassPurpleBackground();
});
const changeColorButton4 = document.getElementById("color4");
changeColorButton4.addEventListener("click", function() {
changeClassGreenBackground();
});
const changeClassRedBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("red-background");
}
const changeClassOrangeBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("orange-background");
};
const changeClassPurpleBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("purple-background");
};
const changeClassGreenBackground = function() {
const bodyElement = document.body;
bodyElement.classList.add("green-background");
};
body {
background-color: pink;
}
.red-background {
background-color: red;
}
.orange-background {
background-color: orange;
}
.purple-background {
background-color: purple;
}
.green-background {
background-color: green;
}
.btn-toggle-nav {
width: 60px;
height: 20%;
background-color: #f98f39;
background-image: url("https://i.stack.imgur.com/tniUv.png");
background-repeat: no-repeat;
background-size: 60%;
background-position: center;
cursor: pointer;
}
.btn-toggle-nav:hover {
opacity: 0.5;
}
.navbar ul {
padding-top: 15px;
/* visibility: hidden; */
}
.navbar ul li {
line-height: 60px;
list-style: none;
background-color: white;
width: 300px;
padding-top: 0px;
padding-top: 0px;
}
.navbar ul li a {
display: block;
height: 60px;
padding: 0 10px;
text-decoration: none;
font-family: arial;
font-size: 16px;
}
.navbar {
background-color: red;
width: 50px;
padding: 0 5px;
height: calc(100vh-60px);
z-index: 1000;
}
.list {
margin-top: 0px;
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<div class="btn-toggle-nav"></div>
<aside class="navbar">
<ul class="list">
<li><a id="color1" href="#">Red</a></li>
<li><a id="color2" href="#">Orange</a></li>
<li><a id="color3" href="#">Purple</a></li>
<li><a id="color4" href="#">Green</a></li>
</ul>
</aside>
Can someone please look at my code and suggest what I can do?
Firstly, I suggest declaring variable bodyElement only once at the top of the file because each time it would be the same body element:
const bodyElement = document.body
Next, we create function that will check if body has any style classes in its classList. If it's not empty (length more than one) we remove all classes, and do nothing otherwise:
const isBodyHasStyle = () => bodyElement.classList.length ? bodyElement.classList = '' : null
Then, on each button click we going to call our new function:
changeColorButton1.addEventListener("click", function() {
isBodyHasStyle()
changeClassRedBackground();
});
Do the same with other buttons.
You need to make sure that you don't have multiple classes conflicting with each other, also try to DRY your code, here is an alternative I came up with:
const changeColor = (e) => {
const bodyElement = document.querySelector('body');
const colorIdMap = {
"color1": "red-background",
"color2": "orange-background",
"color3": "purple-background",
"color4": "green-background"
}
bodyElement.className = colorIdMap[e.target.id];
}
const btns = document.querySelectorAll('.list li');
btns.forEach(btn => btn.addEventListener('click', changeColor))
An easier way to accomplish this is by setting a data attribute on the background, based on the selected color. Just add a color data value to each of the menu items and set the body background to that color.
const toggleMenu = (event) => {
event.target.closest('.navbar').classList.toggle('open');
};
const changeColor = (event) => {
document.body.dataset.background = event.target.dataset.color;
toggleMenu(event); /* do not call ~ to stay open */
};
document.querySelector('.btn-toggle-nav')
.addEventListener('click', toggleMenu)
document.querySelectorAll('.color-picker')
.forEach(e => e.addEventListener('click', changeColor));
/* CSS reset */
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
body { display: flex; background-color: #222; }
ul { list-style-type: none; margin: 0; }
body[data-background="red"] { background-color: red }
body[data-background="orange"] { background-color: orange }
body[data-background="purple"] { background-color: purple }
body[data-background="green"] { background-color: green }
body[data-background="default"] { /* Do not set the background-color */ }
a[data-color="red"] { color: red; }
a[data-color="orange"] { color: orange; }
a[data-color="purple"] { color: purple; }
a[data-color="green"] { color: green; }
a[data-color="default"] { color: #222; }
.list {
position: absolute;
display: none; /* hide menu (default) */
flex-direction: column;
gap: 0.5em;
padding: 0.5em;
width: 6em;
left: 2em;
background: #444;
}
.list li a { text-decoration: none; font-weight: bold; }
.list li a:hover { text-decoration: underline; }
.navbar {
position: relative;
width: 2em;
background-color: #444;
}
.navbar.open .list {
display: flex; /* show menu */
}
.btn-toggle-nav {
width: 2em;
height: 2em;
background-image: url("https://i.stack.imgur.com/tniUv.png");
background-repeat: no-repeat;
background-size: 60%;
background-position: center;
cursor: pointer;
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<aside class="navbar">
<div class="btn-toggle-nav"></div>
<ul class="list">
<li><a class="color-picker" href="#" data-color="red">Red</a></li>
<li><a class="color-picker" href="#" data-color="orange">Orange</a></li>
<li><a class="color-picker" href="#" data-color="purple">Purple</a></li>
<li><a class="color-picker" href="#" data-color="green">Green</a></li>
<li><a class="color-picker" href="#" data-color="default">Default</a></li>
</ul>
</aside>
I have the following functional code. However, I would like to know how I can disable toggle buttons. I always want to have one of my bottom navbar icons active and its respective content should be shown in the main section. If I click on the active navbar icon (the toggle) it wouldn't be deactivated.
Thanks in advance for your help!
$(document).ready(function() {
// only show menu-1
$('.menu-1').click(function() {
if ($('.menu-2, .menu-3').hasClass('active')) {
$('.menu-2, .menu-3').removeClass('active');
$('.content-2, .content-3').removeClass('active');
}
$('.menu-1').toggleClass('active');
$('.content-1').toggleClass('active');
});
// only show menu-2
$('.menu-2').click(function() {
if ($('.menu-1, .menu-3').hasClass('active')) {
$('.menu-1, .menu-3').removeClass('active');
$('.content-1, .content-3').removeClass('active');
}
$('.menu-2').toggleClass('active');
$('.content-2').toggleClass('active');
});
// only show menu-3
$('.menu-3').click(function() {
if ($('.menu-2, .menu-1').hasClass('active')) {
$('.menu-2, .menu-1').removeClass('active');
$('.content-2, .content-1').removeClass('active');
}
$('.menu-3').toggleClass('active');
$('.content-3').toggleClass('active');
});
});
.container {
margin: 0 auto;
background-color: #eee;
border: 1px solid lightgrey;
width: 20vw;
height: 90vh;
font-family: sans-serif;
position: relative;
}
header {
background-color: lightgreen;
padding: 5px;
text-align: center;
text-transform: uppercase;
}
.bottom-navbar {
position: absolute;
bottom: 0;
width: 100%;
padding: 6px 0;
overflow: hidden;
background-color: lightgreen;
border-top: 1px solid var(--color-grey-dark-3);
z-index: 50;
display: flex;
justify-content: space-between;
> a {
display: block;
color: green;
text-align: center;
text-decoration: none;
font-size: 20px;
padding: 0 10px;
&.active {
color: black;
}
}
}
.menu-1.active,
.menu-2.active,
.menu-3.active {
color: black;
}
.content-1,
.content-2,
.content-3 {
display: none;
}
.content-1.active,
.content-2.active,
.content-3.active {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
<div class="container">
<header>My header</header>
<div class="main-content">
<div class="content-1">House content</div>
<div class="content-2">Map content</div>
<div class="content-3">Explore content</div>
<div class="bottom-navbar">
<i class="fa fa-home"></i>
<i class="fa fa-map"></i>
<i class="fa fa-search"></i>
</div>
</div>
If you find it easier, here's my CodePen: https://codepen.io/fergos2/pen/vYYaRzN
You can use this jQuery code. Anyone can enhance that.
$(document).ready(function() {
$('.bottom-navbar a').click(function(){
var cls = $(this).attr('class');
var lastchr = cls.substr(cls.length - 1);
$(this).siblings('a').removeClass('active');
$(this).addClass('active');
$("div[class^='content-'],div[class*=' content-']").removeClass('active');
$('.content-'+ lastchr).addClass('active');
})
});
Instead of toggleClass() you could use addClass():
https://codepen.io/vladanme/pen/LYYBrqJ
$(document).ready(function() {
// only show menu-1
$('.menu-1').click(function() {
if ($('.menu-2, .menu-3').hasClass('active')) {
$('.menu-2, .menu-3').removeClass('active');
$('.content-2, .content-3').removeClass('active');
}
$('.menu-1').addClass('active');
$('.content-1').addClass('active');
});
// only show menu-2
$('.menu-2').click(function() {
if ($('.menu-1, .menu-3').hasClass('active')) {
$('.menu-1, .menu-3').removeClass('active');
$('.content-1, .content-3').removeClass('active');
}
$('.menu-2').addClass('active');
$('.content-2').addClass('active');
});
// only show menu-3
$('.menu-3').click(function() {
if ($('.menu-2, .menu-1').hasClass('active')) {
$('.menu-2, .menu-1').removeClass('active');
$('.content-2, .content-1').removeClass('active');
}
$('.menu-3').addClass('active');
$('.content-3').addClass('active');
});
});
Use addClass() instead of toggleClass().
It looks like you have the code to clear the inactive buttons already. So you're only left with the button that you would like to maintain active.
[..]
$('.menu-1').addClass('active');
$('.content-1').addClass('active');
[..]
[..]
$('.menu-2').addClass('active');
$('.content-2').addClass('active');
[..]
[..]
$('.menu-3').addClass('active');
$('.content-3').addClass('active');
[..]
So far I managed to make this working fiddle. My problem now is that after I press enter to send the data to the server, i need to disable the edit on the current input and pass the focus to the next.
Also does anyone have any idea how do I make that text bliking thing in the project? https://bootsnipp.com/snippets/yNgQ1
PS: you need to press enter to start the console
var terminal = $('#terminal');
$(document).keypress(function(e) {
if (e.which === 13) {
e.preventDefault();
var stdin = $('.stdin').last().text();
console.log(stdin);
consoleInteration(stdin);
}
});
function consoleInteration(stdin) {
//RESULT FROM AJAX POST
result = "This is the output from the shell";
terminal.append('<br><div class="static">' + result + '</div><br>');
terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>');
terminal.append('<div class="stdin" id="stdin" contenteditable="true"></div>');
}
.terminal {
width: 100%;
padding: 4px;
background-color: black;
opacity: 0.7;
height: 650px;
color: #fff;
font-family: 'Source Code Pro', monospace;
font-weight: 200;
font-size: 14px;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
overflow-y: auto;
}
.terminal div {
display: inline-block;
}
.terminal .static {
color: #5ed7ff;
font-weight: bold;
}
.console-arrow {
color: #bde371;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="terminal" class="terminal">
</div>
You can disable edition by doing :
$('.stdin').last().removeAttr("contenteditable")
Then append the next line :
terminal.append('<div class="stdin" id="stdin" contenteditable="true"></div>')
Then select the last (newly added) line and set focus on it :
$('.stdin').last().focus()
What you need
First, .attr(): this allow you to change the contenteditable attribute (true/false).
Secondly .focus(): focus the desired element (just get the last .stdin with .last()).
Handling the cursor
In your div (the one that works like an input), you will make the text color as transparent with color: transparent, this way you will hide the cursor.But you need the text to show, so you will add text-shadow to help: text-shadow: 0 0 0 black.
To create the cursor, you will need one <div> after the other with editable content.
With everything set, you make use of .setInterval() with .css() to change the visibility and, at every change, .remove() the last cursor <div>.
var terminal = $('#terminal');
window.setInterval(function () {
if ($('#cursor').css('visibility') === 'visible') {
$('#cursor').css({
visibility: 'hidden'
});
} else {
$('#cursor').css({
visibility: 'visible'
});
}
}, 500);
$(document).keypress(function(e) {
if (e.which === 13) {
e.preventDefault();
var stdin = $('.stdin').last().text();
console.log(stdin);
consoleInteration(stdin);
}
});
function consoleInteration(stdin) {
$("#cursor").remove();
$(".stdin").last().attr("contenteditable", "false");
//RESULT FROM AJAX POST
result = "This is the output from the shell";
terminal.append('<br><div class="static">' + result + '</div><br>');
terminal.append('<div class="static"><span class="fa fa-arrow-right console-arrow"></span> ~ </div>');
terminal.append('<div class="stdin" id="stdin" contenteditable="true"></div>');
terminal.append('<div id="cursor"></div>');
$(".stdin").last().focus();
}
.terminal {
width: 100%;
padding: 4px;
background-color: black;
opacity: 0.7;
height: 650px;
color: #fff;
font-family: 'Source Code Pro', monospace;
font-weight: 200;
font-size: 14px;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
overflow-y: auto;
}
.terminal div {
display: inline-block;
}
.terminal .static {
color: #5ed7ff;
font-weight: bold;
}
.console-arrow {
color: #bde371;
}
.stdin{
color: transparent;
text-shadow: 0 0 0 white;
}
#cursor {
top: 10px;
width: 7px;
height: 15px;
margin-bottom: 0;
background: #5ed7ff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="terminal" class="terminal">
</div>
How do I make 2 divs (header and sub-header) change color when div (change) is pressed?
The sub-header is going to be changed to another color, not the same color as header.
<div class="change">
Click this to change the background-color of the 2 headers.
</div>
<div class="header>
Header
</div>
<div class="sub-header">
sub-header
</div>
You could approach it like this...
Create a new class for each new background color you'd like:
.header {
background: grey;
}
.header-alt {
background: lightblue;
}
.sub-header {
background: lightblue;
}
.sub-header-alt {
background: grey;
}
Then use jQuery toggleClass to add/remove those classes on click of the div change
$(".change").click(function() {
$('.header').toggleClass("header-alt");
$('.sub-header').toggleClass("sub-header-alt");
});
Example
$(".change").click(function() {
$('.header').toggleClass("header-alt");
$('.sub-header').toggleClass("sub-header-alt");
});
body {
width: 600px;
margin: 0 auto;
color: #FFF;
font-family: sans-serif;
font-size: 20px;
}
div {
padding: 20px;
}
.change {
background: black;
cursor: pointer;
}
.header {
background: grey;
}
.header-alt {
background: lightblue;
}
.sub-header {
background: lightblue;
}
.sub-header-alt {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="change">
Click this to change the background-color of the 2 headers
</div>
<div class="header">
Header
</div>
<div class="sub-header">
sub-header
</div>
Codepen if you prefer...
Onclick of div.change assign background-color to other divs $('.header').css("background-color","red");
$('.change').on('click',function(){
$('.header').css("background-color","red");
$('.sub-header').css("background-color","red");
})
Demo : https://jsfiddle.net/y5tLzbsc/
you give both of them the class 'active'
and on your css
.header.active{
background:blue;
}
.sub-header.active{
background:red;
}
and on your js:
document.querySelector('.change').onclick = function(){
document.querySelector('.header').className += " active";
document.querySelector('.sub-header').className += " active";
}
Here is a code snippet that does exactly what you described. This solution is using jquery. Look at the code below and feel free to ask if something is not clear :)
var colorChanged = false;
$('.change').click(function() {
if(!colorChanged){
$('.header').css('background-color','red');
$('.sub-header').css('background-color','blue');
colorChanged = true;
} else {
$('.header').css('background-color','transparent');
$('.sub-header').css('background-color','transparent');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="change">
Click this to change the background-color of the 2 headers.
</div>
<div class="header">
Header
</div>
<div class="sub-header">
sub-header
</div>
Just add an event listener. See demo:
document.addEventListener('click', function(e) {
if (e.target.className.indexOf('change') > -1) {
var headerEl = document.querySelector(".header");
var subHeaderEl = document.querySelector(".sub-header");
// This will toggle the color change on or off after each click
if (headerEl.className.indexOf('color') > -1) {
headerEl.className = headerEl.className.replace(" color", "");
subHeaderEl.className = subHeaderEl.className.replace(" color", "");
} else {
headerEl.className += " color";
subHeaderEl.className += " color";
}
}
})
.header.color {
background-color: red;
}
.sub-header.color {
background-color: blue;
}
<div class="change">
Click this to change the background-color of the 2 headers.
</div>
<div class="header">
Header
</div>
<div class="sub-header">
sub-header
</div>
This can be done with HTML and CSS. There is no need to use anything advanced or exotic.
The checkbox becomes the click input and it is hidden off screen. Since a connected label acts as the checkbox it becomes your input button. The label is the replacement for your original top DIV.
body {
margin: 0;
padding: 0;
}
#hidden_checkbox {
display: block;
position: absolute;
top: -50px;
right: 0;
}
#visible_label {
display: block;
height: 200px;
cursor: pointer;
background-color: rgb(200, 200, 200);
}
#hidden_checkbox:checked ~ div:nth-of-type(1) {
background-color: rgb(0, 50, 0);
}
#hidden_checkbox:checked ~ div:nth-of-type(2) {
background-color: rgb(0, 0, 50);
}
.header {
height: 200px;
background-color: rgb(0, 128, 128);
}
.sub-header {
height: 200px;
background-color: rgb(128, 0, 128);
}
<input id="hidden_checkbox" type="checkbox">
<label id="visible_label" for="hidden_checkbox">Click this to change the background-color of the 2 headers.</label>
<div class="header">Header</div>
<div class="sub-header">Sub-header</div>
I'm having quite a bit of trouble while trying to use CKEditor's drag and drop integration.
At first, dragging and dropping into the editor works allright with dataTransfer and all. But whenever I have to destroy and recreate an instance of the editor, dragging and dropping content stops working as expected.
I have modified the sample code directly from CKEditor's SDK page about DnD integration, where you can see the issue being reproduced.
(I just reduced the example as to make it more succint and added the "Destroy and recreate" button at the bottom of the list.)
Could not get it to work in JSFiddle, so sorry about that, but here's the code:
'use strict';
var CONTACTS = [{
name: 'Huckleberry Finn',
tel: '+48 1345 234 235',
email: 'h.finn#example.com',
avatar: 'hfin'
}, {
name: 'D\'Artagnan',
tel: '+45 2345 234 235',
email: 'dartagnan#example.com',
avatar: 'dartagnan'
}];
CKEDITOR.disableAutoInline = true;
CKEDITOR.plugins.add('drag_list', {
requires: 'widget',
init: function(editor) {
editor.widgets.add('drag_list', {
allowedContent: true,
pathName: 'drag_list',
upcast: function(el) {
return el.name == 'table' && el.hasClass('product_widget');
}
});
editor.addFeature(editor.widgets.registered.drag_list);
editor.on('paste', function(evt) {
var contact = evt.data.dataTransfer.getData('contact');
if (!contact) {
return;
}
evt.data.dataValue =
'<span class="h-card">' +
'' + contact.name + '' +
' ' +
'<span class="p-tel">' + contact.tel + '</span>' +
'</span>';
});
}
});
CKEDITOR.document.getById('contactList').on('dragstart', function(evt) {
var target = evt.data.getTarget().getAscendant('div', true);
CKEDITOR.plugins.clipboard.initDragDataTransfer(evt);
var dataTransfer = evt.data.dataTransfer;
dataTransfer.setData('contact', CONTACTS[target.data('contact')]);
dataTransfer.setData('text/html', target.getText());
if (dataTransfer.$.setDragImage) {
dataTransfer.$.setDragImage(target.findOne('img').$, 0, 0);
}
});
CKEDITOR.inline('editor1', {
extraPlugins: 'drag_list,sourcedialog,justify'
});
function destroy_recreate() {
for (var instance in CKEDITOR.instances) {
console.log(CKEDITOR.instances[instance])
CKEDITOR.instances[instance].destroy();
}
CKEDITOR.inline('editor1', {
extraPlugins: 'drag_list,sourcedialog,justify'
});
}
.columns {
background: #fff;
padding: 20px;
border: 1px solid #E7E7E7;
}
.columns:after {
content: "";
clear: both;
display: block;
}
.columns > .editor {
float: left;
width: 65%;
position: relative;
z-index: 1;
}
.columns > .contacts {
float: right;
width: 35%;
box-sizing: border-box;
padding: 0 0 0 20px;
}
#contactList {
list-style-type: none;
margin: 0 !important;
padding: 0;
}
#contactList li {
background: #FAFAFA;
margin-bottom: 1px;
height: 56px;
line-height: 56px;
cursor: pointer;
}
#contactList li:nth-child(2n) {
background: #F3F3F3;
}
#contactList li:hover {
background: #FFFDE3;
border-left: 5px solid #DCDAC1;
margin-left: -5px;
}
.contact {
padding: 0 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.contact .u-photo {
display: inline-block;
vertical-align: middle;
margin-right: 10px;
}
#editor1 .h-card {
background: #FFFDE3;
padding: 3px 6px;
border-bottom: 1px dashed #ccc;
}
#editor1 {
border: 1px solid #E7E7E7;
padding: 0 20px;
background: #fff;
position: relative;
}
#editor1 .h-card .p-tel {
font-style: italic;
}
#editor1 .h-card .p-tel::before,
#editor1 .h-card .p-tel::after {
font-style: normal;
}
#editor1 .h-card .p-tel::before {
content: "(☎ ";
}
#editor1 .h-card .p-tel::after {
content: ")";
}
#editor1 h1 {
text-align: center;
}
#editor1 hr {
border-style: dotted;
border-color: #DCDCDC;
border-width: 1px 0 0;
}
<script src="http://cdn.ckeditor.com/4.5.5/standard-all/ckeditor.js"></script>
<div class="columns">
<div class="editor">
<div cols="10" id="editor1" name="editor1" rows="10" contenteditable="true">
<h3>Drop stuff here then press the Destroy/Recreate button and try again.</h3>
</div>
</div>
<div class="contacts">
<h3>List of Droppable Contacts</h3>
<ul id="contactList">
<li>
<div class="contact h-card" data-contact="0" draggable="true" tabindex="0">
<img src="http://sdk.ckeditor.com/samples/assets/draganddrop/img/hfin.png" alt="avatar" class="u-photo">Huckleberry Finn
</div>
</li>
<li>
<div class="contact h-card" data-contact="1" draggable="true" tabindex="0">
<img src="http://sdk.ckeditor.com/samples/assets/draganddrop/img/dartagnan.png" alt="avatar" class="u-photo">D'Artagnan
</div>
</li>
</ul>
<button class='destroy_recreate' onclick='destroy_recreate()'>Destroy and recreate editors</button>
</div>
</div>
Other plugins like sourcedialog and justify seem to keep working well, but drag_list does not.
Does anyone know why this is happening? What do I have to do to be able to drag and drop content such as the example's hcards in a newly created CKEditor instance?
Thanks in advance.
It looks like a nasty bug in the editor core. I checked it and reported a ticket: https://dev.ckeditor.com/ticket/14339 Until the ticket will be fixed, all I can suggest is to reattach dragstart event on the editor recreation. You can put: CKEDITOR.document.getById('contactList').on('dragstart', ... ); inside the plugin init method. After such change drag and drop should work, but dragstart will be fired multiple times. You can detach the dragstart event, before you attach it again end everything should work fine.