tinyMCE.editors[] wordpress 4.8 undefined - javascript

I have a custom posttype with a metabox that can add posts with editors to the post. whenever I add a new post with an editor I want to save the content of that editor. It has worked fine previously but has now stopped working. I can see that there are some changes in the wordpress update 4.8 to the editor api, but I can't see how the changes affect my code.
Making the editor:
<?php
public function wldk_elearn_add_elements_to_metabox($subpage_id){
$parent_id = $subpage_id;
echo '<div id="element_data_input_text">';
<?php
$settings = array( 'textarea_name' => 'mycustomeditor_'.$parent_id );
$editor_id = 'mycustomeditor_'.$parent_id;
wp_editor( "", $editor_id, $settings );
echo '</div>';
}
Javascript
function handleAddElementAction() {
$('.wldk-elearn-add-element').click(function (event) {
event.preventDefault();
var $wrapper = $(this).parents('#wldk-elearn-new-element');
var $subpage = $wrapper.find('input[name=subpage_id]');
var $type = $wrapper.find('input:radio[name=element_type]:checked');
var subpage = $subpage.val();
var content = '';
var whichmceditor = 'mycustomeditor_'+subpage;
console.log(whichmceditor);
if($type.val()=='tx'){
content = tinyMCE.editors[whichmceditor].getContent();
}
});
}
Uncaught TypeError: Cannot read property 'getContent' of undefined
i have also tried
content = tinyMCE.get(whichmceditor).getContent();
Which just gives me
Uncaught TypeError: Cannot read property 'getContent' of null
Its like tinyMCE methods don't exist anymore or something. I am not very good at this so any help or clue would be apreciated greatly.

So i figured it out! It was simply that the editor must be in visual mode in order to get the editor. A simple conditional fixes the issue:
function handleAddElementAction() {
$('.wldk-elearn-add-element').click(function (event) {
event.preventDefault();
var $wrapper = $(this).parents('#wldk-elearn-new-element');
var $subpage = $wrapper.find('input[name=subpage_id]');
var $type = $wrapper.find('input:radio[name=element_type]:checked');
var subpage = $subpage.val();
var content = '';
var whichmceditor = 'mycustomeditor_'+subpage;
console.log(whichmceditor);
if($type.val()=='tx'){
if($wrapper.find('#'+whichmceditor).is(':visible')){
content = $wrapper.find('#'+whichmceditor).val();
}else{
content = tinyMCE.editors[whichmceditor].getContent();
}
}
});
}
That's 3 hours of my life wasted, Maybe the documentation could be clearer, maybe it's me, maybe it's maybeline.

Related

TinyMCE iframe is null

I have two custom fields that use wp_editor() on a WordPress custom post type, which basically embeds an iframe where the content is. I'm trying to capture when someone tries to change one of the values, which I'm learning requires the addEventListener function with the keydown approach.
My problem is that I keep getting an error saying the iframe is null or tinyMCE is undefined. My script works fine in the console, but if I add it from my plugin it won't work. I'm assuming it's a loading issue? But how do I force the JavaScript to not load until after the iframe content or tinymce?
// Fields from metabox:
$pf = 'eri_post_field_';
$meta_keys = [ $pf.'part_email_msg_pre', $pf.'part_email_msg_post' ];
foreach ($meta_keys as $meta_key) {
$meta_value = get_post_meta( $post_id, $meta_key, true );
$settings = array( 'media_buttons' => false, 'textarea_rows' => 10, 'textarea_name' => $meta_key );
wp_editor( $meta_value, $meta_key, $settings );
}
// JavaScript underneath the fields
echo '<script>
var saveNotice = document.getElementById("part_email_save_notice");
var saveNoticeHide = document.getElementById("part_email_save_notice_hide");
var emailMessageFields = [
"part_email_msg_pre",
"part_email_msg_post"
];
emailMessageFields.forEach(function callback(value, index) {
var iframeId = "'.$pf.'" + value + "_ifr";
var iframe = document.getElementById(iframeId);
console.log(iframe); // <-- NULL
// ERROR: Cannot read properties of null (reading "contentWindow")
// var editor = iframe.contentWindow.document.getElementById("tinymce");
// editor.addEventListener("keydown", function (e) {
// saveNotice.style.display = "block";
// saveNoticeHide.style.display = "none";
// console.log("Run: " + value);
// }, { once: true });
// ERROR: Uncaught TypeError: Cannot set properties of null (setting "onload")
document.getElementById(iframeId).onload = function() {
var editor = iframe.contentWindow.document.getElementById("tinymce");
editor.addEventListener("keydown", function (e) {
saveNotice.style.display = "block";
saveNoticeHide.style.display = "none";
console.log("Run: " + value);
}, { once: true });
};
// ERROR: Uncaught ReferenceError: tinymce is not defined
// tinymce.init(...);
});
</script>';
I also tried to insert the JavaScript from add_action('admin_footer'...), but that didn't make a difference. Tried admin_enqueue_scripts as well. Any suggestions?

