TinyMCE Menu Button Icon Doesn't Appear - wordpress

I'm trying to create TinyMCE Menu Button which should open multiple popup window manager. It works fine but the button image doesn't appear.
here is the code. Am I doing something wrong?
(function() {
tinymce.create('tinymce.plugins.shortcodes', {
init : function(ed, url) {
ed.addCommand('scTypography', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 800 + ed.getLang('example.delta_width', 0),
height : 500 + ed.getLang('example.delta_height', 0),
inline : 1
});
});
ed.addCommand('scColumns', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 800 + ed.getLang('example.delta_width', 0),
height : 500 + ed.getLang('example.delta_height', 0),
inline : 1
});
});
ed.addCommand('scButtons', function() {
ed.windowManager.open({
file : url + '/dialog.htm',
width : 800 + ed.getLang('example.delta_width', 0),
height : 500 + ed.getLang('example.delta_height', 0),
inline : 1
});
});
},
createControl : function(n, cm) {
switch (n) {
case 'shortcodes':
var c = cm.createMenuButton('shortcodes', {
title : 'My menu button',
image : '/btn.png'
});
c.onRenderMenu.add(function(c, m) {
var sub;
sub = m.addMenu({title : 'Some item 3'});
sub.add({title : 'Typography', onclick : function() {
tinyMCE.activeEditor.execCommand('scTypography');
}});
sub.add({title : 'Layout Columns', onclick : function() {
tinyMCE.activeEditor.execCommand('scColumns');
}});
sub.add({title : 'Buttons', onclick : function() {
tinyMCE.activeEditor.execCommand('scButtons');
}});
});
// Return the new menu button instance
return c;
}
return null;
},
});
tinymce.PluginManager.add('shortcodes', tinymce.plugins.shortcodes);
})();
I'm not dev, but trying to understand this part to use in Wordpress theme.
Any one can help please?

While the URL to the toolbar image is absolute, you can use the value of the url supplied in init() function that is the URL to the plugin location. For example
image : url + '/btn.png'

Additional to Bretts answer you may need to put the button explicitly into the button config part of the tinymce init.
Example:
I added my own ßplugins buttons to the tinymce UI using this code onInit in my own plugins:
// Register my_button
ed.addButton('my_button', {
title : 'Click me!',
cmd : 'my_command',
image : url + "my_image.png";
});
and here the relevant part of the tinymce init
theme_advanced_buttons1:"style,bold,italic,underline",
theme_advanced_buttons2: "cleanup,save,preview,my_button", // <-- here

Related

Popup dialogue error: Cannot read property 'show' of undefined

