我刚刚将4000多个国家/地区代码导入到directory_country_region表中 - http://www.magentocommerce.com/boards/viewthread/272591/。效果很好......除了一件事。州/省按region_id而不是default_name列排序。
看起来它已经在app / core / code / core / Mage / Directory / Model / Resource / Region / Collection.php中的低级别完成
protected function _construct()
{
$this->_init('directory/region');
$this->_countryTable = $this->getTable('directory/country');
$this->_regionNameTable = $this->getTable('directory/country_region_name');
$this->addOrder('name', Varien_Data_Collection::SORT_ORDER_ASC);
$this->addOrder('default_name', Varien_Data_Collection::SORT_ORDER_ASC);
}
我找到了几个问这些问题的地方,但没有任何效果:
Magento: How to alphabetically sort the state/province dropdown's items
我真的认为这个人会这样做,但它没有任何影响: http://open-source.noads.biz/guide-magento-ecommerce/ordinare-la-tendina-delle-regioni-stati-province.html
谷歌让我失望了,我的想法已经用完了。答案 0 :(得分:4)
此修改后的form.js按您的要求工作
VarienForm = Class.create();
VarienForm.prototype = {
initialize: function(formId, firstFieldFocus){
this.form = $(formId);
if (!this.form) {
return;
}
this.cache = $A();
this.currLoader = false;
this.currDataIndex = false;
this.validator = new Validation(this.form);
this.elementFocus = this.elementOnFocus.bindAsEventListener(this);
this.elementBlur = this.elementOnBlur.bindAsEventListener(this);
this.childLoader = this.onChangeChildLoad.bindAsEventListener(this);
this.highlightClass = 'highlight';
this.extraChildParams = '';
this.firstFieldFocus= firstFieldFocus || false;
this.bindElements();
if(this.firstFieldFocus){
try{
Form.Element.focus(Form.findFirstElement(this.form))
}
catch(e){}
}
},
submit : function(url){
if(this.validator && this.validator.validate()){
this.form.submit();
}
return false;
},
bindElements:function (){
var elements = Form.getElements(this.form);
for (var row in elements) {
if (elements[row].id) {
Event.observe(elements[row],'focus',this.elementFocus);
Event.observe(elements[row],'blur',this.elementBlur);
}
}
},
elementOnFocus: function(event){
var element = Event.findElement(event, 'fieldset');
if(element){
Element.addClassName(element, this.highlightClass);
}
},
elementOnBlur: function(event){
var element = Event.findElement(event, 'fieldset');
if(element){
Element.removeClassName(element, this.highlightClass);
}
},
setElementsRelation: function(parent, child, dataUrl, first){
if (parent=$(parent)) {
// TODO: array of relation and caching
if (!this.cache[parent.id]){
this.cache[parent.id] = $A();
this.cache[parent.id]['child'] = child;
this.cache[parent.id]['dataUrl'] = dataUrl;
this.cache[parent.id]['data'] = $A();
this.cache[parent.id]['first'] = first || false;
}
Event.observe(parent,'change',this.childLoader);
}
},
onChangeChildLoad: function(event){
element = Event.element(event);
this.elementChildLoad(element);
},
elementChildLoad: function(element, callback){
this.callback = callback || false;
if (element.value) {
this.currLoader = element.id;
this.currDataIndex = element.value;
if (this.cache[element.id]['data'][element.value]) {
this.setDataToChild(this.cache[element.id]['data'][element.value]);
}
else{
new Ajax.Request(this.cache[this.currLoader]['dataUrl'],{
method: 'post',
parameters: {"parent":element.value},
onComplete: this.reloadChildren.bind(this)
});
}
}
},
reloadChildren: function(transport){
var data = eval('(' + transport.responseText + ')');
this.cache[this.currLoader]['data'][this.currDataIndex] = data;
this.setDataToChild(data);
},
setDataToChild: function(data){
if (data.length) {
var child = $(this.cache[this.currLoader]['child']);
if (child){
var html = '<select name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
if(this.cache[this.currLoader]['first']){
html+= '<option value="">'+this.cache[this.currLoader]['first']+'</option>';
}
for (var i in data){
if(data[i].value) {
html+= '<option value="'+data[i].value+'"';
if(child.value && (child.value == data[i].value || child.value == data[i].label)){
html+= ' selected';
}
html+='>'+data[i].label+'</option>';
}
}
html+= '</select>';
Element.insert(child, {before: html});
Element.remove(child);
}
}
else{
var child = $(this.cache[this.currLoader]['child']);
if (child){
var html = '<input type="text" name="'+child.name+'" id="'+child.id+'" class="'+child.className+'" title="'+child.title+'" '+this.extraChildParams+'>';
Element.insert(child, {before: html});
Element.remove(child);
}
}
this.bindElements();
if (this.callback) {
this.callback();
}
}
}
RegionUpdater = Class.create();
RegionUpdater.prototype = {
initialize: function (countryEl, regionTextEl, regionSelectEl, regions, disableAction, zipEl)
{
this.countryEl = $(countryEl);
this.regionTextEl = $(regionTextEl);
this.regionSelectEl = $(regionSelectEl);
this.zipEl = $(zipEl);
this.config = regions['config'];
delete regions.config;
this.regions = regions;
this.disableAction = (typeof disableAction=='undefined') ? 'hide' : disableAction;
this.zipOptions = (typeof zipOptions=='undefined') ? false : zipOptions;
if (this.regionSelectEl.options.length<=1) {
this.update();
}
Event.observe(this.countryEl, 'change', this.update.bind(this));
},
_checkRegionRequired: function()
{
var label, wildCard;
var elements = [this.regionTextEl, this.regionSelectEl];
var that = this;
if (typeof this.config == 'undefined') {
return;
}
var regionRequired = this.config.regions_required.indexOf(this.countryEl.value) >= 0;
elements.each(function(currentElement) {
Validation.reset(currentElement);
label = $$('label[for="' + currentElement.id + '"]')[0];
if (label) {
wildCard = label.down('em') || label.down('span.required');
if (!that.config.show_all_regions) {
if (regionRequired) {
label.up().show();
} else {
label.up().hide();
}
}
}
if (label && wildCard) {
if (!regionRequired) {
wildCard.hide();
if (label.hasClassName('required')) {
label.removeClassName('required');
}
} else if (regionRequired) {
wildCard.show();
if (!label.hasClassName('required')) {
label.addClassName('required')
}
}
}
if (!regionRequired) {
if (currentElement.hasClassName('required-entry')) {
currentElement.removeClassName('required-entry');
}
if ('select' == currentElement.tagName.toLowerCase() &&
currentElement.hasClassName('validate-select')) {
currentElement.removeClassName('validate-select');
}
} else {
if (!currentElement.hasClassName('required-entry')) {
currentElement.addClassName('required-entry');
}
if ('select' == currentElement.tagName.toLowerCase() &&
!currentElement.hasClassName('validate-select')) {
currentElement.addClassName('validate-select');
}
}
});
},
update: function()
{
if (this.regions[this.countryEl.value]) {
var i, option, region, def;
def = this.regionSelectEl.getAttribute('defaultValue');
if (this.regionTextEl) {
if (!def) {
def = this.regionTextEl.value.toLowerCase();
}
this.regionTextEl.value = '';
}
this.regionSelectEl.options.length = 1;
for (regionId in this.regions[this.countryEl.value]) {
region = this.regions[this.countryEl.value][regionId];
option = document.createElement('OPTION');
option.value = regionId;
option.text = region.name.stripTags();
option.title = region.name;
if (this.regionSelectEl.options.add) {
this.regionSelectEl.options.add(option);
} else {
this.regionSelectEl.appendChild(option);
}
if (this.regionSelectEl.length) {
var i = 0 ;
while( i< this.regionSelectEl.length) {
option_i = this.regionSelectEl.options[i] ;
if (option_i.value !="" && option_i.text > option.text) break;
else i++ ;
}
if (this.regionSelectEl.options.add) { //IE
this.regionSelectEl.options.add(option, i);
} else {
this.regionSelectEl.add(option, option_i);
}
}
else
{
if (this.regionSelectEl.options.add) { //IE
this.regionSelectEl.options.add(option);
} else {
this.regionSelectEl.options.add(option, null);
//this.regionSelectEl.appendChild(option);
}
}
if (regionId==def || (region.name && region.name.toLowerCase()==def) ||
(region.name && region.code.toLowerCase()==def)
) {
this.regionSelectEl.value = regionId;
}
}
if (this.disableAction=='hide') {
if (this.regionTextEl) {
this.regionTextEl.style.display = 'none';
}
this.regionSelectEl.style.display = '';
} else if (this.disableAction=='disable') {
if (this.regionTextEl) {
this.regionTextEl.disabled = true;
}
this.regionSelectEl.disabled = false;
}
this.setMarkDisplay(this.regionSelectEl, true);
jQuery(this.regionSelectEl).selectbox();
} else {
if (this.disableAction=='hide') {
if (this.regionTextEl) {
this.regionTextEl.style.display = '';
}
this.regionSelectEl.style.display = 'none';
Validation.reset(this.regionSelectEl);
} else if (this.disableAction=='disable') {
if (this.regionTextEl) {
this.regionTextEl.disabled = false;
}
this.regionSelectEl.disabled = true;
} else if (this.disableAction=='nullify') {
this.regionSelectEl.options.length = 1;
this.regionSelectEl.value = '';
this.regionSelectEl.selectedIndex = 0;
this.lastCountryId = '';
}
this.setMarkDisplay(this.regionSelectEl, false);
}
this._checkRegionRequired();
// Make Zip and its label required/optional
var zipUpdater = new ZipUpdater(this.countryEl.value, this.zipEl);
zipUpdater.update();
},
setMarkDisplay: function(elem, display){
elem = $(elem);
var labelElement = elem.up(0).down('label > span.required') ||
elem.up(1).down('label > span.required') ||
elem.up(0).down('label.required > em') ||
elem.up(1).down('label.required > em');
if(labelElement) {
inputElement = labelElement.up().next('input');
if (display) {
labelElement.show();
if (inputElement) {
inputElement.addClassName('required-entry');
}
} else {
labelElement.hide();
if (inputElement) {
inputElement.removeClassName('required-entry');
}
}
}
}
}
ZipUpdater = Class.create();
ZipUpdater.prototype = {
initialize: function(country, zipElement)
{
this.country = country;
this.zipElement = $(zipElement);
},
update: function()
{
// Country ISO 2-letter codes must be pre-defined
if (typeof optionalZipCountries == 'undefined') {
return false;
}
// Ajax-request and normal content load compatibility
if (this.zipElement != undefined) {
this._setPostcodeOptional();
} else {
Event.observe(window, "load", this._setPostcodeOptional.bind(this));
}
},
_setPostcodeOptional: function()
{
this.zipElement = $(this.zipElement);
if (this.zipElement == undefined) {
return false;
}
// find label
var label = $$('label[for="' + this.zipElement.id + '"]')[0];
if (label != undefined) {
var wildCard = label.down('em') || label.down('span.required');
}
// Make Zip and its label required/optional
if (optionalZipCountries.indexOf(this.country) != -1) {
while (this.zipElement.hasClassName('required-entry')) {
this.zipElement.removeClassName('required-entry');
}
if (wildCard != undefined) {
wildCard.hide();
}
} else {
this.zipElement.addClassName('required-entry');
if (wildCard != undefined) {
wildCard.show();
}
}
}
}
答案 1 :(得分:0)
看起来不是收藏问题。 如果您在前端检查返回的json,您会注意到元素已排序。
问题在于RegionUpdater(varien / js.js)类,它解析整数等元素,因此不会遵循您的订单。
一个丑陋的解决方案是将id转换为Mage_Directory_Helper_Data
中的字符串foreach ($collection as $region)
{
if (!$region->getRegionId())
{
continue;
}
$regions[$region->getCountryId()]["'".$region->getRegionId()."'"] = array('code' => $region->getCode(),'name' => $this->__($region->getName()));
}
$json = Mage::helper('core')->jsonEncode($regions);
以这种方式你的id是字符串,所以解析器遵循数组顺序,但现在你必须删除更新中的varien / js.js前端的引号:RegionUpdater类的函数:
option.value = regionId.replace(/'/g, '');
我知道它很难看,但它很快,否则你应该重新编码整个“选择区域”渲染