Data not fetch on CK Editor - javascript

I'm trying to bind data in CK Editor from database. But it is nor work properly, data is fetch but not display, display only when click on inspect element in Google Chrome.
HTML
<textarea id="input" name="input"></textarea>
JS
<script>
$(document).ready(function () {
$("#input").ckeditor();
});
function BindData() {
$("#input").val('This is CK Editor Demo');
}
BindData();
</script>
Link Here

First, you got to wait for DOM to be ready, then you got to wait for editor to be ready, and finally you can bind your data:
// Wait for DOM to be ready.
$( document ).ready( function() {
// Create an instance of the editor.
$( '#input' ).ckeditor( function( textarea ) {
// When the instance is ready, set some data.
$( textarea ).val( 'This is CK Editor Demo!' );
} );
} );
Or with an external method:
function BindData() {
$( '#input' ).val( 'This is CK Editor Demo!' );
}
// Wait for DOM to be ready.
$( document ).ready( function() {
// Create an instance of the editor.
$( '#input' ).ckeditor( function() {
// When the instance is ready, set some data.
BindData();
} );
} );
Read the official guide for the new jQuery adapter (since 4.2).

You load ckeditor and after you fill the textarea. No way, the ckeditor is loaded. An has not live update. You must change order.
<script>
function BindData() {
$("#input").val('This is CK Editor Demo');
}
BindData();
$(document).ready(function () {
$("#input").ckeditor();
});
</script>

You can use :
CKEDITOR.instances[ckeditorname].setData(yourdata)
To bind data after ckeditor instance

Try :
<script>
$(document).ready(function () {
$("#input").ckeditor();
BindData();
});
function BindData() {
CKEDITOR.instances["input"].setData('This is CK Editor Demo');
}
</script>
Calling BindData() function after ckeditor init.

Related

Apply a 'table'-class to a WooCommerce table after AJAX-call

