tinyMCE.get("content") is undefined - javascript

I get this message : tinyMCE.get("message_data_" + msg_id) is undefined on Firebug after
I click on the button to submit the form.
msg_id is defined, I checked it. message_data_ is also defined.
The function tinyMCE.get is not for some reason.

If you are using one single editor instance you may use tinymce.editors[0] instead of tinyMCE.get("message_data_" + msg_id).

If you do not have control over init method of TinyMCE then, you can follow this solution. Basically it adds a fallback if TinyMCE is not initialized.
jQuery(document).ready(function($) {
function myCustomSetContent( id, content ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
editor.setContent( text );
editor.save( { no_events: true } );
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
//TinyMCE will take up this value when it gets initialized.
jQuery( '#'+id ).val( text );
}
return true;
}
return false;
}
function myCustomGetContent( id ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
return editor.getContent();
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
// TinyMCE will take up this value when it gets initialized.
return jQuery( '#'+id ).val();
}
}
return '';
}
$(".class-to-update-content").on("click", function(e) {
myCustomSetContent( "tinymce-editor-id", "New Content in Editor" );
});
$(".class-to-get-content").on("click", function(e) {
$("div.class-to-display-content").html( myCustomGetContent( "tinymce-editor-id" ) );
});
});
Ref : http://blog.incognitech.in/tinymce-undefined-issue/

if you are using multiple editor in a form then you can create a function and get its value
i.e.
// Declare a function to get editor value
function tinyMca_text(field_id) {
if ( jQuery("#"+field_id+":hidden").length > 0)
{
return tinyMCE.get(field_id).getContent();
}
else
{
return jQuery('#'+field_id).val();
}
}
// show that value
console.log(tinyMca_text('field'));

Related

How to show native validation error for specific input on change event?

