Table of contents
In this post, I'm sharing a custom button for your TinyMCE Editor. If you want to add a custom button with your own styles and design then this code is the answer.
Â
Adding a custom button on TinyMCE is easy only. You just need to import custom CSS to your TinyMCE configuration, and set up a dialog with basic form input.
Â
Â
Â
This is our sample CSS code to import:
.btn {
display: inline-block;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: center;
text-decoration: none;
vertical-align: middle;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
border-radius: 0.25rem;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
.btn {
transition: none;
}
}
.btn:hover {
color: #212529;
}
.btn-check:focus + .btn, .btn:focus {
outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
.btn:disabled, .btn.disabled, fieldset:disabled .btn {
pointer-events: none;
opacity: 0.65;
}
.btn-primary {
color: #fff;
background-color: #0d6efd;
border-color: #0d6efd;
}
.btn-primary:hover {
color: #fff;
background-color: #0b5ed7;
border-color: #0a58ca;
}
.btn-check:focus + .btn-primary, .btn-primary:focus {
color: #fff;
background-color: #0b5ed7;
border-color: #0a58ca;
box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);
}
.btn-check:checked + .btn-primary, .btn-check:active + .btn-primary, .btn-primary:active, .btn-primary.active, .show > .btn-primary.dropdown-toggle {
color: #fff;
background-color: #0a58ca;
border-color: #0a53be;
}
.btn-check:checked + .btn-primary:focus, .btn-check:active + .btn-primary:focus, .btn-primary:active:focus, .btn-primary.active:focus, .show > .btn-primary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(49, 132, 253, 0.5);
}
.btn-primary:disabled, .btn-primary.disabled {
color: #fff;
background-color: #0d6efd;
border-color: #0d6efd;
}
.btn-secondary {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
.btn-secondary:hover {
color: #fff;
background-color: #5c636a;
border-color: #565e64;
}
.btn-check:focus + .btn-secondary, .btn-secondary:focus {
color: #fff;
background-color: #5c636a;
border-color: #565e64;
box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);
}
.btn-check:checked + .btn-secondary, .btn-check:active + .btn-secondary, .btn-secondary:active, .btn-secondary.active, .show > .btn-secondary.dropdown-toggle {
color: #fff;
background-color: #565e64;
border-color: #51585e;
}
.btn-check:checked + .btn-secondary:focus, .btn-check:active + .btn-secondary:focus, .btn-secondary:active:focus, .btn-secondary.active:focus, .show > .btn-secondary.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);
}
.btn-secondary:disabled, .btn-secondary.disabled {
color: #fff;
background-color: #6c757d;
border-color: #6c757d;
}
.btn-success {
color: #fff;
background-color: #198754;
border-color: #198754;
}
.btn-success:hover {
color: #fff;
background-color: #157347;
border-color: #146c43;
}
.btn-check:focus + .btn-success, .btn-success:focus {
color: #fff;
background-color: #157347;
border-color: #146c43;
box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);
}
.btn-check:checked + .btn-success, .btn-check:active + .btn-success, .btn-success:active, .btn-success.active, .show > .btn-success.dropdown-toggle {
color: #fff;
background-color: #146c43;
border-color: #13653f;
}
.btn-check:checked + .btn-success:focus, .btn-check:active + .btn-success:focus, .btn-success:active:focus, .btn-success.active:focus, .show > .btn-success.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);
}
.btn-success:disabled, .btn-success.disabled {
color: #fff;
background-color: #198754;
border-color: #198754;
}
.btn-info {
color: #000;
background-color: #0dcaf0;
border-color: #0dcaf0;
}
.btn-info:hover {
color: #000;
background-color: #31d2f2;
border-color: #25cff2;
}
.btn-check:focus + .btn-info, .btn-info:focus {
color: #000;
background-color: #31d2f2;
border-color: #25cff2;
box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);
}
.btn-check:checked + .btn-info, .btn-check:active + .btn-info, .btn-info:active, .btn-info.active, .show > .btn-info.dropdown-toggle {
color: #000;
background-color: #3dd5f3;
border-color: #25cff2;
}
.btn-check:checked + .btn-info:focus, .btn-check:active + .btn-info:focus, .btn-info:active:focus, .btn-info.active:focus, .show > .btn-info.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);
}
.btn-info:disabled, .btn-info.disabled {
color: #000;
background-color: #0dcaf0;
border-color: #0dcaf0;
}
.btn-warning {
color: #000;
background-color: #ffc107;
border-color: #ffc107;
}
.btn-warning:hover {
color: #000;
background-color: #ffca2c;
border-color: #ffc720;
}
.btn-check:focus + .btn-warning, .btn-warning:focus {
color: #000;
background-color: #ffca2c;
border-color: #ffc720;
box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);
}
.btn-check:checked + .btn-warning, .btn-check:active + .btn-warning, .btn-warning:active, .btn-warning.active, .show > .btn-warning.dropdown-toggle {
color: #000;
background-color: #ffcd39;
border-color: #ffc720;
}
.btn-check:checked + .btn-warning:focus, .btn-check:active + .btn-warning:focus, .btn-warning:active:focus, .btn-warning.active:focus, .show > .btn-warning.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);
}
.btn-warning:disabled, .btn-warning.disabled {
color: #000;
background-color: #ffc107;
border-color: #ffc107;
}
.btn-danger {
color: #fff;
background-color: #dc3545;
border-color: #dc3545;
}
.btn-danger:hover {
color: #fff;
background-color: #bb2d3b;
border-color: #b02a37;
}
.btn-check:focus + .btn-danger, .btn-danger:focus {
color: #fff;
background-color: #bb2d3b;
border-color: #b02a37;
box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);
}
.btn-check:checked + .btn-danger, .btn-check:active + .btn-danger, .btn-danger:active, .btn-danger.active, .show > .btn-danger.dropdown-toggle {
color: #fff;
background-color: #b02a37;
border-color: #a52834;
}
.btn-check:checked + .btn-danger:focus, .btn-check:active + .btn-danger:focus, .btn-danger:active:focus, .btn-danger.active:focus, .show > .btn-danger.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);
}
.btn-danger:disabled, .btn-danger.disabled {
color: #fff;
background-color: #dc3545;
border-color: #dc3545;
}
.btn-light {
color: #000;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
.btn-light:hover {
color: #000;
background-color: #f9fafb;
border-color: #f9fafb;
}
.btn-check:focus + .btn-light, .btn-light:focus {
color: #000;
background-color: #f9fafb;
border-color: #f9fafb;
box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);
}
.btn-check:checked + .btn-light, .btn-check:active + .btn-light, .btn-light:active, .btn-light.active, .show > .btn-light.dropdown-toggle {
color: #000;
background-color: #f9fafb;
border-color: #f9fafb;
}
.btn-check:checked + .btn-light:focus, .btn-check:active + .btn-light:focus, .btn-light:active:focus, .btn-light.active:focus, .show > .btn-light.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);
}
.btn-light:disabled, .btn-light.disabled {
color: #000;
background-color: #f8f9fa;
border-color: #f8f9fa;
}
.btn-dark {
color: #fff;
background-color: #212529;
border-color: #212529;
}
.btn-dark:hover {
color: #fff;
background-color: #1c1f23;
border-color: #1a1e21;
}
.btn-check:focus + .btn-dark, .btn-dark:focus {
color: #fff;
background-color: #1c1f23;
border-color: #1a1e21;
box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);
}
.btn-check:checked + .btn-dark, .btn-check:active + .btn-dark, .btn-dark:active, .btn-dark.active, .show > .btn-dark.dropdown-toggle {
color: #fff;
background-color: #1a1e21;
border-color: #191c1f;
}
.btn-check:checked + .btn-dark:focus, .btn-check:active + .btn-dark:focus, .btn-dark:active:focus, .btn-dark.active:focus, .show > .btn-dark.dropdown-toggle:focus {
box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);
}
.btn-dark:disabled, .btn-dark.disabled {
color: #fff;
background-color: #212529;
border-color: #212529;
}
Â
I'm using the bootstrap CSS style on this.
Â
Then add this editor.ui.register to your setup editor function:
editor.ui.registry.addButton('custom_button', {
text: 'Add Button',
onAction: function() {
// Open a Dialog
editor.windowManager.open({
title: 'Add custom button',
body: {
type: 'panel',
items: [{
type: 'input',
name: 'button_label',
label: 'Button label',
flex: true
},{
type: 'input',
name: 'button_href',
label: 'Button href',
flex: true
},{
type: 'selectbox',
name: 'button_target',
label: 'Target',
items: [
{text: 'None', value: ''},
{text: 'New window', value: '_blank'},
{text: 'Self', value: '_self'},
{text: 'Parent', value: '_parent'}
],
flex: true
},{
type: 'selectbox',
name: 'button_rel',
label: 'Rel',
items: [
{text: 'No value', value: ''},
{text: 'Alternate', value: 'alternate'},
{text: 'Help', value: 'help'},
{text: 'Manifest', value: 'manifest'},
{text: 'No follow', value: 'nofollow'},
{text: 'No opener', value: 'noopener'},
{text: 'No referrer', value: 'noreferrer'},
{text: 'Opener', value: 'opener'}
],
flex: true
},{
type: 'selectbox',
name: 'button_style',
label: 'Style',
items: [
{text: 'Success', value: 'success'},
{text: 'Info', value: 'info'},
{text: 'Warning', value: 'warning'},
{text: 'Error', value: 'error'}
],
flex: true
}]
},
onSubmit: function (api) {
var html = '<a href="'+api.getData().button_href+'" class="btn btn-'+api.getData().button_style+'" rel="'+api.getData().button_rel+'" target="'+api.getData().button_target+'">'+api.getData().button_label+'</a>';
// insert markup
editor.insertContent(html);
// close the dialog
api.close();
},
buttons: [
{
text: 'Close',
type: 'cancel',
onclick: 'close'
},
{
text: 'Insert',
type: 'submit',
primary: true,
enabled: false
}
]
});
}
});
Â
Here is the complete code sample of our TinyMCE Configuration:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Basic on TinyMCE with Code Sample</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="assets/plugins/tinymce/js/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
selector: 'textarea#tinymce',
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table paste codesample"
],
toolbar:
"undo redo | fontselect styleselect fontsizeselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | codesample action section button | custom_button",
content_css: ["/assets/css/custom_css_tinymce.css"],
font_formats:"Segoe UI=Segoe UI;",
fontsize_formats: "8px 9px 10px 11px 12px 14px 16px 18px 20px 22px 24px 26px 28px 30px 32px 34px 36px 38px 40px 42px 44px 46px 48px 50px 52px 54px 56px 58px 60px 62px 64px 66px 68px 70px 72px 74px 76px 78px 80px 82px 84px 86px 88px 90px 92px 94px 94px 96px",
codesample_languages: [
{text: 'HTML/XML', value: 'markup'},
{text: 'JavaScript', value: 'javascript'},
{text: 'CSS', value: 'css'},
{text: 'PHP', value: 'php'},
{text: 'Ruby', value: 'ruby'},
{text: 'Python', value: 'python'},
{text: 'Java', value: 'java'},
{text: 'C', value: 'c'},
{text: 'C#', value: 'csharp'},
{text: 'C++', value: 'cpp'}
],
height: 600,
setup: function (editor) {
editor.ui.registry.addButton('custom_button', {
text: 'Add Button',
onAction: function() {
// Open a Dialog
editor.windowManager.open({
title: 'Add custom button',
body: {
type: 'panel',
items: [{
type: 'input',
name: 'button_label',
label: 'Button label',
flex: true
},{
type: 'input',
name: 'button_href',
label: 'Button href',
flex: true
},{
type: 'selectbox',
name: 'button_target',
label: 'Target',
items: [
{text: 'None', value: ''},
{text: 'New window', value: '_blank'},
{text: 'Self', value: '_self'},
{text: 'Parent', value: '_parent'}
],
flex: true
},{
type: 'selectbox',
name: 'button_rel',
label: 'Rel',
items: [
{text: 'No value', value: ''},
{text: 'Alternate', value: 'alternate'},
{text: 'Help', value: 'help'},
{text: 'Manifest', value: 'manifest'},
{text: 'No follow', value: 'nofollow'},
{text: 'No opener', value: 'noopener'},
{text: 'No referrer', value: 'noreferrer'},
{text: 'Opener', value: 'opener'}
],
flex: true
},{
type: 'selectbox',
name: 'button_style',
label: 'Style',
items: [
{text: 'Success', value: 'success'},
{text: 'Info', value: 'info'},
{text: 'Warning', value: 'warning'},
{text: 'Error', value: 'error'}
],
flex: true
}]
},
onSubmit: function (api) {
var html = '<a href="'+api.getData().button_href+'" class="btn btn-'+api.getData().button_style+'" rel="'+api.getData().button_rel+'" target="'+api.getData().button_target+'">'+api.getData().button_label+'</a>';
// insert markup
editor.insertContent(html);
// close the dialog
api.close();
},
buttons: [
{
text: 'Close',
type: 'cancel',
onclick: 'close'
},
{
text: 'Insert',
type: 'submit',
primary: true,
enabled: false
}
]
});
}
});
}
});
</script>
</head>
<body>
<div class="container mt-5">
<form method="post">
<div class="form-group">
<label>Title</label>
<input type="text" name="title" class="form-control">
</div>
<div class="form-group mt-4">
<label>Content</label>
<textarea id="tinymce"></textarea>
</div>
<button class="btn btn-primary mt-4">Submit</button>
</form>
</div>
</body>
</html>
Â
That's it I hope it helps. Thank you for reading :)
Â
Read next