WooCommerce-tables comes with classes like these, out of the box: shop_table shop_table_responsive cart woocommerce-cart-form__contents. So no table-class, which means no nifty Bootstrap-tables.
Huh!
And since overriding the WooCommerce-templates should only be done when absolutely necessary, then let's solve it with JavaScript!
My entire site it encapsulated by a Vue-div, like so:
<div id="app">
...
<table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents">
...
...
</table>
...
</div>
So initially I wrote this code, to add the table-class to all tables:
let tableSelectors = [
'.some-class table',
'.woocommerce-product-attributes',
'.woocommerce-cart-form > table'
];
for( let t = 0; t < tableSelectors.length; t++ ){
let tables = document.querySelectorAll( tableSelectors[t] );
if( tables ){
for( let i = 0; i < tables.length; i++ ){
tables[i].classList.add( 'table' );
}
}
}
... Putting that in the mounted(){ ... }-section.
That worked! So far so good.
But WooCommerce is using jQuery quite a lot. And on the cart page, if I change the quantity (and press 'Update'), then the table-contents are updated using AJAX. If you're curious how it works, then you can check it out here.
And when that runs, I assume that WooCommerce grabs the initial cart-template and reloads that whole table; without the newly added table-class. Bah humbug!
So how can I solve this?
I can override the WooCommerce ./cart/cart.php-template and add the
class to the template. Seems like quite the overkill for adding a class.
I can scan the DOM for tables every second (or so) and apply the table class, if it's not there. Not cool... Regardless if it's done using jQuery or Vue.
Since the whole table is being replaced in the DOM, then it doesn't work to monitor the current table (using watch(){...} in Vue) and apply the class if it changes, - since it never changes (it's replaced).
I'm unable to find a Hook that I can use.
I also tried using ajaxComplete, but I can see in the network-tab that the XHR-request is firing, but this code here is never doing anything (in the console):
jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
console.log( 'Test' );
});
Any other suggestions?
You could use the Mutation Observer API to listen for changes to a wrapper element's contents and re-apply the table classes.
This example is lifted nearly verbatim from the sample code on MDN. Clicking the button replaces the contents of the div, which you can see from the console output fires the observer callback.
// Select the node that will be observed for mutations
const targetNode = document.getElementById('some-id');
// Options for the observer (which mutations to observe)
const config = {
childList: true,
subtree: true
};
// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
console.log('A child node has been added or removed.');
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
function doUpdate() {
targetNode.innerText = Math.random();
}
document.querySelector('button').addEventListener('click', doUpdate);
<div id="some-id">(container)</div>
<button>change</button>
The ajaxComplete() function of jQuery can do what you expected,
I don't know why it's not working for you.
I just open the link of cart page you gave above and paste add the below code in the developer console
and it works as expected after each update of the cart, the "table" class successfully appended to the table as per given selectors.
jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
jQuery('.some-class table, .woocommerce-product-attributes, .woocommerce-cart-form > table').addClass("table");
});
It looks like you have not added the code in the proper place. Since ajaxComplete() function is dependent on jQuery you need to execute the above code after jQuery has been loaded successfully. To do that you can use wp_add_inline_script() function with wp_script_is()
Add the following code in your function.php file, It will add the below script to page after jQuery finish loading.
function my_custom_script() {
if ( ! wp_script_is( 'jquery', 'done' ) ) {
wp_enqueue_script( 'jquery' );
}
wp_add_inline_script( 'jquery-migrate', 'jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
jQuery(".some-class table, .woocommerce-product-attributes, .woocommerce-cart-form > table").addClass("table");
});' );
}
add_action( 'wp_enqueue_scripts', 'my_custom_script');
You can try to change the jquery ajax function
(function ($) {
var _oldAjax = $.ajax;
$.ajax = function (options) {
return _oldAjax(options).done(function (data) {
$('.some-class table, .woocommerce-product-attributes, .woocommerce-cart-form > table').addClass("table");
if (typeof (options.done) === "function")
options.done();
});
};
})(jQuery);
above code must be added before any ajax that is called
i've tested it on your site using the javascript console and actually
jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
console.log( 'Test' );
});
fire pretty well.
maybe you are adding that code on wrong place.. or maybe you have "Group Similar" flagged on javascript console settings and you didn't notice the log
so you could just put your code together like this:
jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
try{
let tableSelectors = [
'.some-class table',
'.woocommerce-product-attributes',
'.woocommerce-cart-form > table'
];
for( let t = 0; t < tableSelectors.length; t++ ){
let tables = document.querySelectorAll( tableSelectors[t] );
if( tables ){
for( let i = 0; i < tables.length; i++ ){
tables[i].classList.add( 'table' );
}
}
}
console.dir("ok");
}catch(ex){console.dir(ex);}
});
or use a jquery like solution like this:
jQuery( document ).ajaxComplete(function( event, xhr, settings ) {
jQuery('.some-class table, .woocommerce-product-attributes, .woocommerce-cart-form > table').addClass("table");
});
i've tested both of them directly on your site and both solutions works pretty well
and of course if you want make it works even at start the same script must be applied to jQuery( document ).ready() too:
jQuery( document ).ready(function() {
jQuery('.some-class table, .woocommerce-product-attributes, .woocommerce-cart-form > table').addClass("table");
});

Ckeditor - why dataProcessor.htmlFilter.addRules does not work? How to fix it?

I want to make that when creating a paragraph in the ckeditor, a certain class is automatically added to it. I wrote this code, but it does not work.
CKEDITOR.on('instanceReady', function (ev) {
var editor = ev.editor;
editor.dataProcessor.htmlFilter.addRules({
elements: {
p: function (el) {
el.addClass('myClass');
}
}
});
});
Why? How can I solve my problem?
Please use something like below. You should use dataFilter instead of htmlFilter and the best approach would be using both of them in order to avoid cases where you create paragraph with no class in design/wysiwyg mode and then you switch to source mode or get data from the editor.
var editor = CKEDITOR.replace( 'editor1', {
language: 'en',
extraPlugins : 'placeholder',
on: {
pluginsLoaded: function( evt ) {
evt.editor.dataProcessor.dataFilter.addRules( {
elements: {
p: function( el ) {
//The Html filter works when you load data into editor.
if(!el.hasClass('nomargins'))
el.addClass('nomargins');
}
}
} );
evt.editor.dataProcessor.htmlFilter.addRules( {
elements: {
p: function( el ) {
//The Html filter works when you get data from editor.
if(!el.hasClass('nomargins'))
el.addClass('nomargins');
}
}
} );
}
}
});