I have a problem with showing popup dialogue using angularJS. I'm trying to exercise with the demo site.
https://material.angularjs.org/latest/demo/dialog.
following code is my controller js code.
(function () {
'use strict';
angular
.module('FramesPopup', ['ngRoute', 'ngMaterial' ])
.controller('PopupController', PopupController);
PopupController.$inject = ['$scope'];
function PopupController($scope, $mdDialog) {
$scope.title = 'PopupController';
$scope.status = ' ';
$scope.customFullscreen = false;
$scope.showAlert = function (ev) {
// Appending dialog to document.body to cover sidenav in docs app
// Modal dialogs should fully cover application
// to prevent interaction outside of dialog
$mdDialog.show(
$mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('This is an alert title')
.textContent('You can specify some description text in here.')
.ariaLabel('Alert Dialog Demo')
.ok('Got it!')
.targetEvent(ev)
);
};
activate();
function activate() {
console.log("test");
}
}
})();
The $mdDialog service is missing from the $inject annotation list:
angular
.module('FramesPopup', ['ngRoute', 'ngMaterial' ])
.controller('PopupController', PopupController);
̶P̶o̶p̶u̶p̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶.̶$̶i̶n̶j̶e̶c̶t̶ ̶=̶ ̶[̶'̶$̶s̶c̶o̶p̶e̶'̶]̶;̶
PopupController.$inject = ['$scope','$mdDialog'];
function PopupController($scope, $mdDialog) {
$scope.title = 'PopupController';
$scope.status = ' ';
$scope.customFullscreen = false;
$scope.showAlert = function (ev) {
// Appending dialog to document.body to cover sidenav in docs app
// Modal dialogs should fully cover application
// to prevent interaction outside of dialog
$mdDialog.show(
$mdDialog.alert()

iFrameResizer - readyCallback seems never called

I am trying to use method readyCallback() in iFrameResizer, but it does not seem to work. When I add the callback to parent iframe object, it is never called:
iFrameResize({
log : true,
checkOrigin: false,
minHeight : 800,
maxHeight : 4000,
readyCallback: function(){
// (!) never called
console.log('ready parent callback .. ');
},
messageCallback: function(data){
// works OK
console.log('message callback .. ');
console.log(data);
},
initCallback: function(){
// works OK
window.scrollTo(0,0);
alert("OK initiated");
},
resizedCallback : function(info){
// works OK
console.log(info);
scrollTo(0, info.iframe.offsetTop);
},
heightCalculationMethod : 'taggedElement'
}, '#iframe123');
The iframeResizer.contentWindow.js inside iframe element loads and works OK.
Am I missing something? Thank you.
Turns out that method readyCallback was in wrong place. Here is working setup:
Parent page with iframe element:
iFrameResize({
log : true,
checkOrigin: false,
minHeight : 800,
maxHeight : 4000,
messageCallback: function(data){
console.log('message callback .. ');
console.log(data);
// scroll to top edge of iframe element
scrollTo(0, data.iframe.offsetTop);
},
initCallback: function(){
console.log("OK initiated");
window.scrollTo(0,0);
},
resizedCallback : function(info){
console.log(info);
scrollTo(0, info.iframe.offsetTop);
},
heightCalculationMethod : 'taggedElement'
}, '#iframe123');
Inside iframe element with loaded iframeResizer.contentWindow.js:
// solution 1:
window.iFrameResizer = {
readyCallback: function(){
// scroll parent to top edge of iframe element
window.parentIFrame.scrollToOffset(0,0);
}
}
// solution 2:
window.iFrameResizer = {
readyCallback: function(){
if('parentIFrame' in window){
parentIFrame.sendMessage('Loaded iframe ['+window.parentIFrame.getId()+'].');
}
}
}
// load content window at the end
<script src="/js/iframeResizer.contentWindow.js"></script>

Submitting form using Casperjs Error

I'm trying to scrape products with color and size variations.
Every variation is a form and to get the next variation I'm clicking on radio button and it is doing a form submit action on each click.
I have tried to click it using
1. “casper.getElementsInfo(element)[0].click();”
2. “document.querySelectorAll(element)[2].click();”
3. “casper.thenClick('element');”
4. “casper.evaluate(function(){document.querySelectorAll(element)[2].click();});”
After every click I'm doing a casper wait for 8 seconds !
So here is my problem Casperjs is getting error after clicking the next color/size
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper.then(function () {
self.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
casper.then(function () {
var varitoinCount = document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
var i = 0;
casper.repeat(varitoinCount + 1, function () {
try {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
casper.log('we got to anhoter variatoin ...' + i);
} catch (error) {
console.log(error);
}
i++;
});
});
});
});
try {
casper.run();
} catch (e) {
consol.log("Error..... " + e);
}
(TypeError: undefined is not a constructor )
And btw when I'm doing the same thing in a console it works fine
You have to understand that accessing DOM is not possible in Casper environment. You should switch to browser environment to execute your DOM selectors by using Casper's evaluate method. Basically it used to get some information from within browser or to manually do some actions with javascript. To understand it you have a whole section dedicated for that in official documentation.
That being said, I amended your code to properly click on different color variation inputs.
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper
.start()
.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
var varitoinCount = this.evaluate(function() {
return document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
});
var i = 0;
this.repeat(varitoinCount + 1, function() {
this.evaluate(function(iterator) {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
}, i);
i++;
})
});
try {
casper.run();
} catch (e) {
console.log("Error..... " + e);
}
However it still doesn't change the color since website(for some reason) needs to take 2 clicks to change the color and I suggest that you throw in some waitFor functions to be sure that color has changed.

adding button returns [object][object] in EXTJS