I have a classic HTML5 form. I would like using jquery/javscript to show the browser native error tooltip when the user change a specific input value. I would like to avoid the user try to submit the form to see all errors.
For that, I tried with the functions checkValidity() and reportValidity() but it works only if I add alert('test'); in my condition...so weird
JS script
myInputJqueryObject.on('change', function() {
if ( !this.checkValidity() ) {
this.setCustomValidity( 'Custom error !!!' );
var $form = $('#my-form');
if( $form[0].checkValidity() === false) {
$form[0].reportValidity();
//alert('test'); <-- works only if I active this line code
return true;
}
}
});
You do not need to check the form validity when you know that the input is invalid. You can omit if( $form[0].checkValidity() === false). Also you can reportValidity on the input itself.
And setCustomValidity takes some time to be applied to the input field. So you have to wrap reportValidity into setTimeout:
$('input').on('change', function() {
var self = this;
if (!self.checkValidity()) {
self.setCustomValidity('Custom error !!!');
setTimeout(function() {
self.reportValidity();
self.setCustomValidity('');
}, 1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my-form"><input value="del me" required></form>
Based on 'Kosh Very' answer, I found the solution. It sounds good without bugs.
JS Script :
$('input').on('focusout', function() {
var self = this;
var validity = self.checkValidity();
if( !validity ){
if( self.validity.patternMismatch ){ //<-- Optionnal : Condition to keep others native message errors except Pattern.
self.setCustomValidity( 'Custom Error about pattern!!!' );
}
setTimeout(function() {
self.reportValidity();
self.setCustomValidity( '' ); //<-- Important to reinit
}, 1);
}
});

Unsure how to perform action if all form inputs do NOT contain specific values

This is more of a question on how to approach this scenario.
I have a form, and I need to perform an action if any form input contains ".ca", "canada" or "canadian", but I also need to reverse that action if the fields do NOT contain these strings. Ideally, this would action would trigger (if needed) as the form is completed rather than when submit is clicked.
My code to check for ".ca", "canada", or "canadian"
var optInFieldIsVisible = false;
var optInField = jQuery( 'input[name*="email"]' );
jQuery("*").find('input').bind('input propertychange', function() {
if (/.ca$|canada|canadian/i.test( jQuery(this).val() ) ) {
optInFieldIsVisible = true;
optInField.closest( '.formField' ).show();
// show special form field because reference to canada is present
}
else {
if (optInFieldIsVisible == false) {
optInField.closest( '.formField' ).hide();
// hide special form field because reference to canada is removed
}
});
The problem with the above code is that it has no condition that is ever valid for the special field will never re-hide once it is activated.
If I remove the "if (optInFieldIsVisible == false)" under the else-condition the field will show and hide properly if the user works within the currently selected input, BUT it will then re-hide as soon as anything is typed into the next input (since the regex returns false in the now-selected new form input).
Clearly a flag variable isn't the solution, and some sort of counter variable I also can't see as working here. Does anyone have pointers?
EDIT:
See live demo http://jsbin.com/toyin/1/edit
I'm not sure I understand you correctly, but this may be what you want:
var optInFieldIsVisible = false;
var optInField = jQuery( 'input[name*="email"]' );
jQuery("*").find('input').bind('input propertychange', function() {
if (/.ca$|canada|canadian/i.test( jQuery(this).val() && !optInFieldIsVisible ) ) {
optInFieldIsVisible = true;
optInField.closest( '.formField' ).show();
// show special form field because reference to canada is present
}
else if (optInFieldIsVisible){
optInFieldIsVisible = false;
optInField.closest( '.formField' ).hide();
// hide special form field because reference to canada is removed
}
});
Checkout the fiddle, is it the thing you want to do?
var optInFieldIsVisible = false;
var optInField = jQuery( 'input[name*="opt-in"]' );
optInField.closest( 'div.formField' ).hide();
jQuery("*").find('input').bind('input propertychange', function() {
if (/.ca$|canada|canadian/i.test( jQuery(this).val() ) ) {
optInFieldIsVisible = true;
optInField.closest( 'div.formField' ).show();
}
else {
optInFieldIsVisible = false;
optInField.closest( 'div.formField' ).hide();
}
});
This is what I came up with to address this. Added a new function:
/* clear required field on focusout if triggers are removed from all fields */
jQuery("*").find('input').focusout(function(){
var eList = [];
jQuery("*").find('input').each( function() {
if ( /.ca$|canada|canadian/i.test( jQuery(this).val() ) == false ) {
eList.push(false);
}
else {
eList.push(true);
}
})
if ( jQuery.inArray(true, eList )==-1 ) {
optInField.closest( '.formField' ).hide();
}
})
Also removed the else statement from my original code, as that was no longer needed with the above added. See http://jsbin.com/toyin/3/edit

Unwanted "display: none" added on class change in jQuery

I've got a weird bug happening on a music library site that I'm working on. The intended functionality (take a form of checkboxes, dynamically change them into selectable words that highlight and "check" the associated checkbox on click, then automatically update the songs below based on the highlighted tags) works fine -- but when you click a selected tag to remove it, it does the correct functionality with the data below and the highlight is removed, but all other selected tags are getting "display: none" added to them.
Here, I think, is the function causing the weird issue:
// Given an label "$label," if it hasn't been selected, then
// highlight the label area and set the "checked" value of the
// appropriate checkbox input to true; if it is already selected,
// remove the highlight and set the "checked" value of the appropriate
// checkbox to "false"
function highlightAndCheck( $label )
{
var id = $label.attr("id"),
$checkbox = $label.prev(),
val = $checkbox.attr("value");
if( id === val )
{
if( $label.hasClass("clicked") )
{
$checkbox.prop("checked", false);
$label.removeClass("clicked");
} else
{
$checkbox.prop("checked", true);
$label.addClass("clicked");
}
}
}
Here's the full jQuery code for the page. I can provide more code if anything is confusing, but I hope the labeling, etc. are straightforward:
$(function() { //on document ready
var $categoriesAndTags = $("div#categories-and-tags"),
$tagCategory = $categoriesAndTags.find("div.tag-category"),
$searchButton = $categoriesAndTags.find("input#public-user-tag-search-submit");
// First, hide the checkboxes and search button, since we don't need them in the dynamic version
$tagCategory.addClass("tag-spinner-skin")
.find("input[type=checkbox]").hide();
$tagCategory.find("br").hide();
$searchButton.hide();
// Make it so then clicking on the text of a tag makes the hidden select box "select"
$tagCategory.find("label").each(function(){
$(this).on("click",function(){
var $this = $(this);
highlightAndCheck( $this );
searchByTags();
//While the unwanted "display:none" bug is happening, use this to make them re-appear on next click
$this.siblings("label").show();
});
});
// Make the search update automatically when a select box is clicked or unclicked.
var tagIDs = getUrlVarValArray( "tagID" );
$tagCategory.find("label").each(function(){
var $this = $(this),
id = $this.attr("id");
if( tagIDs.indexOf( id ) > -1 )
{ highlightAndCheck( $this ); }
});
});
function searchByTags( tags )
{
data = $("form#tag-select input").serialize()
if( data.length > 0 )
{
data += "&search=search";
}
$.ajax({
url: "songs/",
data: data,
type: "GET",
success: function(data){
// DO THIS if we successfully do the Ajax call
$newSongPlayers = $(data).find("div#songs-area");
$("div#songs-area").replaceWith( $newSongPlayers );
$.getScript("javascripts/public.js");
}
});
}
// Given an label "$label," if it hasn't been selected, then
// highlight the label area and set the "checked" value of the
// appropriate checkbox input to true; if it is already selected,
// remove the highlight and set the "checked" value of the appropriate
// checkbox to "false"
function highlightAndCheck( $label )
{
var id = $label.attr("id"),
$checkbox = $label.prev(),
val = $checkbox.attr("value");
if( id === val )
{
if( $label.hasClass("clicked") )
{
$checkbox.prop("checked", false);
$label.removeClass("clicked");
} else
{
$checkbox.prop("checked", true);
$label.addClass("clicked");
}
}
}
function getUrlVarValArray( needle )
{
var results = [],
hash,
hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
if( needle.length > 0 )
{
if( hash[0] === needle )
{
results[ results.length ] = hash[1]; // array[ array.length ] is a faster way to apend than array.push() in small arrays
}
}
}
return results;
}
Thanks in advance for your help! If it's helpful to login and see this in context, please go to the test site and use username: stackoverflowuser; password: HelpMeFigureThisOut -- once you're logged in, click on "View Songs"and the jQuery is referencing the tags at the top of the page.
Look at the following code in the public.js file:
$("html").on("click", function(event){
if(!$(event.target).is('.options-button')
&& !$(event.target).is('input.add-new-playlist')
&& !$(event.target).is('button.submit-new-playlist')
&& !$(event.target).is('button.add-song-to-playlist')
&& !$(event.target).is('button.playlist-popup-button')
)
{
if(!$(event.target).is('.clicked') && !$(event.target).is('.clicked > div') )
{ $(".clicked").hide().removeClass("clicked"); }
}
});
This handler gets executed because the click event propagates from the <label> element to the <html> element. It executes after the click handler on the <label> element, which removes the "clicked" class from the <label> element. Since the <label> element is the event.target and no longer has the "clicked" class, the following line is executed:
$(".clicked").hide().removeClass("clicked");
That line hides all the labels that still have the "clicked" class.

Adding custom id attribute for img and input elements

I am trying to add a custom id attribute for each img & input elements in ckeditor 3.6.4.
So far I have added dataProcessor.htmlFilter to handle the id attribute like this
CKEDITOR.on( 'instanceReady', function(event) {
var editor = CKEDITOR.instances.editor;
editor.dataProcessor.htmlFilter.addRules(
{
elements: {
$: function (element) {
if ( (element.name == 'img' || element.name == 'input') && CKEDITOR.instances.editor.mode == 'wysiwyg' ) {
if (!element.attributes.id){
var g = createID();
alert('new id: ' + g);
element.attributes.id = g;
}
}
}
}
});
});
and when I add a new textfield in visual editor I do get a new id. But if I set to the source mode the mode is still 'wysiwyg' and not 'source' and it gives a new Id.
How can I prevent the double action?
Did some testing. Added this
CKEDITOR.instances.editor.on('mode', function() {
// Code to execute when the user switches editing modes
alert('Changed to: ' + CKEDITOR.instances.editor.mode);
});
Somehow that fires after the htmlFilter rule.
You can try adding a check for the editor mode to your rule.
if ( (element.name == 'img' || element.name == 'input') && editor.mode == "wysiwyg" ) {
if (!element.attributes.id){
var g = createID();
alert('new id: ' + g);
element.attributes.id = g;
}
}
I'm not sure whether "editor" would be the correct object name to use, you may want to use CKEDITOR.currentInstance.mode
There is also a getMode() method.
Here are some api references for the items mentioned:
mode property
currentInstance property
getMode() method
Went with plan B
Customized the widgets needed and added the id attribute in plugin. Was easy and fast.

TinyMCE validation gives error: Cannot call method 'getContent' of undefined

I have a text area with tiny mce, I load it like this:
$(document).ready(function () {
tinyMCE.init({
mode: "textareas",
...
This text area is in a form. I bind forms submit button to:
$('#btnSubmit').click(function() {
tinymce.triggerSave();
var editorContent = tinyMCE.get('Description').getContent();
if (editorContent == '' || editorContent == null)
{
$(tinymce.activeEditor.getBody()).css("background-color", '#ffeeee');
$(tinymce.activeEditor.getBody().parentNode).css("background-color", '#ffeeee');
$(tinymce.activeEditor.getBody().parentNode).css("border", '1px solid #ff0000');
}
});
In my entity class I have Required attribute.
My goal is to make tinyMCE background red when model is not valid. But I get error from ti question title.
Any help?
So, validation works. If I remove textarea empty check and leave color changing it changes. But the problem is when there is something in text area and I click submit area first become red and then submit.
Is there maybe some fubction where I can do something if validation fail?
It sounds to me just like an undefined object error - where the code can't resolve this line tinyMCE.get('Description').getContent();.
You seem to be mixing between using activeEditor sometimes and other times not, so instead I've standardised the code so you are always relying on activeEditor - this means I've removed the line that was triggering the error. You also seem to switch between using tinymce and tinyMCE which might not be causing problems but is best to be avoided... so I've standardised that as well.
Without seeing more of the way the rest of the code and markup is set-up however it's a bit difficult to tell exactly what is going on. Does my change repair the problem?
$('#btnSubmit').click(function() {
tinyMCE.triggerSave();
var editorContent = tinyMCE.activeEditor.getContent();
if (editorContent == '' || editorContent == null)
{
$(tinyMCE.activeEditor.getBody())
.css("background-color", '#ffeeee')
.parent()
.css({
"background-color": '#ffeeee',
"border": '1px solid #ff0000'
});
}
});
If you do not have control over init method of TinyMCE then, you can follow this solution.
jQuery(document).ready(function($) {
function myCustomSetContent( id, content ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
editor.setContent( text );
editor.save( { no_events: true } );
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
//TinyMCE will take up this value when it gets initialized.
jQuery( '#'+id ).val( text );
}
return true;
}
return false;
}
function myCustomGetContent( id ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
return editor.getContent();
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
// TinyMCE will take up this value when it gets initialized.
return jQuery( '#'+id ).val();
}
}
return '';
}
$(".class-to-update-content").on("click", function(e) {
myCustomSetContent( "tinymce-editor-id", "New Content in Editor" );
});
$(".class-to-get-content").on("click", function(e) {
$("div.class-to-display-content").html( myCustomGetContent( "tinymce-editor-id" ) );
});
});
Ref : http://blog.incognitech.in/tinymce-undefined-issue/

Categories

Resources