jQuery error on Custom Javascript variable in Google tag manager

Why am I getting an error when I run a jquery as a Custom javasript variable? The error description is "Error at line 10, character 2: Parse error. ')' expected"
function(){
$( document ).ready(function() {
$('button[class="panel__link panel__link--btb"]').on( 'click', function(e) {
var $label = $( this ).parent().find("h2").text();
return $label;
});
});
};
Please advise.
Regards,
Sree
Remove the last semicolon ; on the last line:
function(){
$( document ).ready(function() {
$('button[class="panel__link panel__link--btb"]').on( 'click', function(e) {
var $label = $( this ).parent().find("h2").text();
return $label;
});
});
}
I think you did some conceptual mistake, when you working with GTM. Custom variable should return some value when trigger is fired.
I think your initial goal in GTM is:
Send some tag (to Universal analytics or something else) when user clicks on button button[class="panel__link panel__link--btb"]. This tag should contain some text information, which you can find like that .parent().find("h2").text();
If i am correct, then you should do the following:
Go to Variables. Built-in variables-> Configure-> Enable Click Element
Go to Triggers -> New -> Type: All Elements -> Click Element:matches CSS selector:button.panel__link.panel__link--btb
Go to Variables. New -> Custom JavaScript: function(){return {{Click Element}}.parent().find("h2").text();} -> Name: 'H2 text'
Go to Tags. New -> Assign trigger from step #2. -> Type: (you can choose what you need) -> And here you can use your variable {{H2 text}}, it will return necessary text
The error is caused because there no name for the function. I think you are trying to do a Self Invoking function which should be
(function(){
//your code
}());
Your code should be,
(function(){
$( document ).ready(function() {
$('button[class="panel__link panel__link--btb"]').on( 'click', function(e) {
var $label = $( this ).parent().find("h2").text();
return $label;
});
});
}());
Or
Remove the function() {} and simply execute the code with .ready
$( document ).ready(function() {
$('button[class="panel__link panel__link--btb"]').on( 'click', function(e) {
var $label = $( this ).parent().find("h2").text();
return $label;
});
});

What page is loaded in div

I'm using this command : $( "#result" ).load( "ajax/test.html" ); to load html page's content into div.
My question is how to know what I entered after I enterd it. A function that return the html page that is already inside the div.
You can store in a variable the currently loaded page (currentPage) and compare the page you load with the value of this variable:
<div id="result"></div>
<input type="button" onclick="load('test1.html')" value="Load">
<script>
var currentPage;
function load(page) {
if ( currentPage != page ) {
$("#result").load(page, function () {
currentPage = page;
});
}
else console.log('already loaded');
}
</script>
If you mean to access the contents of that page after it is loaded, You can use the callback of the function load.
$( "#result" ).load( "ajax/test.html", function() {
alert( "Load was performed." );
});
The callback is added as the second parameter one function and work within when it is charged.
You can also receive parameters in the callback.
Type: Function( String responseText, String textStatus, jqXHR jqXHR )
Full documentation have it here http://api.jquery.com/load/

AJAX URL append conflicting with stored jQuery .data()

I've got a document.ready function that stores all of the data in preparation for a popover on :hover.
domReady( function() {
$('.foo').each( function() {
var el = $(this);
var el_content = el.find('[data-content]');
el.data( 'content-attr', { content: el_content, classes: el_classes } );
} );
} );
Everything works fine by default, but when the URL is appended for AJAX sorting, I lose my window ref I suppose, because the following event handler returns undefined when accessing the data which is accessed without issue when the URL is not appended. I'm aware that this must be a window reference issue in the event handler, can someone point me to the correct way to reference window so that that the jQuery object where data is stored on load is accessible to .on( 'hover', function() { //do stuff }); while the URL is appended for AJAX?
$( window ).on( 'hover', '[rel="popover"]', function() {
var el = $(this);
var this_content_data = el.data( 'content-attr' ).content;
function() {
// do stuff
}
} );
In the case of this particular issue, I realized the only way to do this was to store the data in a jQuery .data attribute on the initialization of the view for access by the function on $(window).element.on( 'hover', ...){}.

Categories

Resources