TinyMCE and HTML5 form validation - html

I'm using TinyMCE in a Rails application. In my form, I have a "description" field with TinyMCE and this field is mandatory for the form validation.
But when I try to submit my form, I can't, because of the HTML5 form validation. My browser (Chrome and Firefox) tells me that the field is empty. And I have another problem. When Chrome displays the dialog for the empty field, it appears on the top of my page, not near my form field.

FF show up a bubble for required fileld but at wrong place, Chrome throws an error because it can't find field to show bubble.. So my solution is disable display:none style set by TinyMCE and reduce the field size and make its visibility hidden. this way browser will show bubble next to this field as this field is next to TinyMCE editor user will know what required field is missing.
textarea.tinymce {
background: transparent;
border: none;
box-shadow: none;
display: block !important;
height: 0;
resize: none;
width: 0;
visibility: hidden;
}

I used the "oninit" option in the textareas and worked:
oninit: function(editor) {
$currentTextArea.closest('form').bind('submit invalid', function() {
editor.save();
});
}
You could try to use onChange event, but it doesn't work properly in Firefox.
My complete code:
$('textarea.tinymce').each(function(){
var options = {
theme : "advanced",
skin : "cirkuit",
plugins : "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template", theme_advanced_buttons1 :"formatselect,fontsizeselect,forecolor,|,bold,italic,strikethrough,|,bullist,numlist,|,justifyleft,justifycenter,justifyright,|,link,unlink,|,spellchecker",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true
},
$this = $(this);
// fix TinyMCE bug
if ($this.is('[required]')) {
options.oninit = function(editor) {
$this.closest('form').bind('submit invalid', function() {
editor.save();
});
}
}
$this.tinymce(options);
});

I took #lucaswxp code and changed it a bit, because Firefox was throwing an error ($this.is not a function, if I recall it correctly).
Also I changed the way it fires the code from:
$this.tinymce(options);
to:
tinymce.init(options);
Full code:
$(window).load(function() {
var options = {
selector: 'textarea',
skin: "lightgray"
},
$this = $(this);
// fix tinymce bug
if ($this.is('[required]')) {
options.oninit = function(editor) {
$this.closest('form').bind('submit, invalid', function() {
editor.save();
});
}
}
tinymce.init(options);
});
Many thanks to the creator, it worked like wonder :)

Related

monaco-editor - resize property causes editor popups to be hidden

I am using deltaDecorations to show errors in my editor.
here is my code: https://gist.github.com/dinager/41578bd658b60cc912a6023f80431810
Here is the result:
I am trying to add resize property to the editor by adding to the style
resize: both;overflow: auto;
But then the hover message is partly hidden by the edges of the editor
As you can see in below attached image - the editor can resize now (bottom right), but the hover message is partly hidden
How can I add resize property to not hide elements?
Another question: can I make the hover message float inside the editor, meaning if it's at the top line it should float to the bottom, if at the side of the editor float to the middle, etc..
Attaching the code adding the markerDecorations (exists also in the gist link at the top):
this.markerDecorations = codeEditor.deltaDecorations(this.markerDecorations, [
{
range: new monaco.Range(pos.startLine, pos.startColumn, pos.endLine, pos.endColumn),
options: {
className: 'squiggly-error',
minimap: {
color: { id: 'minimap.errorHighlight' },
position: monaco.editor.MinimapPosition.Gutter,
},
overviewRuler: {
color: { id: 'editorOverviewRuler.errorForeground' },
position: monaco.editor.OverviewRulerLane.Full,
},
stickiness: monaco.editor.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges,
zIndex: 1,
hoverMessage: { value: parseResponse.error, isTrusted: false },
},
},
]);
solved it by adding fixedOverflowWidgets: true on monaco.editor.create options.
this.editor = monaco.editor.create(el, {
// ...
fixedOverflowWidgets: true
});

TinyMCE add div around in the body from the iframe

