Has anyone got chosen.js working on Magento 1.7x?
I've seen one thread talking about problems with it and Magento validation.
If someone knows if it works can he show me how to do it?
Old question, but I just ran into this issue, so I came up with an alternate solution, inspired by the answer given by @kevnk
My solution is to replace all selects, site wide, but it can simply be adjusted to target specific selects.
This is done in magento EE 1.12, but I see no reason for it to work in other versions.
I created the following script which does the following:
isValidation
method of Validation with a fallback to the original (now named _isValidation
) The original will be called for anything other than select, or if a select does not have a matching chosen element insertAdvice
method of Validation. This purely changes the container to the matching chosen element, so the validation advice is placed after thatSimply include this code via layout to your site.
document.observe("dom:loaded", function() {
Object.extend(Validation, {
isVisible : function(elm) {
if ($(elm).tagName == 'SELECT') {
if ($(elm.id.replace(new RegExp('-', 'g'), '_') + '_chosen') != undefined) {
// need to be careful of payment types, as they may not be selected
// so we do not want to validate the children.
// determine the parent ul element of this select is display none, and if so,
// do not validate it.
var parentUL = elm.up('ul');
if(typeof parentUL != 'undefined' && parentUL.style.display == 'none')
{
return false;
}
return true;
}
}
return this._isVisible(elm);
},
_isVisible : function(elm) {
while (elm.tagName != 'BODY') {
if (!$(elm).visible()) return false;
elm = elm.parentNode;
}
return true;
},
insertAdvice : function(elm, advice){
if($(elm.id.replace(new RegExp('-', 'g'),'_')+'_chosen') != undefined) {
var container = $(elm.id.replace(new RegExp('-', 'g'),'_')+'_chosen');
} else {
var container = $(elm).up('.field-row');
}
if(container){
Element.insert(container, {after: advice});
} else if (elm.up('td.value')) {
elm.up('td.value').insert({bottom: advice});
} else if (elm.advaiceContainer && $(elm.advaiceContainer)) {
$(elm.advaiceContainer).update(advice);
}
else {
switch (elm.type.toLowerCase()) {
case 'checkbox':
case 'radio':
var p = elm.parentNode;
if(p) {
Element.insert(p, {'bottom': advice});
} else {
Element.insert(elm, {'after': advice});
}
break;
default:
Element.insert(elm, {'after': advice});
}
}
}
});
jQuery("select").chosen(
{
disable_search_threshold: 10,
no_results_text: "Sorry, nothing found!",
width: "100%",
inherit_select_classes: true
});
jQuery("select").chosen().change( function(e){
Validation.validate(e.target);
});
});
After using this, I found that in checkout (OPC), the payment methods select boxes are not being transformed, as well as shipping, the state selection box is still visible. The issue is AJAXED in content.
I fixe dthis by wrapping the realoadProgressBlock method in checkout, to re-init the chosen object, thus fixing ajaxed in content.
if(typeof Checkout != 'undefined')
{
Checkout.prototype.reloadProgressBlock = Checkout.prototype.reloadProgressBlock.wrap(function (parent) {
jQuery("select").chosen(
{
disable_search_threshold: 10,
no_results_text: "Sorry, nothing found!",
width: "84%",
inherit_select_classes: true
});
parent();
});
}
EDIT:
A slight adjustment is needed in the code above, to make this work in magento EE 1.13 (possibly EE1.14/CE 1.8/1.9 ?)
the call to parent();
in the code above must be changed to parent(this.currentStep);
Hope this is of help to someone.
I've managed to get it working in the admin. You will need to use event.simulate.js (https://github.com/kangax/protolicious/blob/5b56fdafcd7d7662c9d648534225039b2e78e371/event.simulate.js) if you would like it to fire when you change the select element. I added a JS file to instantiate chosen and it worked fine.
Here's a snippet we often use to get Magento validation and Chosen to work well together:
// Rewriting Validation.isVisible from /js/prototype/validation.js so Chosen selects will be validated
if (Validation._isVisible == "undefined") {
Validation._isVisible = Validation.isVisible;
Validation.isVisible = function(elm) {
return elm.hasClassName('chzn-done') || this._isVisible(elm);
};
};
The isVisible
method gets called in a conditional statement in Validation.test
in /js/prototype/validation.js. Returning true
when the select you want to validate has the chzn-done
class will let it pass through that conditional and be validated.
The wrapping if statement in the above code is so you don't overwrite the overwrite and the internal call to this._isVisible(elm)
doesn't return a copy of itself