Call script inside if statement Wordpress

Im trying to conditionally call script depending of language in Wordpress with polylang. I can see the script in Google Inspector but it doesn't work. Script works correctly in customizer.
Code:
<?php
if(pll_current_language() == 'en') : ?>
<script type="text/javascript">
const cartBtn = document.querySelector('.cart button');
const formCart = document.querySelector('div.product.elementor form.cart');
var newBtn = document.createElement('a');
newBtn.innerHTML = "<h1>Back to shop</h1>";
newBtn.classList.add('cart-custom-link');
newBtn.setAttribute("href", "/shop/");
cartBtn.addEventListener('click', function() {
formCart.appendChild(newBtn);
console.log('click');
});
</script>
<?php endif; ?>
<?php
if(pll_current_language() == 'uk') : ?>
<script type="text/javascript">
const cartBtn = document.querySelector('.cart button');
const formCart = document.querySelector('div.product.elementor form.cart');
var newBtn = document.createElement('a');
newBtn.innerHTML = "<h1>Повернутися до магазину</h1>";
newBtn.classList.add('cart-custom-link');
newBtn.setAttribute("href", "/shop-uk/");
cartBtn.addEventListener('click', function() {
formCart.appendChild(newBtn);
console.log('click');
});
</script>
<?php endif; ?>
Is there any solution?
My assumption why the code does not work is because the script code is added (and therefore run) before the DOM tree is ready. Thus, it has to be wrapped in a window.onload handler (or jQuery's $(document).ready();). Also, copy&pasting the JS code for every language isn't really pretty. There's a cleaner solution:
place the code in a .js-file
use a JS-object for the text to be translated
enqueue the script, then use wp_localize_script() on it
like so:
my_cart.js
window.onload = function () {
const cartBtn = document.querySelector('.cart button');
const formCart = document.querySelector('div.product.elementor form.cart');
var newBtn = document.createElement('a');
newBtn.innerHTML = "<h1>"+cart_localize.back_to_shop+"</h1>";
newBtn.classList.add('cart-custom-link');
newBtn.setAttribute("href", "/shop-uk/");
cartBtn.addEventListener('click', function() {
formCart.appendChild(newBtn);
console.log('click');
});
}
Next, within PHP, enqueue the script like so:
function load_localized_scripts() {
$cart_localize = array(
'back_to_shop' => 'Back to shop', // default
);
if (pll_current_language() == 'uk') {
$cart_localize['back_to_shop'] = 'Повернутися до магазину';
}
if (pll_current_language() == 'de') {
$cart_localize['back_to_shop'] = 'Zurück zum Shop';
}
wp_enqueue_script('my-cart', plugin_dir_url( __FILE__ ) . 'js/my_cart.js');
wp_localize_script('my-cart', 'cart_localize', $cart_localize);
}
add_action('wp_enqueue_scripts', 'load_localized_scripts');
The $cart_localize array may contain as many key → value pairs of label => text translation as you like. It is inserted into the JavaScript object named like the 2nd argument of the wp_localized_script function. Then, you can access it within JS using cart_localize.key_name.
Technically, you can also register a Polylang string using pll_register_string named back_to_shop and easily insert the translations you entered under Languages → String translations using the pll__() function:
$cart_localize['back_to_shop'] = pll__('back_to_shop');
I won't fully cover this here, since I'm not sure this matches the way you want to manage translations.

Sending Object Data from AJAX to PHP

I'm trying to send data to a php file to save in database, but I don't have any response. If a checkbox is check, the [obj][idCheckbox] = 1, else [obj][idCheckbox] = 0.
File that sends
var i=0;
var objetoTodasPermissoes = function(){};
var objTodasPermissoes = new objetoTodasPermissoes();
$.each($(".classePermissoes"), function(){
objTodasPermissoes[$(this)[0].id] = 0
i++;
});
$.each($(".classePermissoes:checked"), function(){
alert('ok');
objTodasPermissoes[$(this)[0].id] = 1;
});
console.log(objTodasPermissoes);
$.each($("#userList tr"),function(){
alert(this.id);
var iduser = this.id;
$.ajax({
url:'../json/usuarioperm/savePermissions.php',
data:({
idusuario:iduser,
objTodasPermissoes:objTodasPermissoes,
}),
success:function(a){
Alert("Saved!");
}
});
});
}
the savePermissions.php file.
$iduser = $_POST["iduser"];
$perm_usuarios = $_POST["objTodasPermissoes"]["perm_usuarios"];
$perm_importar = $_POST["objTodasPermissoes"]["perm_importar"];
$perm_log = $_POST["objTodasPermissoes"]["perm_log"];
$perm_proto = $_POST["objTodasPermissoes"]["perm_proto"];
$perm_limpeza = $_POST["objTodasPermissoes"]["perm_limpeza"];
$perm_lixeira = $_POST["objTodasPermissoes"]["perm_lixeira"];
$perm_relatusuarios = $_POST["objTodasPermissoes"]["perm_relatusuarios"];
$perm_deptos = $_POST["objTodasPermissoes"]["perm_deptos"];
$perm_deptospastas = $_POST["objTodasPermissoes"]["perm_deptospastas"];
$perm_empresas = $_POST["objTodasPermissoes"]["perm_empresas"];
mysql_query("UPDATE hospital.users set
perm_usuarios=".$perm_usuarios.",
perm_importar=".$perm_importar.",
perm_log=".$perm_log.",
perm_proto=".$perm_proto.",
perm_limpeza=".$perm_limpeza.",
perm_lixeira=".$perm_lixeira.",
perm_relatusuarios=".$perm_relatusuarios.",
perm_deptos=".$perm_deptos.",
perm_deptospastas=".$perm_deptospastas.",
perm_empresas=".$perm_empresas." where id=".$iduser) or die (mysql_error());
Thank you.
PHP is kind of interesting in that it doesn't pull from $_POST like other forms when Ajax is involved. You actually will need to read the input from php://input
Here is a tiny example
$data = file_get_contents("php://input");
$response = json_decode($data, true ); // True converts to array; blank converts to object
$emailAddr = $response["email"];
Hopefully you can apply that successfully.
Edit: You can add the filter_var command to strip bad characters and sanitize the input.
$emailAddr = filter_var($response["email"], FILTER_SANITIZE_EMAIL);
$firstName = filter_var($response["firstName"], FILTER_SANITIZE_STRING);
While debugging this I would highly recommend using Chrome's Developer mode with the 'network' tab. Find your ajax call near the bottom and you can view exact header info.

Assign Value of Custom Wordpress Post/Page Meta Field to JavaScript Variable

Is there a way via some lines of JavaScript to assign the value of a custom meta field in a Wordpress post/page to a JavaScript variable?
In other words, I've got a custom meta field in all my Wordpress posts and pages named "customamznsearch". I'd like to assign the value of that field to a JavaScript variable with the same name... or different name if need be.
Also, an added bonus would be to also define a static value for the variable if no data is available from that meta field.
This is the code that will be utilizing the "customamznsearch" variable.
<script type="text/javascript">
amzn_assoc_placement = "adunit0";
amzn_assoc_tracking_id = "livcouintheci-20";
amzn_assoc_ad_mode = "search";
amzn_assoc_ad_type = "smart";
amzn_assoc_marketplace = "amazon";
amzn_assoc_region = "US";
amzn_assoc_textlinks = "";
amzn_assoc_linkid = "0c1ce8995df23ae16ec99d3bb32502ec";
amzn_assoc_default_category = "SportingGoods";
amzn_assoc_default_search_phrase = customamznsearch;
</script>
<script src="//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US"></script>
This code will be displayed in an Enhanced Text Widget in the footer of my page. The Enhanced Text widget should be fully capable of supporting Text, HTML, CSS, JavaScript, Flash, Shortcodes, and PHP.
After much research, the following snippet of code was what ended up working (please note that I decided to change the variable to 'amazonadserach'):
var amazonadsearch = "<?php global $post;
$amazonadsearch = get_post_meta($post->ID, 'amazonadsearch', true);
echo $amazonadsearch; ?>";
You can just output javascript code from php like this:
<script>
var customamznsearch = "<?php echo addcslashes($customamznsearch, '"'); ?>";
</script>
Or if you mean to get it from the <meta> tags, then:
function getMeta(metaName) {
var metas = document.getElementsByTagName('meta');
for (i=0; i<metas.length; i++) {
if (metas[i].getAttribute("name") == metaName) {
return metas[i].getAttribute("content");
}
}
return "";
}
var twitterTitle = getMeta("twitter:title");

How to display Colorbox popup in "jQuery ajax() Method" in following scenario?

I'm using PHP, Smarty, jQuery, AJAX, Colorbox - a jQuery lightbox, etc. for my website. There is some old code done using jQuery AJAX method to display the message in popup using standard jQuery library functions. Now I want to replace that typical popup using Colorbox popup. In short Iwant to change the design part only the message part is as it is. I tried to do this but couldn't succeeded yet. Can you help me in doing the necessary changes to the existing old code in order to show the messages in Colorbox popup instead of typical popup? For your reference I'm putting the old code below:
Code from smarty template to give a call to the jQuery AJAX function is as follows:
<span class="submit edit_user_transaction_status" value="{$control_url}{$query_path}?op=edit_user_transaction&page={$page}&txn_no={$user_transaction_details.transaction_no}&transaction_data_assign={$user_transaction_details.transaction_data_assign}&user_id={$user_id}{if $user_name!=''}&user_name={$user_name}{/if}{if $user_email_id!=''}&user_email_id={$user_email_id}{/if}{if $user_group!=''}&user_group={$user_group}&{/if}{if $user_sub_group!=''}&user_sub_group={$user_sub_group}{/if}{if $from_date!=''}&from_date={$from_date}{/if}{if $to_date!=''}&to_date={$to_date}{/if}{if $transaction_status!=''}&transaction_status={$transaction_status}{/if}{if $transaction_no!=''}&transaction_no={$transaction_no}{/if}">Update</span>
The code from js file which contains the existing AJAX code is as follows:
$(document).ready(function() {
//This function is use for edit transaction status
$(document).on('click', '.edit_user_transaction_status', function (e) {
e.preventDefault();
$.colorbox.close();
//for confirmation that status change
var ans=confirm("Are you sure to change status?");
if(!ans) {
return false;
}
var post_url = $(this).attr('value');
var transaction_status_update = $('#transaction_status_update').val();
$.ajax({
type: "POST",
url: post_url+"&transaction_status_update="+transaction_status_update,
data:$('#transaction_form').serialize(),
dataType: 'json',
success: function(data) {
var error = data.login_error;
$(".ui-widget-content").dialog("close");
//This variables use for display title and success massage of transaction update
var dialog_title = data.title;
var dialog_message = data.success_massage;
//This get link where want to rerdirect
var redirect_link = data.href;
var $dialog = $("<div class='ui-state-success'></div>")
.html("<p class='ui-state-error-success'>"+dialog_message+"</p>")
.dialog({
autoOpen: false,
modal:true,
title: dialog_title,
width: 500,
height: 80,
close: function(){
document.location.href =redirect_link;
}
});
$dialog.dialog('open');
}
});
});
});
Now the code snippet from PHP file which contains the PHP code and success message is as follows:
case "edit_user_transaction":
$transaction_no = $request['txn_no'];
$transaction_status_update = $request['transaction_status_update'];
$transaction_data_assign = $request['transaction_data_assign'];
$user_id = $request['user_id'];
$from_date = $request['from_date'];
$to_date = $request['to_date'];
$page = $request['page'];
if($request['transaction_no']!=''){
$query = "&transaction_no=".$request['transaction_no'];
}
// If public transaction status is entered
if($request['transaction_status']!='') {
$query .= "&transaction_status=".$request['transaction_status'];
}
// For checking transaction no is empty, blank, and numeric
if($transaction_no!='' && !empty($transaction_no)) {
$objUserTransactions = new UserTransactions();
$objUserPackages = new UserPackages();
//if transaction status update to success and transaction data not yet assign
if(empty($transaction_data_assign) && $transaction_data_assign == 0 && $transaction_status_update == "success") {
$user_transactions = $objUserTransactions->GetUserTransactionsDetailsByTransactionNo($transaction_no, $user_id);
$i = 0 ;
$j = 0 ;
//Create array related study and test
foreach($user_transactions['transaction_details'] as $my_cart) {
if(!empty($my_cart['pack_id'])) {
if($my_cart['pack_type'] == 'study') {
$data['study'][$i] = $my_cart['pack_id'];
$i++;
}
if($my_cart['pack_type'] == 'test') {
$data['test'][$j]['pack_id'] = $my_cart['pack_id'];
$data['test'][$j]['pack_expiry_date'] = $my_cart['pack_expiry_date'];
$data['test_pack_ids'][$j] = $my_cart['pack_id'];
$j++;
}
}
}
if(!empty($data['study'])) {
$objUserStudyPackage = new UserStudyPackages();
//Update packages sold count & purchase date in package table
$objUserStudyPackage->UpdateStudyPackagePurchaseData($data['study']);
//For insert packages related data to package_user table
foreach($data['study'] as $study_pack_id) {
$objUserPackages->InsertStudyPackagesToPackageUser($study_pack_id, $user_id);
}
}
if(!empty($data['test'])) {
$objUserTestPackage = new UserTestPackages();
//Update packages sold count & purchase date in test package table
$objUserTestPackage->UpdateTestPackagePurchaseData($data['test_pack_ids']);
//For insert test related data to test_user table
foreach($data['test'] as $test_pack_data) {
$objUserPackages->InsertTestPackagesToTestUser($test_pack_data['pack_id'], $test_pack_data['pack_expiry_date'], $user_id);
}
}
//This function is use for update status inprocess to success and transaction_data_assign flag 1
$user_transactions = $objUserTransactions->UpdateTransactionStatusByTransactionNo($transaction_no, $user_id, $transaction_status_update, '1');
} else {
// This function is use for update status
$user_transaction_details = $obj_user_transactions->UpdateTransactionStatusByTransactionNo($transaction_no, $user_id, $transaction_status_update);
}
//Email functionality when status update
include_once("transaction_status_update_email.php");
**$reponse_data['success_massage'] = "Transaction status updated successfully";
$reponse_data['title'] = "Transaction";
$reponse_data['href'] = "view_transactions.php?page=".$page."&from_date=".$from_date."&to_date=".$to_date.$query;
$reponse_data['login_error'] = 'no';
$reponse_data = json_encode($reponse_data);
echo $reponse_data;
die();**
}
break;
The code shown in bold font is the success response message. Can you help me in this regard, please? Thanks in advance.
Yo, you asked for help in PHP chat. Hopefully this helps:
So the dialog portion at the bottom needs to change to support colorbox. Firstly, load all your colorbox stuff. Second, you'll need to create your colorbox content dynamically by either grabbing content from an element on the page or building it on the fly.
You might need to debug some of this but here's generally how you do this...
Delete the entire $dialog variable
var $dialog = .....
And change that to something that will look similar to:
var $dialog = $('<div>').addClass('ui-state-success').append($('<p>').addClass('ui-state-error-success').html(dialog_message));
Then you'll need to do something like this:
$.colorbox({html: $dialog});
If you're having trouble seeing the content that is dynamically built inside your colorbox try calling $.colorbox.resize() on the opened callback:
opened: function(){
$.colorbox.resize();
}
If that doesn't work you may also need to pass a innerWidth/innerHeight or width/height property inside the resize method.

Categories

Resources