I use the TinyMCE. The textarea create the tiny-editor. And the tiny-code create the iframe and in this iframe is the editor. So is it normal!
But now I want a div around the editor, in the body of the iframe. Is there an option to solve my problem?
enter image description here
I tried to make something
tinymce.init({
selector: "#mytextarea",
tinymce options: ... ,
toolbar: "add_div",
setup: function(editor) {
editor.ui.registry.addButton("add_div", {
text: "Add Div",
icon: "plus", // look editor-icon-identifiers page
onAction: function() {
var element = tinymce.activeEditor.dom.select("#tinymce");
var content = element[0].innerHTML;
element[0].innerHTML = "<div>"+content+"</div>";
}
}); // close registry.addButton
}, // close setup function
}); // close tinymce.init

change the back background Color of Textareafield

i cant change the backgroundColor of Textareafield In EXT js4.2
css
.disable-field{
background: #b5b8c8 !important;
}
Js
var remaskTextField = Ext.create('Ext.panel.Panel', {
id : 'remasksTextField',
title: 'Remark',
items: [ {
id : 'remask',
xtype : 'textareafield',
name : 'message',
width: 310,
height:230
}]
});
i tried the following code to change colour .
only the first one can change the backgroundColor but the top line of the Textareafield still remaining unchanged .
document.getElementById('remaskTextField').style.backgroundColor = "#c3c5ce";
Ext.getCmp('remask').addClass('disable-field');
Ext.getCmp('remasksTextField').addClass('disable-field');
One approach, that worked for me with ExtJS 4.2, is fieldStyle config:
fieldStyle : String
Optional CSS style(s) to be applied to the field input element. Should
be a valid argument to Ext.Element.applyStyles. Defaults to undefined.
See also the setFieldStyle method for changing the style after
initialization.
Example:
Ext.onReady(function() {
Ext.create('Ext.form.TextArea', {
renderTo: Ext.getBody(),
width: 400,
height: 400,
fieldStyle: "background: #b5b8c8 none repeat scroll 0 0 !important;"
});
});

Ckeditor allowedContent for html tag

I am using Ckeditor as rich editor for text input in the Chrome browser. I also have added some html id tag for easy parsing by bs4 after the system getting the data.
The following is my setting in the html:
CKEDITOR.replace( 'editor', {
toolbar : 'Basic',
uiColor : '#9AB8F3',
height : '70%',
startupShowBorders: false,
})
And in the config.js:
config.toolbarGroups = [
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ] },
{ name: 'links' },
{ name: 'insert' },
{ name: 'forms' },
{ name: 'tools' },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
{ name: 'others' },
'/',
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
{ name: 'styles' },
{ name: 'colors' },
{ name: 'about' }
];
// Remove some buttons provided by the standard plugins, which are
// not needed in the Standard(s) toolbar.
config.removeButtons = 'Underline,Subscript,Superscript';
// Set the most common block elements.
config.format_tags = 'p;h1;h2;h3;pre';
// Simplify the dialog windows.
config.removeDialogTabs = 'image:advanced;link:advanced';
config.allowedContent = True;
};
Although I have already followed the instruction to allow all html tag content to be preserved with config.allowedContent = *; in the config.jd. However, it seems not working as I got the following results when getting data (by CKEDITOR.instances.editor.getData()):
<span style='font-size:11.0pt;'> content </span>
instead of this that I want:
<span id="news_content" style='font-size:11.0pt;'> content </span>
In other words, it still strips out all the html tag I added.
When I checked the source code, I found that the same textarea content was produced twice with the one with the tag being put in hidden format, i.e.,
<textarea name="editor" id="editor" rows="100" cols="40" style="visibility: hidden; display: none;">
And the editor produces another version in the real textarea that allows me to edit. However, this is useless because all the html tags are stripped there.
So, my question is, how to preserve the html tag in the real textarea so that I can parse the html with id tags after editing and submission. Could anyone advise on this? Thanks a lot.
I may not be able to answer my own question, but I like to share my solution with those encountering similar situation.
In short, finally I give up using ckeditor or any plug-in editor as many of them will strip off the html tag, which is essential to me in the subsequent process.
Thanks to html5, my solution is using editable div. The setting is very simple as below:
css:
#my-content {
box-shadow: 0 0 2px #CCC;
min-height: 150px;
overflow: auto;
padding: 1em;
margin: 5px;
resize: vertical;
outline: none;
}
html:
<div id="my-content" class="editable" style="width:900px; height:400px; text-overflow: ellipsis; overflow-y: scroll;"></div>
js script:
$('.editable').each(function(){
this.contentEditable = true;
});
So far, I am happy with it, it shows what exactly the html code showing and preserve all the tags I added. The only downside is it does not provide any toolbar for format editing. My solution is to make one for it, and via the following link you can get a very good tutorial as to making a toolbar with a ready-to-use demo as illustration.
https://code.tutsplus.com/tutorials/create-a-wysiwyg-editor-with-the-contenteditable-attribute--cms-25657
Hope this helps.

