I have installed a pop-up plugin on my Wordpress site. The pop-up has a CTA button that links to an inner page and I would like to track clicks on the button using Google events tracking.
This is the Google analytics code I'm using: onClick="_gaq.push(['_trackEvent', 'Popup', 'click']);"
and the following code is from the plugin which outputs the CTA button link:
if ( $has_cta ) {
$cta_button_tag = sprintf(
'%3$s',
esc_url( $this->cta_link ),
esc_attr( $cta_target ),
esc_html( $this->cta_label )
);
Firstly, I strongly recommend you upgrade your tracking to Google universal analytics (you're currently still on ga.js classic)
Just add your onclick event to the a element then:
if ( $has_cta ) {
$cta_button_tag = sprintf(
'%3$s',
esc_url( $this->cta_link ),
esc_attr( $cta_target ),
esc_html( $this->cta_label )
);
This will certainly fire off the tracking but it may be cancelled by the browser. You therefore need to investigate the hitCallback feature of GA.
Related
I see in CKEitor 4.5 there is a new drag and drop system. I would like to drop external DIVs or SPANs into my CkEditor and have them turn into "placeholders" "fake objects" or "protected source" objects. I.e., the dropped object should turn into arbitrary HTML that's related to the content.
The available demos seem to be about uploading content, but this is different and I'd appreciate a demo ...
Yes, it is possible. CKEditor 4.5 is in the beta phase at the moment, what means there is no tutorials yet, but here is sample how to do it.
First, you need to mark your data on dragstart. You can simple set text:
dragstart( evt ) {
evt.dataTransfer.setData( 'text', 'foo' );
} );
But then you need to make your text unique, otherwise every time someone drop foo it will be recognize as your container.
I prefer to use CKEditor data transfer facade, which let you use custom data type on every browser (including IE 8+):
dragstart( evt ) {
var evt = { data: { $: $evt } }; // Create CKEditor event.
CKEDITOR.plugins.clipboard.initDragDataTransfer( evt );
evt.data.dataTransfer.setData( 'mydatatype', true );
// Some text need to be set, otherwise drop event will not be fired.
evt.data.dataTransfer.setData( 'text', 'x' );
} );
Then in the CKEDITOR you can recognize this data and set your html to be dropped. You can replace dropped content whit whatever you need. Simple set text/html data in the drop event:
editor.on( 'drop', function( evt ) {
var dataTransfer = evt.data.dataTransfer;
if ( dataTransfer.getData( 'mydatatype' ) ) {
dataTransfer.setData( 'text/html', '<div>Bar</div>' );
}
} );
You can find working sample here: http://jsfiddle.net/oqzy8dog/3/
I'm working on a CKEditor plugin for annotating text and adding margin comments, but I'd like some of my custom toolbar buttons to be enabled only when the user has already selected a range of text. Whenever the user is typing, or the cursor is at a single-point (instead of a range), the buttons (and their associated commands) should be disabled.
I'm a pretty experienced plugin author, and I've spent a fair amount of time hunting through the core API docs, but I haven't found anything yet that looks like it'll help.
Your case is a little tricky, because selection change event is not well implemented across browsers, FF is the main problem.
In your case you'll going to need check selection changes very frequently, as you're interested in all selection changes therefore CKEditor selectionChange won't fit it.
Fortunately there's a selectionCheck event in editor that fires much more frequently and is implemented for FF.
Solution:
Here you have init method of a plugin that I've mocked to solve your problem. It will disable / enable Source button the way you explained.
I've already added throttling to this function, so that customers with less expansive machine can admire your feature :)
init: function( editor ) {
// Funciton depending on editor selection (taken from the scope) will set the state of our command.
function RefreshState() {
var editable = editor.editable(),
// Command that we want to control.
command = editor.getCommand( 'source' ),
range,
commandState;
if ( !editable ) {
// It might be a case that editable is not yet ready.
return;
}
// We assume only one range.
range = editable.getDocument().getSelection().getRanges()[ 0 ];
// The state we're about to set for the command.
commandState = ( range && !range.collapsed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
command.setState( commandState );
}
// We'll use throttled function calls, because this event can be fired very, very frequently.
var throttledFunction = CKEDITOR.tools.eventsBuffer( 250, RefreshState );
// Now this is the event that detects all the selection changes.
editor.on( 'selectionCheck', throttledFunction.input );
// You'll most likely also want to execute this function as soon as editor is ready.
editor.on( 'instanceReady', function( evt ) {
// Also do state refresh on instanceReady.
RefreshState();
} );
}
If you are working on a plugin, I guess that you are registering commands with the ckeditor.
In that case, you should provide a refresh method, which will be called by the CKEditor to update the state of the button when needed:
Defined by the command definition, a function to determine the command
state. It will be invoked when the editor has its states or selection
changed.
You can see examples of implementation in several of the plugins developed by the CKEditor team. Here is one taken from the source code of the Link plugin:
refresh: function( editor, path ) {
var element = path.lastElement && path.lastElement.getAscendant( 'a', true );
if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() )
this.setState( CKEDITOR.TRISTATE_OFF );
else
this.setState( CKEDITOR.TRISTATE_DISABLED );
}
Here is the code required to answer exactly the question using the refresh method as suggested by Gyum Fox.
I mention that to make it work, contextSensitive has to be set to 1.
editor.addCommand( 'myCommand', {
exec: function( editor ) {
// Custom logic of the command
},
refresh: function( editor ) {
var editable = editor.editable();
range = editable.getDocument().getSelection().getRanges()[ 0 ]; // We assume only one range.
commandState = ( range && !range.collapsed ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;
this.setState( commandState );
},
contextSensitive: 1
});
EDIT: I noticed some refresh issues on my side. So, because of that, I'd go for the Marek Lewandowski answer.
I am trying to remove the ability to click on an image in woocommerce's product featured images, so that you can no longer click on the image and make it bigger.
Not much skills with css so simple explanations are appreciated.
I have the product-image.php open and I know how to enter custom code into my theme.
Anyone?
Change this line inthe product-image.php
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image_link, $image_title, $image ), $post->ID );
to
echo apply_filters( 'woocommerce_single_product_image_html', sprintf( '%s', $image ), $post->ID );
and in the product-thumbnails.php file, change
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', sprintf( '%s', $image_link, $image_class, $image_title, $image ), $attachment_id, $post->ID, $image_class );
to
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', sprintf( '<a title="%s">%s</a>', $image_title, $image ), $attachment_id, $post->ID, $image_class );
Doing the above should remove the ability to click on the image and make it bigger.
works perfectly however I'm facing one issue because of it. I set up my page so that when I click a thumbnail it replaces the product image. When I apply your rule to make the product image unclickable, then the other js doesnt work anymore. Do you have any idea how I could make both work together? The jquery Im using is
(function($){
$(document).ready(function(){
$('.thumbnails a.zoom').click(function(event){
event.preventDefault();
var thumb_url = $(this).find('img').attr('src');
$('.woocommerce-main-image img').attr('src', thumb_url );
});
});
})(jQuery);
Try this
.woocommerce-product-gallery__image {
pointer-events: none;
It works perfectly for me.
Check if your theme has a custom CSS section and just paste it there.
First of all, if you want to replace single-product.php template you have to create a new one in you own theme folder.
Example: wp-content/themes/woocommerce/single-product.php
<?php
global $product;
echo $product->get_image();
?>
Will output only img tag without link and any div's.
This might be helpful https://docs.woocommerce.com/wc-apidocs/source-class-WC_Block_Featured_Product.html#156-175
I was looking for how to disable the zoom and lightbox on product images and the following code (inserted on functions.php) helped:
add_action( 'after_setup_theme', 'remove_pgz_theme_support', 100 );
function remove_pgz_theme_support() {
remove_theme_support( 'wc-product-gallery-zoom' );
remove_theme_support( 'wc-product-gallery-lightbox' );
}
This had, however, the side effect of still allowing users to click on the image, sending them to the direct link of the file. On the OceanWP theme I found this to work (insert it on your css):
img.wp-post-image {
pointer-events:none !important;
This will work for the featured image, but if you have other images in the same product gallery, those ones will still be clickable. To disable the click on those too, insert this extra code on your css:
div.woocommerce-product-gallery__image.flex-active-slide {
pointer-events:none !important;
Hope it helps you!
I'm beginning to work on Bootstrap in Yii framework and finding some difficulties in making it work the way I want to.
And have not found anything useful in the docs, although I might have missed something.
I have the navbar like this:
<?php $this->widget('bootstrap.widgets.TbNavbar', array(
'collapse'=>true, // requires bootstrap-responsive.css
'fixed'=>'none',
'brand'=>false,
'items'=>array(
array(
'class'=>'bootstrap.widgets.TbMenu',
'items'=>array(
array('label'=>'Home', 'url'=>'#', 'active'=>true),
array('label'=>'Link', 'url'=>'#'),
array('label'=>'Dropdown', 'url'=>'#', 'items'=>array(
array('label'=>'Action', 'url'=>'#'),
array('label'=>'Another action', 'url'=>'#'),
array('label'=>'Something else here', 'url'=>'#'),
'---',
array('label'=>'NAV HEADER'),
array('label'=>'Separated link', 'url'=>'#'),
array('label'=>'One more separated link', 'url'=>'#'),
)),
),
),
),
));
?>
By default submenu drop out by Click event, but I want to submenu drop out at mouseover event. How do it, please help. Thanks in advance.
Im using bootstrap with Yii for a while and submenus popups automatically. Check also this link http://www.bootply.com/60842 which shows that bootstrap submenus popups automatically on mouseover.
You will be probably overriding/missing some css/javascript files. Also check console if your page has no errors after loading.
Find bootstrap.js in the asset folder of the bootstrap extension folder.
Replace the following (rows 797- 800) :
.on('click.dropdown.data-api', clearMenus)
.on('mouseover.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('mouseover.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
.on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
to becomes
.on('click.dropdown.data-api', clearMenus)
.on('mouseover.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('mouseover.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
.on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
In order to work, you have to clean the asset folder in the main directory to generate once from the asset you've just changed.
I'm trying to call close function for CKEditor dialog box from my custom plugin. Just like it happens when you are clicking on smile in "smileys" plugin, but I can't find out how can I do the same in my own plugin.
Thanx for reply!
I've got the solution.
In my plugin I needed to call close function from "CKEDITOR.dialog.add" in "onLoad" section. So, I have to do this:
CKEDITOR.dialog.add( 'plugin_name', function( editor ){
onLoad: function( event ){
[...some code...]
event.sender.hide();
}
}
CKEDITOR.dialog.getCurrent().hide()
I propose you do it the same way it is done by CKEditor Dialog plugin internally. See line 535 in plugin.js
By clicking the button or firing the cancel event you ensure correct handling by the plugin.
Code sample:
// If there's a Cancel button, click it, else just fire the cancel event and hide the dialog.
button = CKEDITOR.dialog.getCurrent().getButton( 'cancel' );
if ( button )
CKEDITOR.tools.setTimeout( button.click, 0, button );
else {
if ( CKEDITOR.dialog.getCurrent().fire( 'cancel', { hide : true } ).hide !== false )
CKEDITOR.dialog.getCurrent().hide();
}