How Do You Change the Placeholder Text Dynamically in TinyMCE 5? - tinymce

I'm using TinyMCE 5.6.2. I have a single textarea tied to TinyMCE. The placeholder text needs to change dependent upon the selection of a dropdown. I know I can initialize it with a static value:
tinymce.init({
selector: '.tinymce',
placeholder: "Please enter the complete date.",
However I need to change it based on the selection of a dropdown (the following was based on what I was doing before I tried to convert the textarea to TinyMCE).
if (reportingStatusId == "1") {
document.getElementById('notes').placeholder = 'Please enter why not started and estimated start month.';
} else if (reportingStatusId == "2") {
document.getElementById('notes').placeholder = 'Please enter why not applicable.';
} else if (reportingStatusId == "3") {
document.getElementById('notes').placeholder = 'Please enter why not reported.';
}
I've tried the following but neither works:
if (reportingStatusId == "1") {
tinyMCE.get('notes').placeholder = 'Please enter why not started and estimated start month.';
} else if (reportingStatusId == "2") {
tinyMCE.get('notes').placeholder = 'Please enter why not applicable';
} else if (reportingStatusId == "3") {
tinyMCE.get('notes').placeholder = 'Please enter why not reported';
}
and this:
if (reportingStatusId == "1") {
tinymce.init({
selector: ".tinymce",
placeholder: "Please enter why not started and estimated start month.",
});
} else if (reportingStatusId == "2") {
etc.....
} else if (reportingStatusId == "3") {
etc....
}
Here is the textarea I am targeting:
<textarea id="notes" class="form-control statusfield tinymce" rows="3" style="background-color:white" asp-for="Model[0].notes" >#Model.Model[0].notes</textarea>
Is there a way to change the placeholder text of a TinyMCE textarea dynamically? If so, how?

TinyMCE does not officially support the ability to modify the placeholder text once the editor is loaded.
If you inspect the DOM where TinyMCE appears you will see that there is an attribute on the <body> tag within the TinyMCE <iframe> called data-mce-placeholder. You can modify that attribute using JavaScript and that will cause the placeholder text to update. Here is a running example:
https://fiddle.tiny.cloud/6Xhaab
The key line is:
tinymce.activeEditor.getBody().setAttribute('data-mce-placeholder', 'This is NEW placeholder text');
Please note that this relies on the current way TinyMCE injects itself into the page and how it handles the placeholder. If TinyMCE were to change that in the future this would potentially break this workaround but for TinyMCE 5.x this should work across all versions.

Related

Resetting form and input fields

So I am making a simple todo list app with Framework7 and VueJS, but I'm struggling to understand how to reset the input fields.
<f7-list id="todo-form">
<f7-list-input id="item-input" type="text" name="listitem">
</f7-list-input>
</f7-list>
<f7-button #click="newItem">Add task</f7-button>
newItem() {
let formData = this.$f7.form.convertToData('#todo-form');
this.listItemName = formData.listitem;
if (this.listItemName == '' || this.listItemName === undefined) {
return false;
} else {
this.listItems.push(this.listItemName);
console.log(this.$$('#item-input')); // What to do here?
}
}
I would like to reset the item-input field as I click the button. I tried using Dom7 (not jQuery!) for this but there seems to be nothing storing the form input value.. After googling all I could find is suggestions to do $$('#item-input').val('') but there is no .val when I look through the element in the console.
Help is, as always, much appreciated!

bootstrap-tagsinput form submited on press enter key

in bootstrap-tagsinput on press enter key for next tag form is submitted!
what is the solution?
$("#inputID").tagsinput();
First, you'll want to map 'Enter' to your tagsinput's confirmkeys option, then you'll need to call preventDefault() on your enter key to prevent the form from being submitted. In my solution, it only prevents submission by enter key while the user is focused in the tags input field.
To add a bit of redundancy, I also re-map the enter key to a comma in the input field, just to be sure.
$('#tags-input').tagsinput({
confirmKeys: [13, 188]
});
$('#tags-input input').on('keypress', function(e){
if (e.keyCode == 13){
e.keyCode = 188;
e.preventDefault();
};
});
Just also an FYI, Enter key is mapped as 13, and comma is 188 in JS.
Try this:
$('.bootstrap-tagsinput input').keydown(function( event ) {
if ( event.which == 13 ) {
$(this).blur();
$(this).focus();
return false;
}
})
Go to tagsinput.js
Find line:
self.$container.on('keypress', 'input', $.proxy(function(event) {
Before the end of this function add following:
if (event.which == 13) {
return false; // dont submit form !!
}
Enter key is register for postback form . that's why a case has been happened that when you hit 'enter' key it trigger the 'postback' event so the form goes to submitted .
solution :
on page load reserve the enter key for tag input :
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { onkeydown = "return event.keyCode!=13" }))
if using asp.net mvc framework this is a simple example .
This work for me
$('.bootstrap-tagsinput input[type=text]').on('keydown', function (e) {
if ( event.which == 13 ) {
$(this).blur();
$(this).focus();
return false;
}
});
The cancelConfirmKeysOnEmpty option is set to true by default, but when set to false calls .preventDefault on the tag delimeter keydown event. Set it to false.
This solution also fixes the issue of a "carried comma".
cancelConfirmKeysOnEmpty: false,
// If the field is empty, let the event triggered fire as usual
if (self.options.cancelConfirmKeysOnEmpty === false) {
event.preventDefault();
}

Express.js: Validation of forms with text boxes and buttons

I am working with forms in Express.js and I am using express-validator for validation. The code I have shown below is a "form" with two text boxes, a choose file button and a submit button. When the user submits the form, but there are validation errors I would like to:
Show an error message, saying which of the elements in the form the user needs to fill in. I believe I know how to do this with pop-up windows, but I would like to know if there is a way to "highlight" the text box that the user is required to fill in, or put a "* Required" text next to the text box/button.
Currently, if there are errors, after the submission, the two text boxes in the form are populated with the variables that were previously submitted by the user. I would like to do the same thing for the "Choose file" button. Using the "value" field as I have done in the two text boxes, does not work for the button. Is there way to do this?
//in routes folder
exports.myPage = function(req, res) {
res.render('myPage.jade', {valName: 'Enter', valLastName: 'Enter'});
};
exports.myPage_post_handler = function(req, res) {
nameID = req.body.nameID;
lastNameID = req.body.lastNameID;
my_file = req.body.my_file;
req.session.nameID = nameID;
req.session.lastNameID = lastNameID;
req.session.my_file = my_file;
if (typeof req.session.nameID != 'undefined'){
valName = nameID;
}
if (typeof req.session.lastNameID != 'undefined'){
valLastName = lastNameID;
}
req.assert('nameID', 'Please enter a name').notEmpty();
req.assert('lastNameID', 'Please enter a last name').notEmpty();
req.assert('my_file', 'Please enter a my_file').notEmpty();
var errors = req.validationErrors();
if( !errors){
res.redirect('/other_page');
}
else {
res.render('myPage.jade');
}
};
//in my_page.jade
form(method='post')
| Name:
div
input(type='text', name='nameID', id = 'name', value = valName)
| Session ID:
div
input(type='text', name='laastNameID', id ='lastName', value = valLastName)
| Video:
div
input(type='file', name='my_file', id='fileF')
div
input(type='submit', value='submit', value='Submit')
In Html5 (which also applies to Jade) you can put a "required" parameter whenever you declare text boxes or radio buttons etc..

Prevent TinyMCE from removing span elements

Here is the problem demonstration
You can try it here: http://fiddle.tinymce.com/SLcaab
This is TinyMCE default configuration
less all the plugins
with extended_valid_elements: "span"
1 - Open the Html Source Editor
2 - Paste this html into the Html Source Editor:
<p><span>Hello</span></p>
<p>Google 1</p>
<p>Google 2</p>
3 - Click update in the Html Source Editor to paste the html in the editor
4 - Remember there is a span around 'Hello'.
5 - Place your cursor just before Google 2 and press backspace (the two links should merge inside the same paragraph element).
6 - Look at the resulting html using the Html Source Editor.
Result (problem): No more span in the html document even though we added 'span' to the extended_valid_elements in the TinyMCE settings.
Note: I removed all the plugins to make sure the problem is at the core of TinyMCE.
Edit 1 - I also tried: valid_children : "+p[span]" - still does not work
Edit 2: Only reproduced on WebKit (OK on Firefox and IE)
Insert extended_valid_elements : 'span' into tinymce.init:
tinymce.init({
selector: 'textarea.tinymce',
extended_valid_elements: 'span',
//other options
});
I have the same problem and I find solutions. Tiny MCE deleted SPAN tag without any attribute. Try us span with class or another attribute for example:
<h3><span class="emptyClass">text</span></h3>
In TinyMCE 4+ this method good work.
Tinymce remove span tag without any attribute. We can use span with any attribute so that it is not removed.
e.g <span class="my-class">Mahen</span>
Try this for 3.5.8:
Replace cleanupStylesWhenDeleting in tiny_mce_src.js (line 1121) with this::
function cleanupStylesWhenDeleting() {
function removeMergedFormatSpans(isDelete) {
var rng, blockElm, wrapperElm, bookmark, container, offset, elm;
function isAtStartOrEndOfElm() {
if (container.nodeType == 3) {
if (isDelete && offset == container.length) {
return true;
}
if (!isDelete && offset === 0) {
return true;
}
}
}
rng = selection.getRng();
var tmpRng = [rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset];
if (!rng.collapsed) {
isDelete = true;
}
container = rng[(isDelete ? 'start' : 'end') + 'Container'];
offset = rng[(isDelete ? 'start' : 'end') + 'Offset'];
if (container.nodeType == 3) {
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
// On delete clone the root span of the next block element
if (isDelete) {
blockElm = dom.getNext(blockElm, dom.isBlock);
}
if (blockElm && (isAtStartOrEndOfElm() || !rng.collapsed)) {
// Wrap children of block in a EM and let WebKit stick is
// runtime styles junk into that EM
wrapperElm = dom.create('em', {'id': '__mceDel'});
each(tinymce.grep(blockElm.childNodes), function(node) {
wrapperElm.appendChild(node);
});
blockElm.appendChild(wrapperElm);
}
}
// Do the backspace/delete action
rng = dom.createRng();
rng.setStart(tmpRng[0], tmpRng[1]);
rng.setEnd(tmpRng[2], tmpRng[3]);
selection.setRng(rng);
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
// Remove temp wrapper element
if (wrapperElm) {
bookmark = selection.getBookmark();
while (elm = dom.get('__mceDel')) {
dom.remove(elm, true);
}
selection.moveToBookmark(bookmark);
}
}
editor.onKeyDown.add(function(editor, e) {
var isDelete;
isDelete = e.keyCode == DELETE;
if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
e.preventDefault();
removeMergedFormatSpans(isDelete);
}
});
editor.addCommand('Delete', function() {removeMergedFormatSpans();});
};
put an external link to tiny_mce_src.js in your html below the tiny_mce.js
It's possible to use the work around by writing it as a JavaScript script which prevents WYSIWIG from stripping empty tags. Here my issue was with including Font Awesome icons which use empty <i> or <span> tags.
<script>document.write('<i class="fa fa-facebook"></i>');</script>
In the Tinymce plugin parameters enable:
Use Joomla Text Filter.
Be sure your user group have set "No filtered" Option in global config > text filters.
Came across this question and was not happy with all the provided answers.
We do need to update wordpress at some point so changing core files is not an option. Adding attributes to elements just to fix a tinyMCE behaviour also doesn't seem to be the right thing.
With the following hook in the functions.php file tinyMCE will no longer remove empty <span></span> tags.
function tinyMCEoptions($options) {
// $options is the existing array of options for TinyMCE
// We simply add a new array element where the name is the name
// of the TinyMCE configuration setting. The value of the array
// object is the value to be used in the TinyMCE config.
$options['extended_valid_elements'] = 'span';
return $options;
}
add_filter('tiny_mce_before_init', 'tinyMCEoptions');
I was having same issue. empty SPAN tags are being removed. The solution i found is
verify_html: false,
Are you running the newest version of TinyMCE? I had the opposite problem - new versions of TinyMCE would add in unwanted span elements. Downgrading to v3.2.7 fixed the issue for me, that might also work for you if you are willing to use an old version.
Similar bugs have been reported, see the following link for bugs filtered on "span" element:
http://www.tinymce.com/develop/bugtracker_bugs.php#!order=desc&column=number&filter=span&status=open,verified&type=bug

forced_root_block option in TinyMCE

I am trying to implement a custom WYSIWYG editor using a contenteditable <div>.
One of the major issues I am facing is the inconsistent way browsers handle ENTER keystroke (linebreaks). Chrome inserts <div>, Firefox inserts <br> and IE inserts <p>. I was taking a look at TinyMCE and it has a configuration option called forced_root_block. Setting forced_root_block to div actually works across all major browser. Does someone know how forced_root_block option in TinyMCE is able to achieve it across browsers ?
In the tinymce source (/tiny_mce/classs/dom/DomParser.js) you will find the following:
rootBlockName = "forced_root_block" in args ? args.forced_root_block : settings.forced_root_block;
whiteSpaceElements = schema.getWhiteSpaceElements();
startWhiteSpaceRegExp = /^[ \t\r\n]+/;
endWhiteSpaceRegExp = /[ \t\r\n]+$/;
allWhiteSpaceRegExp = /[ \t\r\n]+/g;
function addRootBlocks() {
var node = rootNode.firstChild, next, rootBlockNode;
while (node) {
next = node.next;
if (node.type == 3 || (node.type == 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type'))) {
if (!rootBlockNode) {
// Create a new root block element
rootBlockNode = createNode(rootBlockName, 1);
rootNode.insert(rootBlockNode, node);
rootBlockNode.append(node);
} else
rootBlockNode.append(node);
} else {
rootBlockNode = null;
}
node = next;
};
};
This obviously takes care of creating root block elements.
I am 99% sure that tinymce handles the 'ENTER' keystroke itself and stops the propagation/ default browser command.