Required Attribute Not work in Safari Browser

I have tried following code for make the required field to notify the required field but its not working in safari browser.
Code:
<form action="" method="POST">
<input required />Your name:
<br />
<input type="submit" />
</form>
Above the code work in firefox. http://jsfiddle.net/X8UXQ/179/
Can you let me know the javascript code or any workarround? am new in javascript
Thanks
Safari, up to version 10.1 from Mar 26, 2017, doesn't support this attribute, you need to use JavaScript.
This page contains a hacky solution, that should add the desired functionality: http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-safari
HTML:
<form action="" method="post" id="formID">
<label>Your name: <input required></label><br>
<label>Your age: <input required></label><br>
<input type="submit">
</form>
JavaScript:
var form = document.getElementById('formID'); // form has to have ID: <form id="formID">
form.noValidate = true;
form.addEventListener('submit', function(event) { // listen for form submitting
if (!event.target.checkValidity()) {
event.preventDefault(); // dismiss the default functionality
alert('Please, fill the form'); // error message
}
}, false);
You can replace the alert with some kind of less ugly warning, like show a DIV with error message:
document.getElementById('errorMessageDiv').classList.remove("hidden");
and in CSS:
.hidden {
display: none;
}
and in HTML:
<div id="errorMessageDiv" class="hidden">Please, fill the form.</div>
The only drawback to this approach is it doesn't handle the exact input that needs to be filled. It would require a loop accross all inputs in the form and checking the value (and better, check for "required" attribute presence).
The loop may look like this:
var elems = form.querySelectorAll("input,textarea,select");
for (var i = 0; i < elems.length; i++) {
if (elems[i].required && elems[i].value.length === 0) {
alert('Please, fill the form'); // error message
break; // show error message only once
}
}
If you go with jQuery then below code is much better. Just put this code bottom of the jquery.min.js file and it works for each and every form.
Just put this code on your common .js file and embed after this file jquery.js or jquery.min.js
$("form").submit(function(e) {
var ref = $(this).find("[required]");
$(ref).each(function(){
if ( $(this).val() == '' )
{
alert("Required field should not be blank.");
$(this).focus();
e.preventDefault();
return false;
}
}); return true;
});
This code work with those browser which does not support required (html5) attribute
Have a nice coding day friends.
I had the same problem with Safari and I can only beg you all to take a look at Webshim!
I found the solutions for this question and for this one very very useful, but if you want to "simulate" the native HTML5 input validation for Safari, Webshim saves you a lot of time.
Webshim delivers some "upgrades" for Safari and helps it to handle things like the HMTL5 datepicker or the form validation. It's not just easy to implement but also looks good enough to just use it right away.
Also useful answer on SO for initial set up for webshim here! Copy of the linked post:
At this time, Safari doesn't support the "required" input attribute. http://caniuse.com/#search=required
To use the 'required' attribute on Safari, You can use 'webshim'
1 - Download webshim
2 - Put this code :
<head>
<script src="js/jquery.js"></script>
<script src="js-webshim/minified/polyfiller.js"></script>
<script>
webshim.activeLang('en');
webshims.polyfill('forms');
webshims.cfg.no$Switch = true;
</script>
</head>
I have built a solution on top of #Roni 's one.
It seems Webshim is deprecating as it won't be compatible with jquery 3.0.
It is important to understand that Safari does validate the required attribute. The difference is what it does with it. Instead of blocking the submission and show up an error message tooltip next to the input, it simply let the form flow continues.
That being said, the checkValidity() is implemented in Safari and does returns us false if a required filed is not fulfilled.
So, in order to "fix it" and also show an error message with minimal intervention (no extra Div's for holding error messages) and no extra library (except jQuery, but I am sure it can be done in plain javascript)., I got this little hack using the placeholder to show standard error messages.
$("form").submit(function(e) {
if (!e.target.checkValidity()) {
console.log("I am Safari"); // Safari continues with form regardless of checkValidity being false
e.preventDefault(); // dismiss the default functionality
$('#yourFormId :input:visible[required="required"]').each(function () {
if (!this.validity.valid) {
$(this).focus();
$(this).attr("placeholder", this.validationMessage).addClass('placeholderError');
$(this).val(''); // clear value so it shows error message on Placeholder.
return false;
}
});
return; // its invalid, don't continue with submission
}
e.preventDefault(); // have to add it again as Chrome, Firefox will never see above
}
I found a great blog entry with a solution to this problem. It solves it in a way that I am more comfortable with and gives a better user experience than the other suggestions here. It will change the background color of the fields to denote if the input is valid or not.
CSS:
/* .invalid class prevents CSS from automatically applying */
.invalid input:required:invalid {
background: #BE4C54;
}
.invalid textarea:required:invalid {
background: #BE4C54;
}
.invalid select:required:invalid {
background: #BE4C54;
}
/* Mark valid inputs during .invalid state */
.invalid input:required:valid {
background: #17D654 ;
}
.invalid textarea:required:valid {
background: #17D654 ;
}
.invalid select:required:valid {
background: #17D654 ;
}
JS:
$(function () {
if (hasHtml5Validation()) {
$('.validate-form').submit(function (e) {
if (!this.checkValidity()) {
// Prevent default stops form from firing
e.preventDefault();
$(this).addClass('invalid');
$('#status').html('invalid');
}
else {
$(this).removeClass('invalid');
$('#status').html('submitted');
}
});
}
});
function hasHtml5Validation () {
return typeof document.createElement('input').checkValidity === 'function';
}
Credit: http://blueashes.com/2013/web-development/html5-form-validation-fallback/
(Note: I did extend the CSS from the post to cover textarea and select fields)
I use this solution and works fine
$('#idForm').click(function(e) {
e.preventDefault();
var sendModalForm = true;
$('[required]').each(function() {
if ($(this).val() == '') {
sendModalForm = false;
alert("Required field should not be blank."); // or $('.error-message').show();
}
});
if (sendModalForm) {
$('#idForm').submit();
}
});
The new Safari 10.1 released Mar 26, 2017, now supports the "required" attribute.
http://caniuse.com/#search=required
You can add this event handler to your form:
// Chrome and Firefox will not submit invalid forms
// so this code is for other browsers only (e.g. Safari).
form.addEventListener('submit', function(event) {
if (!event.target.checkValidity()) {
event.preventDefault();
var inputFields = form.querySelectorAll('input');
for (i=0; i < inputFields.length; i++) {
if (!inputFields[i].validity.valid) {
inputFields[i].focus(); // set cursor to first invalid input field
return false;
}
}
}
}, false);
Within each() function I found all DOM element of text input in the old version of PC Safari, I think this code useful for newer versions on MAC using inputobj['prpertyname'] object to get all properties and values:
$('form').find("[required]").each(function(index, inputobj) {
if (inputobj['required'] == true) { // check all required fields within the form
currentValue = $(this).val();
if (currentValue.length == 0) {
// $.each((inputobj), function(input, obj) { alert(input + ' - ' + obj); }); // uncomment this row to alert names and values of DOM object
var currentName = inputobj['placeholder']; // use for alerts
return false // here is an empty input
}
}
});
function customValidate(){
var flag=true;
var fields = $('#frm-add').find('[required]'); //get required field by form_ID
for (var i=0; i< fields.length;i++){
debugger
if ($(fields[i]).val()==''){
flag = false;
$(fields[i]).focus();
}
}
return flag;
}
if (customValidate()){
// do yor work
}