Is it possible to use EasyMDE with Laravel Livewire? - laravel

I use EasyMDE right now.
I load it up like this:
// markdown editor init
const easyMDE = new EasyMDE({
toolbar: ['undo', 'redo', 'bold', 'italic', 'strikethrough', 'heading-smaller', 'heading-bigger', '|', 'code', 'quote', 'ordered-list', 'unordered-list', '|', 'link', 'horizontal-rule', '|', 'clean-block'],
spellChecker: false,
element: document.getElementById('content')
});
It targets the textarea with the id "content" and transforms it to its markdown editor, which works just fine!
But now I have to make it work with livewire(validation and other stuff).
I have another, simple input:text above that with the id "title".
When I add wire:model="title" to it and write something in it, livewire updates and removes the markdown editor completely, replacing it with the default <textarea>.
This is obviously not working out for me, because I must use the markdown editor (and also validate other fields in the meantime).
Is there something I have to change that I don't know about?
If more info is needed please ask and I'll deliver.
Edit#1: So I figured if I put wire:ignore in the div containing the textarea, livewire just ignores it which would be fine, but I still need to validate it on the backend (which I can't if it gets ignored).

Related

CKEditor 5 - Using HTML inside mentions

I have been using mentions in CKEditor 5 to tag certain system variables. A typical tag looks like as:
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
#ApprovedCosts
</span>
When I try to render the following (the idea is to show the variable value when the user clicks preview, while he continues editing):
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
<p>Nice rendered <b>html</b></p>
</span>
CKEditor goes bonkers.
My requirement is to show a nicely formatted variable name inside the tag. I know I can control via CSS, but there could be a situation where I might end-up rendering a small table (if variable points to a data set), etc.
Help will be appreciated.
Cheers.
Generally speaking, CKEditor 5 documentations refrain from going with your basic plain HTML approach, as seen in the comments:
This plugin customizes the way mentions are handled in the editor model and data.
Instead of a classic <span class="mention"></span>,
Within their mentions documentation (by the way, highly suggested to take a look at - it's very well documented with lots of useful examples in case you're stuck!), they're defining a ClassicEditor (to be precise, they want to mimic a chat platform in which you can tag a user and will receive a list of users in return).
ClassicEditor
.create( document.querySelector( '.chat__editor' ), {
extraPlugins: [ Essentials, Paragraph, Mention, MentionLinks, Bold, Italic, Underline, Strikethrough, Link ],
toolbar: {
items: [
'bold', 'italic', 'underline', 'strikethrough', '|', 'link', '|', 'undo', 'redo'
]
},
mention: {
feeds: [
{
marker: '#',
feed: [
{ id: '#cflores', avatar: 'm_1', name: 'Charles Flores' },
[...]
],
itemRenderer: customItemRenderer
[...]
After the mention object is created, they're calling the customItemRenderer function. This infrastructure could nearly identical be copied. For your part the function MentionLinks is important, as you can customize how mentions are handled, i.e. let's take a look at their example:
function MentionLinks( editor ) {
editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'a',
key: 'data-mention',
classes: 'mention',
attributes: {
href: true
}
},
model: {
key: 'mention',
value: viewItem => editor.plugins.get( 'Mention' ).toMentionAttribute( viewItem )
},
converterPriority: 'high'
} );
Basically, you can customize all the properties within the MentionLinks function. CKEditor 5 did a good job documenting the mention plugin very hierarchically:
The documentation can be found here.
On a slight off-topic note I noticed your code passage <p>Nice rendered <b>html</b><p> contains little formality issues, i.e. you need to close the <p> tag by assigning a close tag </p>:
<p>Nice rendered <b>html</b></p>
Though I'm pretty sure that's not the error as you're talking about HTML in general and not only this code passage.
I think your main issue is your tags. Your paragraph tags (<p>) don't have a closing tag, only two opening tags. It should be <p>***your text here***</p>. If this doesn't fix the issue, please leave a comment.

Classes for Apostrophe Rich Text Widget

I've run into an issue passing classes to the Apostrophe Rich Text Widget. I've updated the sanitizeHtml document, and I'm able to pass one custom class, but as soon as I try to add multiple classes in the widget stops working (at least the style selector does).
{{ apos.singleton(data.page, 'servicesSubtitle', 'apostrophe-rich-text', {
toolbar: [ 'Styles' ],
styles: [
{
name: 'Services Subtitle',
element: 'h3',
attributes: {
class: 'sub-title primary-color'
}
}
],
class
controls: {
movable: false,
removable: false
}
}) }}
This works if I only have:
attributes: {
class: 'sub-title'
}
but doesn't when trying to pass two classes. I'm assuming there's something wonky with passing a space to that parameter, since it always grabs the first chunk of text, but I could be totally wrong about that. I figure I'm missing something really obvious, but cant figure it out or find any docs about it.
Any help would be appreciated!
This is a known CKEditor bug that the Apostrophe team hasn't quite pinned down. Multiple classes WILL work in certain cases (change the order, try different phrases)
This is a crummy answer. We'd love a contribution!

Adding Fontawesome to ckeditor

I am using Fontawesome in my website and have my own CMS to edit the website pages. What I would like to develop is a dialog for the user where he can pick an fontawesome icon but for now it is OK to add them in the codeview of ckeditor.
Icons added to the content are not shown in ckeditor designview. I have changed ckeditor config file so that the editor accepts i tags (*). I added the fontawesome CSS file as an #import rule to contents.css but still no fontawesome icon visible in the editor area.
(*)config.js
config.allowedContent = true;
config.ProtectedTags = 'i' ;
config.protectedSource.push( /<i[\s\S]*?\>/g ); //allows beginning <i> tag
config.protectedSource.push( /<\/i[\s\S]*?\>/g ); //allows ending </i> tag
What can I do to make this work?
config.protectedSource.push( /<i class[\s\S]*?\>/g );
config.protectedSource.push( /<\/i>/g );
What you have will interfere with img tags.
AND OR, after all of config:
CKEDITOR.dtd.$removeEmpty['i'] = false;
Both work well. Just be sure you have cleared cache completely when making changes.
*EDIT
One works while messing something else up. A no go solution.
I stopped using this bulky editor. Created my own.
However, to solve the solution, use EM or SPAN instead of I tags for this.
When you add something to the protectedSource setting, you're hiding it from the editor, that content is converted into a HTML comment to protect it and avoid that it can be modified by the user, but being a comment it's obviously hidden.
I'm using 4.11.4 and this solution not working correctly
This solution correctly work on 4.11.4
config.protectedSource.push( /<i class[\s\S]*?\><\/i>/g ); // Font Awesome fix
Goodluck
Instead of:
config.protectedSource.push(/<i class[\s\S]*?\><\/i>/g );
use more stronger and best way:
config.protectedSource.push(/<i class="fa[s|r|l|b] [A-Za-z0-9\-]+"><\/i>/g);
Because when user pasting content from another source, CKEDITOR.dtd should remove empty < i >, or convert < i > to semantic < em >, but only fontawesome icons with class="fas/far/fal/fab *" should be preserved.
(Naming in fontawesome: https://fontawesome.com/how-to-use/on-the-web/setup/getting-started)
Take a look at this: ckeditor fontawesome addon.
Basically, you should download the fontawesome addon in zip format, and extract to "ckeditor/plugins/", with the name "fontawesome".
Then, open "ckeditor/config.js" and signal the usage of the new addon:
config.extraPlugins = 'fontawesome';
config.contentsCss = 'path/to/your/font-awesome.css';
config.allowedContent = true;
The next thing is to edit your HTML's section:
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>
The final step is to use the toolbargroupname: "FontAwesome" in your toolbar:
config.toolbar = [
{ name: 'insert', items: [ 'FontAwesome', 'Source' ] }
];
Here is a demo.
This also applies for glyphicons, in the same way the fontawesome is used.
Cheers

CKEDITOR inline and multiple toolbars

I have multiple instances of a CKEDITOR inline on a page.
I want to be able to customise the toolbar for each of these to display different fonts in each of them.
So I have something like the following:
CKEDITOR.disableAutoInline = true;
var editor1 = CKEDITOR.inline(document.getElementById('editable_476'));
CKEDITOR.config.toolbar = [ .....
];
CKEDITOR.config.font_names = 'Helvetica Nueue/Helvetica Nueue';
This works well if I have one, but If I use the same code for another CKEDITOR instance, the font is overwritten.
How do I use different toolbars for different CKEDITOR instances?
Thanks
UPDATE:
CKEDITOR.inline( editable_498, {
toolbar: [
['Bold','Italic','Underline'],
['NumberedList','BulletedList'],
['JustifyLeft','JustifyCenter','JustifyRight'],
['Undo','Redo'],
'/',
['TextColor','Font','FontSize']
],
font_names: 'Helvetica Nueue/Helvetica Nueue';
});
This throws a syntax error:
Uncaught SyntaxError: Unexpected token ;
The line is font_names: 'Helvetica Nueue/Helvetica Nueue';
Use per-instance config:
CKEDITOR.inline( element, {
toolbar: [
...
],
font_names: '...'
});
CKEDITOR.config is something that all instances inherit from. Use config for a specific instance, it'll overwrite global rules from CKEDITOR.config.
See the official configuration guide.

jQuery disable rule validation on a single field

I am using MVC to create forms that are generated at runtime. For validation, I am trying my hand at the jQuery validation library which is very convenient to use. I have the validation expression of each field in the cdata attribute of the tag
<input type="text" name="xyz" id="xyz" class="defaultTextBox"
cdata="{validate:{required:true, decimal:true, messages:
{required:'Please enter an decimal value',
decimal:'Please enter a valid decimal'}}}">
This works beautifully. Now one more requirement I have is that some fields are being shown and hidden according to the logic on the page and I need to disable the validation on the hidden fields such that they do not interfere with the form submission. Just toggling the required:true to false and back to true should be enough. Only i do not know how.
Anyone has any experience with that?
Just add the ignore rule and define the selector.
In this example, the validation will ignore all elements that have the class="ignore"
$("#myform").validate({
ignore: ".ignore"
})
If you're using ASP.NET MVC Unobtrusive JQuery validation you need to set the settings in this way. This is because of the way Microsoft actually calls jQuery validate. This should be safe to do inside a ready method.
Edit: Please see Cory's comment below before copy pasting this. This is my original code
$("form").data("validator").settings.ignore = ".data-val-ignore, :hidden, :disabled";
Then I just apply .data-val-ignore class to things not to validate.
Note that you'll probably want to add :hidden which is actually the default ignore behavior defined in jquery.validate.js. I like to add :disabled too.
$.extend($.validator, {
defaults: {
messages: {},
groups: {},
rules: {},
errorClass: "error",
validClass: "valid",
errorElement: "label",
focusInvalid: true,
errorContainer: $([]),
errorLabelContainer: $([]),
onsubmit: true,
ignore: ":hidden", // default for ignore in jquery.validate.js
ignoreTitle: false,
onfocusin: function( element, event ) {
this.lastActive = element;
And finally you may want to style it - especially useful during debugging.
.data-val-ignore
{
background: #eee;
}
Following on Gabe's answer, you can also set the ignore value as a default, so you don't have to set it on each form.
$.validator.setDefaults({ignore: ".ignore"});
Also note, the ignore field is a jQuery selector that is used in the jQuery not() function so any valid selector can be used, not just simple classes.
See also http://docs.jquery.com/Plugins/Validation/validate#toptions for details on other default values that can be set.
I had a better time with $('.multiselect').rules('remove');
in my case for whatever reason adding .cancel or .data-val-ignore
to both the $.validator.setDefaults and $('.multiselect') did not fix it.
I also tried
$('select[multiple][data-val]').removeAttr('data-val').removeAttr('data-val-number').addClass('data-val-ignore').validate({ ignore: "[multiple]" });
$.validator.setDefaults({ ignore: ":hidden,:disabled,.data-val-ignore" });
$('.multiselect').closest('form').data('validator').settings.ignore = ":hidden,:disabled,.data-val-ignore, .data-val-ignore *";
$('.multiselect').data('validator').settings.ignore = "[multiselect]"
each of those... and combinations of them
my jquery.validate.js was
/*! jQuery Validation Plugin - v1.11.0 - 2/4/2013
* https://github.com/jzaefferer/jquery-validation
* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT */
jquery was
jQuery JavaScript Library v1.9.1 - Date: 2013-2-4
You can remove a rule from a single field by doing the following:
$("#field").rules('remove', 'required');
Where the second parameter is the rule name. I also remove the attribute associated with this rule to avoid any confusion:
$("#field").removeAttr('required');

Resources