Am having a controller which basically calls a message window that is displayed for a few seconds. Am trying to add a button to this message window, but its returning [object][object].
Controller
success : function(response) {
this.mWin = Ext.create('App.view.GenMessage');
this.mWin.addMessage(true, LANG.SUCT, LANG.SUCTxt1);
}
View
Ext.define('App.view.GenMessage', {
extend : 'Ext.panel.Panel',
alias : 'widget.genmessage',
initComponent : function() {
this.msgCt = App.genMsgCt
this.msgCt.setWidth(300);
},
addMessage : function(status, title, msg) {
if (status == false) {
delay = 3000;
} else {
delay = 2000;
}
Ext.DomHelper.append(this.msgCt, {
html : this.buildMessageBox(status, title, msg)
}, true).slideIn('t').pause(delay).ghost("t", {
remove : false
});
},
/*
* buildMessageBox
*/
buildMessageBox : function(status, title, msg) {
console.log('buildMesssage');
switch (status) {
case true :
var icon = GENHTML.tick;
break;
case false :
var icon = GENHTML.warning;
break;
}
return ['<div class="genMsgDiv">', icon,
'<div class="genMsgHd leftMargin">', title,
'</div><div class="H3 leftMargin">', msg,
'</div></div>'].join('');
}
What i did was declare a button like
var button={
id: 'button1',
text :'Button1'
}
and then add to the div class mentioned above and return
['<div class="genMsgDiv">', button].join();
But, what i see in the screen is [object][object] in place of the button.
Could anyone please tell me what am doing wrong here. Is this the correct way to add the button
EDIT
Since we cannot add a button to a div, i tried doing
var config = Ext.create(Ext.panel.Panel, {
itemId : 'GENMSGPANEL',
height : 150,
cls : 'msg effect1',
border : false,
html : '<div class="genMsgDiv">' + icon +
'<div class="genMsgHd leftMargin">'+ title +
'</div><div class="H3 leftMargin">'+ msg +
'</div></div>',
items : [{
xtype : 'panel',
//cls : 'winTitle',
}, {
xtype : 'form',
itemId : 'GENMSGFORM',
border : false,
title : '',
buttonAlign : 'center',
fieldDefaults : {
msgTarget : 'side',
labelWidth : 110,
size : 30
},
buttons : [{
text : LANG.BTYES,
iconCls : 'icon-tick-tb',
iconAlign : 'right',
cls : 'tip-btn',
action : 'genDelete',
id : 'BTYES'
}, {
text : LANG.BTNO,
iconCls : 'icon-cross-tb',
iconAlign : 'right',
cls : 'tip-btn',
action : 'notDelete',
id : 'BTNO'
}]
}]
});
return config;
But, even this did not return anything
The answer is simple: You cannot add a ExtJS Button into the html config property of a component. This one is just for plain html. ExtJS objects belongs into the items array.
Decide to place your html content into a box (xtype for component) and add this to the items array. Then you can add your button. Don't use the html at all in your case.
You may change/set any required classes. Please note that I haven't check the way you manipulate the DOM.
// you may use a layout to align them
items : [
{
xtype: 'box',
cls : 'msg effect1',
html : '<div class="genMsgDiv">' + icon +
'<div class="genMsgHd leftMargin">'+ title +
'</div><div class="H3 leftMargin">'+ msg +
'</div></div>'
},
{
xtype : 'panel',
//cls : 'winTitle',
},
...

How to add multiple buttons to TinyMCE in WP?

I've followed a tutorial on Nettuts on how to add a custom button to TinyMCE (http://net.tutsplus.com/tutorials/wordpress/wordpress-shortcodes-the-right-way/)
It works great and all, but i want to add many buttons and i wonder if there's a smart way to do this without having to duplicate all the code over and over.
Here's the code i use for adding a button:
add_shortcode("quote", "quote");
function quote( $atts, $content = null ) {
return '<div class="right text">"'.$content.'"</div>';
}
add_action('init', 'add_button');
function add_button() {
if ( current_user_can('edit_posts') && current_user_can('edit_pages') )
{
add_filter('mce_external_plugins', 'add_plugin');
add_filter('mce_buttons_3', 'register_button');
}
}
function register_button($buttons) {
array_push($buttons, "quote");
return $buttons;
}
function add_plugin($plugin_array) {
$plugin_array['quote'] = get_bloginfo('template_url').'/js/customcodes.js';
return $plugin_array;
}
And then i create a customcodes.js file with this code in:
(function() {
tinymce.create('tinymce.plugins.quote', {
init : function(ed, url) {
ed.addButton('quote', {
title : 'Add a Quote',
image : url+'/image.png',
onclick : function() {
ed.selection.setContent('[quote]' + ed.selection.getContent() + '[/quote]');
}
});
},
createControl : function(n, cm) {
return null;
},
});
tinymce.PluginManager.add('quote', tinymce.plugins.quote);
})();
So again, how can i add multiple buttons without having to do all this code for each new button?
Thanks :) Sebastian
If i am understanding your question correctly you want to add to more buttons without having to make duplicates of the register_button($buttons) and add_plugin($plugin_array) functions?
I know this is an old question, but there is a way to do it without duplicating the functions.
Just go into your customcodes.js and in the init : function(ed, url) create new buttons just like you did the first one, so it would look as such:
init : function(ed, url) {
/* your original button */
ed.addButton('quote', {
title : 'Add a Quote',
image : url+'/image.png',
onclick : function() {
ed.selection.setContent('[quote]' + ed.selection.getContent() + '[/quote]');
}
});
/* your second button */
ed.addButton('singlequote', {
title : 'Add a Single Quote',
image : url+'/image.png',
onclick : function() {
ed.selection.setContent('[singlequote]' + ed.selection.getContent() + '[/singlequote]');
}
});
}
And so forth, as many buttons as you require.
After that just head back to your register_button($buttons) function and update the array_push().
So whilst, when you had only one button to add it looked like this:
function register_button($buttons) {
array_push($buttons, "quote");
return $buttons; }
Now that you created your new buttons this function would look like this.
function register_button($buttons) {
array_push($buttons, "quote", "singlequote");
return $buttons; }
And so on, depending how many new buttons youve added.
You do not need to duplicate functions, or add new actions and filters to add new buttons to your tinyMCE.
You just create the new buttons inside your tinyMCE plug-in and list the names of the buttons youve created inside the array_push().
Perhaps you werent aware that array_push() accepts multiple push values.
Here is its documentation on php.net
Modify the php at step 3 to push your second buttons :
//Step 3: Register Our Button
function register_button($buttons) {
array_push($buttons, "BOUTON1");
array_push($buttons, "BOUTON2");
return $buttons;
}
Add a specific pass to that BOUTON2 :
//Step 4: Register Our TinyMCE Plugin
function add_plugin($plugin_array) {
$plugin_array['BOUTON1'] = '/yourpathtojs/bouton1.js';
$plugin_array['BOUTON2'] = '/yourpathtojs/bouton2.js';
return $plugin_array;
}
Then you have distinct files for each, look on the use of PLUG1 and BOUTON1, its better that on nettuts because they dont made distinction with the term 'quote' :
bouton1.js :
(function() {
tinymce.create('tinymce.plugins.PLUG1', {
init : function(ed, url) {
ed.addButton('BOUTON1', {
title : 'You', image : url+'/image.png',
onclick : function() { ed.selection.setContent('[thumb from="youtube" code="'+ed.selection.getContent()+'"]'); }
});
},
createControl : function(n, cm) {
return null;
},
});
tinymce.PluginManager.add('BOUTON1', tinymce.plugins.PLUG1);
})();
bouton2.js :
(function() {
tinymce.create('tinymce.plugins.PLUG2', {
init : function(ed, url) {
ed.addButton('BOUTON2', {
title : 'Vim', image : url+'/image.png',
onclick : function() { ed.selection.setContent('[thumb from="vimeo" code="'+ed.selection.getContent()+'"]'); }
});
},
createControl : function(n, cm) {
return null;
},
});
tinymce.PluginManager.add('BOUTON2', tinymce.plugins.PLUG2);
})();
Apart from maybe adding the extra button code inside your already existing functions, I don't think there's a way to do what you're trying.
Unfortunately, that's the code to add a button, so if you want to add another button you've got to add the code again.
If the buttons you wanted to add were similar in almost every way, you could maybe get away with doing a foreach {} followed by a switch(){case '':} where you feed the data through but unless all your buttons do the same thing this seems a bit redundant.
If all you're trying to do is keep your function.php file tidy then I suggest putting each button in a separate .php file named the same as the main function, in a folder called inc or includes inside your template, then include them like so:
$temp_path = 'http//www.yourdomain.com/wp-content/theme/yourtheme/includes/';
include $temp_path.'file1.php';
include $temp_path.'file2.php';
I'm using a temp_path variable because for some reason bloginfo() and get_bloginfo() just don't seem to work in the functions file.
On a side note, even though it's just for personal use, try to use much more unique function names, quote could be anything, tinymce_quote_button that's definitely what it is. This avoids potential function name clashes later.
If all the buttons are related and you want to add them all at once (ie you don't need to pick and choose which buttons get added, you could just duplicate the ed.addButton calls in the init call. It would make sense to encapsulate each addbutton call into it's own function,
(function() {
function addQuoteButton(ed, url){
ed.addButton('quote', {
title : 'Add a Quote',
image : url+'/image.png',
onclick : function() {
ed.selection.setContent('[quote]' + ed.selection.getContent() + '[/quote]');
}
});
}
function addOtherButton(ed, url){
// functionality to add another button.
}
tinymce.create('tinymce.plugins.quote', {
init : function(ed, url) {
addQuoteButton(ed, url);
addOtherButton(ed,url);
},
createControl : function(n, cm) {
return null;
},
});
tinymce.PluginManager.add('quote', tinymce.plugins.quote);
})();
to get further decomposition, you could then split the add*Button functions out into their own files (as suggested by #DouglasMarken).

Resources