Replies: 21 comments
|
Hey. Smart feature. Nice 👏 |
|
I too would love to have something like this. Will try to contribute! :P |
|
+1 for this feature |
|
This is very interested feature! 😃 |
|
This is the only feature I need to start using Editor.js in my project. Tabs (vertical/horizontal) Since editor.js allows us to set our own options. You can add options for: I have also explained some of it on my post #1199 |
|
+1 from my end too please. This would be really important to have. @neSpecc Also, is it limited to 2 columns or can it be more? For eg. if I need a row with 4 columns, while the data model should remain the same making it Thanks. |
|
Is the idea to limit it to a single level? Or will it be recursive nesting? In other words, will this be possible? |
|
@oodeveloper Awesome to see this. Do you have any reference/code on how we can do this? Thanks. |
|
@tvvignesh sure, the issue is that you need to add settings to each plugin too( like Header, Quote, Image and ...)
PLUGIN: #editorjs{max-width: 650px;margin: 0 auto}
.codex-editor__redactor{display: flex;flex-wrap: wrap;flex-direction: row;}
.ce-block{width: 100%;padding-left: 0;padding-right: 0;}
.cdx-settings-input{border: 1px solid rgba(201,201,204,.48);-webkit-box-shadow: inset 0 1px 2px 0 rgba(35,44,72,.06);box-shadow: inset 0 1px 2px 0 rgba(35,44,72,.06);border-radius: 3px;padding: 3px 8px;outline: none;width: 100%;-webkit-box-sizing: border-box;box-sizing: border-box;}
.cdx-small{font-size: .6rem}
.ce-block__content{max-width: 100%}
.cdx-settings-button.disabled{pointer-events: none;opacity: .5}
.cdx-settings-sidebar{position: absolute;left: 100%;top:0;background: #fff;width: 108px;height: 145px;box-shadow: 0 3px 15px -3px rgba(13,20,33,.13);border-radius: 0 4px 4px 0;z-index: 0;}JS: // Button
class SimpleButtonField {
constructor({data, api}){
this.api = api;
this._currentWidth = 12;
this._pl = 0;
this._pr = 0;
this._pt = 0;
this._pb = 0;
this._wrapper = undefined;
this._block = undefined;
this._input = undefined;
this._settingsSidebar = undefined;
this._button = undefined;
}
static get toolbox() {
return {
title: 'Button',
icon: `<svg version="1.1" width="22" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 30" style="enable-background:new 0 0 50 30;" xml:space="preserve"><path id="XMLID_2_" class="st0" d="M45.7,0.2H5.1c-1.8,0-3.2,1.5-3.2,3.2V27c0,1.8,1.5,3.2,3.2,3.2h40.7c1.8,0,3.2-1.5,3.2-3.2V3.4 C49,1.6,47.5,0.2,45.7,0.2z M28.9,20.9l-1.2,0.8l-1.9-2.9l-3.4,2.2L20.2,8.7l10.3,6.8l-3.6,2.4L28.9,20.9z"/></svg>`
};
}
render(){
var wrapper = document.createElement('div');
var button = document.createElement('button');
wrapper.setAttribute('class','form-group');
button.setAttribute('class','btn btn-primary btn-block');
button.innerHTML = 'Button';
wrapper.appendChild(button);
this._button = button;
this._wrapper = wrapper;
return wrapper;
}
renderSettings(){
const wrapper = document.createElement('div');
let caption = document.createElement('input');
caption.classList.add('cdx-settings-input','mb-1');
caption.setAttribute("placeholder", 'Caption');
let selectClass = document.createElement('select');
selectClass.setAttribute('id','field-type');
selectClass.setAttribute("placeholder", 'Type');
selectClass.classList.add('cdx-settings-input');
selectClass.classList.add('mb-1');
const classOptions = [
{
value: '',
title: 'Class'
},
{
value: 'info',
title: 'Info'
},
{
value: 'warning',
title: 'Warning'
},
{
value: 'danger',
title: 'Danger'
},
{
value: 'success',
title: 'Success'
},
{
value: 'primary',
title: 'Primary'
}
];
classOptions.forEach( opt => {
let option = document.createElement('option');
option.setAttribute("value", opt.value);
option.innerHTML = opt.title;
selectClass.appendChild(option);
});
// inputId.innerHTML = tune.icon;
caption.addEventListener('keyup', (e) => {
this._button.innerHTML = e.target.value;
});
selectClass.addEventListener('change', (e) => {
this._button.setAttribute('class','btn btn-block btn-'+e.target.value);
});
var parent = this._wrapper.parentNode;
this._block = parent.parentNode;
// increase width
let inreaseWidthBtn = document.createElement('div');
inreaseWidthBtn.classList.add('cdx-settings-button');
inreaseWidthBtn.innerHTML = `<svg width="17" height="10" viewBox="0 0 17 10" xmlns="http://www.w3.org/2000/svg"><path d="M13.568 5.925H4.056l1.703 1.703a1.125 1.125 0 0 1-1.59 1.591L.962 6.014A1.069 1.069 0 0 1 .588 4.26L4.38.469a1.069 1.069 0 0 1 1.512 1.511L4.084 3.787h9.606l-1.85-1.85a1.069 1.069 0 1 1 1.512-1.51l3.792 3.791a1.069 1.069 0 0 1-.475 1.788L13.514 9.16a1.125 1.125 0 0 1-1.59-1.591l1.644-1.644z"/></svg>`;
wrapper.appendChild(inreaseWidthBtn);
inreaseWidthBtn.addEventListener('click', () => {
this._increaseWidth();
inreaseWidthBtn.classList.toggle('cdx-settings-button--active');
});
/// Decrease width
let decreaseWidthBtn = document.createElement('div');
decreaseWidthBtn.classList.add('cdx-settings-button');
decreaseWidthBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><path d="M-674,383.9h3.6l-1.7-1.7c-0.4-0.4-0.4-1.2,0-1.6c0.4-0.4,1.1-0.4,1.6,0l3.2,3.2c0.6,0.2,0.8,0.8,0.6,1.4 c-0.1,0.1-0.1,0.3-0.2,0.4l-3.8,3.8c-0.4,0.4-1.1,0.4-1.5,0c-0.4-0.4-0.4-1.1,0-1.5l1.8-1.8h-3.6V383.9z"/><path d="M-657,386.1h-3.6l1.7,1.7c0.4,0.4,0.4,1.2,0,1.6c-0.4,0.4-1.1,0.4-1.6,0l-3.2-3.2c-0.6-0.2-0.8-0.8-0.6-1.4 c0.1-0.1,0.1-0.3,0.2-0.4l3.8-3.8c0.4-0.4,1.1-0.4,1.5,0c0.4,0.4,0.4,1.1,0,1.5l-1.8,1.8h3.6V386.1z"/></svg>`;
wrapper.appendChild(decreaseWidthBtn);
decreaseWidthBtn.addEventListener('click', () => {
this._decreaseWidth();
decreaseWidthBtn.classList.toggle('cdx-settings-button--active');
});
// Paddings
let paddingBtn = document.createElement('div');
paddingBtn.classList.add('cdx-settings-button');
paddingBtn.innerHTML = `<svg version="1.1" height="12" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 379 17 12" style="enable-background:new -674 379 17 12;" xml:space="preserve"><rect x="-666.1" y="379.9" width="1.7" height="10.3"/><polygon points="-657,384.2 -659.9,384.2 -658.8,383.1 -660,381.9 -663.1,385 -660,388.1 -658.8,386.9 -659.9,385.8 -657,385.8 "/><rect x="-671.9" y="379.9" width="4.1" height="1.7"/><rect x="-674" y="384.2" width="6.1" height="1.7"/><rect x="-671.9" y="388.4" width="4.1" height="1.7"/></svg>`;
wrapper.appendChild(paddingBtn);
paddingBtn.addEventListener('click', (e) => {
if(e.target.classList.contains('cdx-settings-button--active')){
this._settingsSidebar.remove();
e.target.classList.remove('cdx-settings-button--active');
} else {
e.target.classList.add('cdx-settings-button--active');
let paddingWrapper = document.createElement('div');
paddingWrapper.classList.add('cdx-settings-sidebar');
// buttons
// Left
let paddingLeftBtn = document.createElement('span');
paddingLeftBtn.classList.add('cdx-settings-button','disabled');
paddingLeftBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><polygon points="-659,384.1 -667.8,384.1 -665.8,381.9 -667,380.7 -671,384.9 -667.1,388.9 -665.8,387.7 -667.8,385.7 -659,385.7 "/></svg>`;
paddingWrapper.appendChild(paddingLeftBtn);
let paddingLeftPlusBtn = document.createElement('span');
paddingLeftPlusBtn.classList.add('cdx-settings-button');
paddingLeftPlusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingLeftPlusBtn);
paddingLeftPlusBtn.addEventListener('click', (e) => {
this._increasePadding('l');
});
let paddingLeftMinusBtn = document.createElement('span');
paddingLeftMinusBtn.classList.add('cdx-settings-button');
paddingLeftMinusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingLeftMinusBtn);
paddingLeftMinusBtn.addEventListener('click', (e) => {
this._decreasePadding('l');
});
// Right
let paddingRightBtn = document.createElement('span');
paddingRightBtn.classList.add('cdx-settings-button','disabled');
paddingRightBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 380 17 10" style="enable-background:new -674 380 17 10;" xml:space="preserve"><polygon points="-671,385.7 -662.2,385.7 -664.2,387.7 -662.9,388.9 -659,384.9 -663,380.7 -664.2,381.9 -662.2,384.1 -671,384.1 "/></svg>`;
paddingWrapper.appendChild(paddingRightBtn);
let paddingRightPlusBtn = document.createElement('span');
paddingRightPlusBtn.classList.add('cdx-settings-button');
paddingRightPlusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingRightPlusBtn);
paddingRightPlusBtn.addEventListener('click', (e) => {
this._increasePadding('r');
});
let paddingRightMinusBtn = document.createElement('span');
paddingRightMinusBtn.classList.add('cdx-settings-button');
paddingRightMinusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingRightMinusBtn);
paddingRightMinusBtn.addEventListener('click', (e) => {
this._decreasePadding('r');
});
// Top
let paddingTopBtn = document.createElement('span');
paddingTopBtn.classList.add('cdx-settings-button','disabled');
paddingTopBtn.innerHTML = `<svg version="1.1" height="13" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 378.5 17 13" style="enable-background:new -674 378.5 17 13;" xml:space="preserve"><polygon points="-664.6,391 -664.6,382.2 -662.6,384.2 -661.4,382.9 -665.4,379 -669.6,383 -668.4,384.2 -666.2,382.2 -666.2,391 "/></svg>`;
paddingWrapper.appendChild(paddingTopBtn);
let paddingTopPlusBtn = document.createElement('span');
paddingTopPlusBtn.classList.add('cdx-settings-button');
paddingTopPlusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingTopPlusBtn);
paddingTopPlusBtn.addEventListener('click', (e) => {
this._increasePadding('t');
});
let paddingTopMinusBtn = document.createElement('span');
paddingTopMinusBtn.classList.add('cdx-settings-button');
paddingTopMinusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingTopMinusBtn);
paddingTopMinusBtn.addEventListener('click', (e) => {
this._decreasePadding('t');
});
// Bottom
let paddingBottomBtn = document.createElement('span');
paddingBottomBtn.classList.add('cdx-settings-button','disabled');
paddingBottomBtn.innerHTML = `<svg version="1.1" height="13" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 378.5 17 13" style="enable-background:new -674 378.5 17 13;" xml:space="preserve"><polygon points="-666.2,379 -666.2,387.8 -668.4,385.8 -669.6,387 -665.4,391 -661.4,387.1 -662.6,385.8 -664.6,387.8 -664.6,379 "/></svg>`;
paddingWrapper.appendChild(paddingBottomBtn);
let paddingBottomPlusBtn = document.createElement('span');
paddingBottomPlusBtn.classList.add('cdx-settings-button');
paddingBottomPlusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-664.7,388.5 -664.7,381.5 -666.3,381.5 -666.3,388.5 "/><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingBottomPlusBtn);
paddingBottomPlusBtn.addEventListener('click', (e) => {
this._increasePadding('b');
});
let paddingBottomMinusBtn = document.createElement('span');
paddingBottomMinusBtn.classList.add('cdx-settings-button');
paddingBottomMinusBtn.innerHTML = `<svg version="1.1" height="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-674 381.5 17 7" style="enable-background:new -674 381.5 17 7;" xml:space="preserve"><polygon points="-669,385.8 -662,385.8 -662,384.2 -669,384.2 "/></svg>`;
paddingWrapper.appendChild(paddingBottomMinusBtn);
paddingBottomMinusBtn.addEventListener('click', (e) => {
this._decreasePadding('b');
});
// buttons - end
wrapper.appendChild(paddingWrapper);
this._settingsSidebar = paddingWrapper;
}
});
wrapper.appendChild(caption);
wrapper.appendChild(selectClass);
return wrapper;
}
_increaseWidth(){
this._block.classList.remove('col-'+this._currentWidth);
if(this._currentWidth < 12){
this._currentWidth = this._currentWidth + 1;
}
this._block.classList.add('col-'+this._currentWidth);
}
_decreaseWidth(){
this._block.classList.remove('col-'+this._currentWidth);
if(this._currentWidth > 2){
this._currentWidth = this._currentWidth - 1;
}
this._block.classList.add('col-'+this._currentWidth);
}
_increasePadding(direction = 'l'){
var amount = 0;
if(direction == 'l'){
amount = this._pl;
} else if(direction == 'r'){
amount = this._pr;
} else if(direction == 't'){
amount = this._pt;
} else if(direction == 'b'){
amount = this._pb;
}
this._block.classList.remove('p'+direction+'-'+amount);
if(amount < 5){
if(direction == 'l'){
this._pl = this._pl + 1;
amount = this._pl;
} else if(direction == 'r'){
this._pr = this._pr + 1;
amount = this._pr;
} else if(direction == 't'){
this._pt = this._pt + 1;
amount = this._pt;
} else if(direction == 'b'){
this._pb = this._pb + 1;
amount = this._pb;
}
}
this._block.classList.add('p'+direction+'-'+amount);
}
_decreasePadding(direction = 'l'){
var amount = 0;
if(direction == 'l'){
amount = this._pl;
} else if(direction == 'r'){
amount = this._pr;
} else if(direction == 't'){
amount = this._pt;
} else if(direction == 'b'){
amount = this._pb;
}
this._block.classList.remove('p'+direction+'-'+amount);
if(amount > 0){
if(direction == 'l'){
this._pl = this._pl - 1;
amount = this._pl;
} else if(direction == 'r'){
this._pr = this._pr - 1;
amount = this._pr;
} else if(direction == 't'){
this._pt = this._pt - 1;
amount = this._pt;
} else if(direction == 'b'){
this._pb = this._pb - 1;
amount = this._pb;
}
}
this._block.classList.add('p'+direction+'-'+amount);
}
save(blockContent){
return {
url: blockContent.value
}
}
}
|
|
@oodeveloper Thanks 🙏 I will test it out and see if I can get around it. I am new to editorjs too. The minimalistic UI, clean data and good docs were what pulled me to it. Hoping to experiment a lot with it. |
|
@tvvignesh 🙏 |
|
Hey, Every current tool will work fine except table and quote tools. |
|
Other altnative tools: editor-js/awesome-editorjs#14 |
|
@hata6502 Thanks man 🙏 inline editorjs is an awesome idea.
BUT now inline editor idea can help a lot and make this work for me 🎉! |
|
@neSpecc Thanks for this issue. Appreciate if you could share a timeline for releasing this feature. We would like to use this in one of our projects. |
|
I developed a layout block tool. |
|
@hata6502 I think this is the one. Specially new column zooming in feature is awesome. Thanks man (:pray:) |
|
Hey, I have an alternative solution i have been working on Is this of use to anyone? |
|
+1 it's about time this basic feature is implement. The editor is useless for modern landing pages without that… |


Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
idto each block to saved datablockspropertylayoutproperty to saved data object.The
layoutshould describe layout scheme of Blocks by their ids. For exampleshould be described as
All reactions