I have the same problem as in this question here, which is the conflict between jQuery UI and Bootstrap. The given answer from Darkseal
$.widget.bridge('uibutton', $.ui.button);
completely solved my problem for the "button"-widget. But it seems to me, that also the "buttonset"-widget reveals a conflict between the two libraries but
$.widget.bridge('uibuttonset', $.ui.buttonset);
does not do the trick for me. Am I doing something wrong?
This is an older question but I thought I'd share my fix for this.
You don't need the..
$.widget.bridge('uibuttonset', $.ui.buttonset);
There isn't any conflict there with Bootstrap (v3.3.6). The issue is $.ui.buttonset makes calls to .button() which isn't the the new name you declared so the conflict lives on. To fix this, I updated the calls to .button() inside .buttonset() to match the new name, "uibutton" or whatever you declare it as.
Below is my code for version jQuery UI 1.11.4. Perhaps there is an easier fix, but I've not come across it.
$.widget( "ui.buttonset", {
version: "1.11.4",
options: {
items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
},
_create: function() {
this.element.addClass( "ui-buttonset" );
},
_init: function() {
this.refresh();
},
_setOption: function( key, value ) {
if ( key === "disabled" ) {
this.buttons.uibutton( "option", key, value );
}
this._super( key, value );
},
refresh: function() {
var rtl = this.element.css( "direction" ) === "rtl",
allButtons = this.element.find( this.options.items ),
existingButtons = allButtons.filter( ":ui-button" );
// Initialize new buttons
allButtons.not( ":ui-button" ).uibutton();
// Refresh existing buttons
existingButtons.uibutton( "refresh" );
this.buttons = allButtons
.map(function() {
return $( this ).uibutton( "widget" )[ 0 ];
})
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
.filter( ":first" )
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
.end()
.filter( ":last" )
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
.end()
.end();
},
_destroy: function() {
this.element.removeClass( "ui-buttonset" );
this.buttons
.map(function() {
return $( this ).uibutton( "widget" )[ 0 ];
})
.removeClass( "ui-corner-left ui-corner-right" )
.end()
.uibutton( "destroy" );
}
});
I hope that helps you and everyone else.
Related
I'am working on a web app with datatable.
I've done global research bar and individual research bar, like this example: https://datatables.net/examples/api/multi_filter.html
Now what I want to do is to start research by the first letter only in the individuals columns.
I tried to do this whith global research and it worked fine, thank to this :
$(document).ready(function() {
var table=$('#example').DataTable( {
responsive: true
} );
$('.dataTables_filter input').on( 'keyup', function (e) {
var regExSearch = '\\b' + this.value;
table.search(regExSearch, true, false).draw();
});
} );
But this is not what I want
And I have programmed my individual research like that :
table.columns(':gt(1)').every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search(this.value )
.draw();
}
} );
} );
I tried to use the same logic as global research while adding
.search('\\b' +this.value )
but when I try to search something, nothing is returned.
Maybe I do something wrong, does anyone know how to do that ?
Ok I was so close.
The only thing I had to do is :
table.columns(':gt(1)').every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search('\^'+this.value, true, false ) // regex=true, smart=false
.draw();
}
} );
} );
And it work.
I've built a custom website using Wordpress and WooCommerce and have installed Select2 to generate custom selects which is working fine. The issue I am having is with some of the selects on the WooCommerce pages, specifically those that trigger an event on change.
The custom selects successfully change the option selected, but the issue arises with selects that are meant to trigger an event. For example, the colour variation dropdown on the product page or the 'Sort By' select on the store page.
I've looked through the WooCommerce JS files and discovered some WooCommerce specific events that are triggered when a selection is made using the actual select box but I'm not sure how to implement this when using Select2 instead.
Here is a copy of the WooCommerce JS in relation to the event I'm talking about (in this case the change to the select for product variations):
.on( 'change', '.variations select', function() {
$form.find( 'input[name="variation_id"], input.variation_id' ).val( '' ).change();
$form.find( '.wc-no-matching-variations' ).remove();
if ( $use_ajax ) {
if ( $xhr ) {
$xhr.abort();
}
var all_attributes_chosen = true;
var some_attributes_chosen = false;
var data = {};
$form.find( '.variations select' ).each( function() {
var attribute_name = $( this ).data( 'attribute_name' ) || $( this ).attr( 'name' );
if ( $( this ).val().length === 0 ) {
all_attributes_chosen = false;
} else {
some_attributes_chosen = true;
}
data[ attribute_name ] = $( this ).val();
});
if ( all_attributes_chosen ) {
// Get a matchihng variation via ajax
data.product_id = $product_id;
$xhr = $.ajax( {
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_variation' ),
type: 'POST',
data: data,
success: function( variation ) {
if ( variation ) {
$form.find( 'input[name="variation_id"], input.variation_id' )
.val( variation.variation_id )
.change();
$form.trigger( 'found_variation', [ variation ] );
} else {
$form.trigger( 'reset_data' );
$form.find( '.single_variation_wrap' ).after( '<p class="wc-no-matching-variations woocommerce-info">' + wc_add_to_cart_variation_params.i18n_no_matching_variations_text + '</p>' );
$form.find( '.wc-no-matching-variations' ).slideDown( 200 );
}
}
} );
} else {
$form.trigger( 'reset_data' );
}
if ( some_attributes_chosen ) {
if ( $reset_variations.css( 'visibility' ) === 'hidden' ) {
$reset_variations.css( 'visibility', 'visible' ).hide().fadeIn();
}
} else {
$reset_variations.css( 'visibility', 'hidden' );
}
} else {
$form.trigger( 'woocommerce_variation_select_change' );
$form.trigger( 'check_variations', [ '', false ] );
$( this ).blur();
}
// Custom event for when variation selection has been changed
$form.trigger( 'woocommerce_variation_has_changed' );
} )
And then my own attempt to utilise this event:
$('#pa_colour').select2();
$('#pa_colour').on('change', function(){
var $form = $(this).parents('form');
$form.trigger( 'woocommerce_variation_select_change' );
$form.trigger( 'woocommerce_variation_has_changed' );
});
Unfortunately the site isn't live yet so I can't provide a link but hopefully you get the idea.
If someone can help me here I'd be so appreciative, I'm not exactly sure how Wordpress hooks (if this is what this is) work and I may be just missing something obvious.
Thanks,
Kathryn
This isn't a solution exactly, but I ended up replacing the Select2 plugin with the Selectric plugin and that works perfectly. Oh well! Thanks guys. http://lcdsantos.github.io/jQuery-Selectric/
I came across the same issue and found a solution in the last comment in this thread Select2 not showing selected value
The comment by Matt inspired by Kevin suggested wrapping the select2 call in $(window).bind("load", function() {...}); which worked for me.
Kudos to those guys.
On the product category page, when someone clicks "Add to cart", woocommerce adds "View cart" below this button through Ajax. I found that the script which handle this is /assets/js/frontend/add-to-cart.js
Now, I want to add also "Procceed to checkout", so someone can go to checkout immediately.
This is the output of the script:
jQuery( function( $ ) {
// wc_add_to_cart_params is required to continue, ensure the object exists
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
// Ajax add to cart
$( document ).on( 'click', '.add_to_cart_button', function(e) {
// AJAX add to cart request
var $thisbutton = $( this );
if ( $thisbutton.is( '.product_type_simple' ) ) {
if ( ! $thisbutton.attr( 'data-product_id' ) )
return true;
$thisbutton.removeClass( 'added' );
$thisbutton.addClass( 'loading' );
var data = {
action: 'woocommerce_add_to_cart',
};
$.each( $thisbutton.data(), function( key, value ) {
data[key] = value;
});
// Trigger event
$( 'body' ).trigger( 'adding_to_cart', [ $thisbutton, data ] );
// Ajax action
$.post( wc_add_to_cart_params.ajax_url, data, function( response ) {
if ( ! response )
return;
var this_page = window.location.toString();
this_page = this_page.replace( 'add-to-cart', 'added-to-cart' );
if ( response.error && response.product_url ) {
window.location = response.product_url;
return;
}
// Redirect to cart option
if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
window.location = wc_add_to_cart_params.cart_url;
return;
} else {
$thisbutton.removeClass( 'loading' );
fragments = response.fragments;
cart_hash = response.cart_hash;
// Block fragments class
if ( fragments ) {
$.each( fragments, function( key, value ) {
$( key ).addClass( 'updating' );
});
}
// Block widgets and fragments
$( '.shop_table.cart, .updating, .cart_totals' ).fadeTo( '400', '0.6' ).block({
message: null,
overlayCSS: {
opacity: 0.6
}
});
// Changes button classes
$thisbutton.addClass( 'added' );
// View cart text
if ( ! wc_add_to_cart_params.is_cart && $thisbutton.parent().find( '.added_to_cart' ).size() === 0 ) {
$thisbutton.after( ' <a href="' + wc_add_to_cart_params.cart_url + '" class="added_to_cart wc-forward" title="' +
wc_add_to_cart_params.i18n_view_cart + '">' + wc_add_to_cart_params.i18n_view_cart + '</a>' );
}
// Replace fragments
if ( fragments ) {
$.each( fragments, function( key, value ) {
$( key ).replaceWith( value );
});
}
// Unblock
$( '.widget_shopping_cart, .updating' ).stop( true ).css( 'opacity', '1' ).unblock();
// Cart page elements
$( '.shop_table.cart' ).load( this_page + ' .shop_table.cart:eq(0) > *', function() {
$( '.shop_table.cart' ).stop( true ).css( 'opacity', '1' ).unblock();
$( 'body' ).trigger( 'cart_page_refreshed' );
});
$( '.cart_totals' ).load( this_page + ' .cart_totals:eq(0) > *', function() {
$( '.cart_totals' ).stop( true ).css( 'opacity', '1' ).unblock();
});
// Trigger event so themes can refresh other areas
$( 'body' ).trigger( 'added_to_cart', [ fragments, cart_hash, $thisbutton ] );
}
});
return false;
}
return true;
});
Is there anybody who has done something similar?
If you look here from the Woocommerce repo, you can see that add-to-cart.js is localized from that class.
Unfortunately, there isn't a filter to just add your own link. What you could try is copying add-to-cart.js to your theme and set the new src of the registered add-to-cart.js to your new local copy, by using this method.
From there you can alter the this conditional found in Woocommerce repo.
So, technically yes, you could could this, but there are caveats:
You would need to repeat this process for variation products
If translation is a concern, you need to address that as well
Any time the plugin updates, you now have to comb through these files for any differences that could break functionality or cause a security issue.
I'm using JQuery Tool Tip in on my HTML page and in that tool tip I've User Name and a Sign Out Link.
Now I'm trying to bind the event in my backbone view, on the id of the Sign Out Link.
But the event is not fired.
I removed the tool tip code and then when i clicked on the sign out link the event got fired.
So question here is - Is it possible to bind the backbone event on jquery tool tip? If not than what would be the work around.
Some code snippets
This is the function which is used to apply jquery tool tip
jQuery(function () {
jQuery.widget("ui.tooltip", jQuery.ui.tooltip, {
options: {
content: function () {
// self.addDescendant('toolTip', {selector: templ.loginHelpContent, view: tt});
return jQuery(templ.loginHelpContent).html();
},
show: null,
close: function (event, ui) {
ui.tooltip.hover(
function () {
jQuery(this).stop(true).fadeTo(400, 1);
},
function () {
jQuery(this).fadeOut("400", function () {
jQuery(this).remove();
})
});
},
position: {
my: "left-190 bottom-18",
using: function( position, feedback ) {
jQuery( this ).css( position );
jQuery( "<div>" )
// .addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
},
}
});
jQuery(templ.loginHelpIcon).tooltip();
});
and the HTML
<span id=loginHelpContent style="display:none">
Not Elizabeth Murphy? <a id="logoutLink" style="color:blue;text-decoration: none">Sign out</a><br> and login as a different user.
</span>
When I tried to bind and event on 'logoutLink' it didn't worked.
You can listen to the "tooltipopen" event ".tooltip tooltipopen": "listenTooltip" and in listenTooltip function :
listenTooltip: function( e ) {
var tooltip = $( e )
}
Now you can bind listener to tooltip in this function
I know a lot of people ask questions about plug-ins and callbacks (and I've read lots of them - that's how i got this far) so please, bear with me. I tried my hand at a very simple hide/show accordion type plugin for FAQs and was successful at getting it to do what I wanted. However, as I am still learning, I am not really sure how some things work.
I was able to add a callback to the plugin after reading this question and a few others.
My question is: Is this code correct and is there a better way to implement this callback?
Here's a working sample and the code below.
Thank you for your time.
( function($) {
$.fn.simpleFAQ = function( options, callback ) {
// define default options
var defaults = {
textExpand : "Expand all",
textCollapse : "Collapse all",
displayAll : false,
toggleSpeed : 250
};
var options = $.extend( defaults, options );
// callback
if( typeof callback != "function" ) { callback = function(){} }
this.each( function () {
obj = $(this);
// insert FAQ expand all/collapes all text before FAQ
var txt = '<span class="simple_jfaqText">' + options.textExpand + ' / ' + options.textCollapse + '</span>';
$( txt ).insertBefore( obj );
// add class to desired FAQ element
obj.addClass( 'simple_jfaq' );
// show/hide faq answers according to displayAll option
( options.displayAll == false ) ? ddDisplay = 'none' : ddDisplay = 'block';
obj.children( 'dd' ).css( 'display', ddDisplay );
// add classes according to <dd> state (hidden/visible)
obj.children( 'dd:visible' ).prev( 'dt' ).addClass( 'expanded' );
obj.children( 'dd:hidden' ).prev( 'dt' ).addClass( 'collapsed' );
obj.children( 'dt' )
.click( function() {
// show/hide all answers (dd elements) on click
$(this).nextUntil( 'dt' ).slideToggle( options.toggleSpeed, callback );
// dt class change on click
$(this).toggleClass( 'collapsed' ).toggleClass( 'expanded' ); })
.hover( function() { $(this).toggleClass( 'hover' ); }, function(){ $(this).toggleClass( 'hover' ); });
});
// Expand All
obj.prev( 'span' ).children( 'a[rel=jfaq_expand]' ).click( function() {
// show all answers
$(this).parent( 'span' ).next( '.simple_jfaq' ).children( 'dd:hidden' ).slideToggle( options.toggleSpeed );
setTimeout( callback, options.toggleSpeed )
// change classes
$(this).parent( 'span' ).next( '.simple_jfaq' ).children( 'dt' ).removeClass( 'collapsed' ).addClass( 'expanded' );
});
// Collapse all
obj.prev( 'span' ).children( 'a[rel=jfaq_collapse]' ).click( function() {
// hide all answers
$(this).parent( 'span' ).next( '.simple_jfaq' ).children( 'dd:visible' ).slideToggle( options.toggleSpeed );
setTimeout( callback, options.toggleSpeed );
// change classes
$(this).parent( 'span' ).next( '.simple_jfaq' ).children( 'dt' ).removeClass( 'expanded' ).addClass( 'collapsed' );
});
};
})( jQuery );
I would recommend using jQuery's built in event system for this. You can trigger an event on any node, then the user of the FAQ code could bind to that event on that node. You can even pass data to the binding function.
Of course, my real recommendation is to use my plug-in of the same name. :)
It might be nice if the callback would execute in the context of some relevant element.
var clicked = this;
setTimeout(function() { callback.call(clicked); }, options.toggleSpeed );