【发布时间】:2011-06-18 11:44:09
【问题描述】:
在http://alanstorm.com/magento_system_configuration_in_depth_tutorial@AlanStorm 给出了非常好的系统配置教程。
他还解释了如何使用
我的问题是如果字段 A 具有值 V1 或 V2,我如何使字段 B 可见。
如果有人知道magento的代码在哪里实现,我也想自己看看代码。
谢谢
【问题讨论】:
标签: magento magento-1.4
在http://alanstorm.com/magento_system_configuration_in_depth_tutorial@AlanStorm 给出了非常好的系统配置教程。
他还解释了如何使用
我的问题是如果字段 A 具有值 V1 或 V2,我如何使字段 B 可见。
如果有人知道magento的代码在哪里实现,我也想自己看看代码。
谢谢
【问题讨论】:
标签: magento magento-1.4
如果我正确理解了 Magento 1.7.0.1 的发行说明,则此功能已实现 (http://goo.gl/ZgHG0)。我已经在 Magento CE 1.7.0.2 上成功测试了它。
你必须像这样在字段依赖中声明一个分隔符参数:
<depends>
<depends_from_field separator=",">
depends_from_field_value_1,depends_from_field_value_2
</depends_from_field>
</depends>
注意depends_from_field_value_1 和depends_from_field_value_2 用逗号分隔,即separator="," 中声明的确切符号
【讨论】:
安德鲁的回答几乎成功了。我现在在 1.6.2.0 上,我修改了 app\code\core\Mage\Adminhtml\Block\System\Config\Form.php 中的 initFields() 方法如下:
if ($e->depends) {
foreach ($e->depends->children() as $dependent) {
Mage::log((array)$dependent);
$dependentId = $section->getName()
. '_' . $group->getName()
. '_' . $fieldPrefix
. $dependent->getName();
if ($dependent->hasChildren()) {
$dependentValue = (array) $dependent;
$dependentValue = array_values($dependentValue);
} else {
$dependentValue = (string) $dependent;
}
$shouldBeAddedDependence = true;
$dependentFieldName = $fieldPrefix . $dependent->getName();
$dependentField = $group->fields->$dependentFieldName;
/*
* If dependent field can't be shown in current scope and real dependent config value
* is not equal to preferred one, then hide dependence fields by adding dependence
* based on not shown field (not rendered field)
*/
if (!$this->_canShowField($dependentField)) {
$dependentFullPath = $section->getName()
. '/' . $group->getName()
. '/' . $fieldPrefix
. $dependent->getName();
if (is_array($dependentValue)) {
foreach ($dependentValue as $dependentOption) {
$shouldBeAddedDependence |= $dependentOption != Mage::getStoreConfig(
$dependentFullPath,
$this->getStoreCode()
);
}
} else {
$shouldBeAddedDependence = $dependentValue != Mage::getStoreConfig(
$dependentFullPath,
$this->getStoreCode()
);
}
}
if($shouldBeAddedDependence) {
$this->_getDependence()
->addFieldMap($id, $id)
->addFieldMap($dependentId, $dependentId)
->addFieldDependence($id, $dependentId, $dependentValue);
}
}
}
也没有必要编辑核心文件。我overrode the admin theme 插入了我自己的form.js 版本,并使用自定义模块的config.xml 重写了两个PHP 类。
【讨论】:
有更好的方法,但您需要覆盖核心文件
覆盖以下文件下的方法 app\code\core\Mage\Adminhtml\Block\Widget\Form\Element\Dependence.php
public function addFieldDependence($fieldName, $fieldNameFrom, $refValues)
{
/*
if (is_array($refValues)) {
Mage::throwException('Dependency from multiple values is not implemented yet. Please fix to your widget.xml');
}
*/
$this->_depends[$fieldName][$fieldNameFrom] = $refValues;
return $this;
}
在 app\code\core\Mage\Adminhtml\Block\System\Config\Form.php 修改方法initFields
if ($e->depends) {
foreach ($e->depends->children() as $dependent) {
$dependentId = $section->getName() . '_' . $group->getName() . '_' . $fieldPrefix . $dependent->getName();
if ($dependent->count()) {
$dependentValue = (array) $dependent;
$dependentValue = array_values($dependentValue);
} else {
$dependentValue = (string) $dependent;
}
$this->_getDependence()
->addFieldMap($id, $id)
->addFieldMap($dependentId, $dependentId)
->addFieldDependence($id, $dependentId, $dependentValue);
}
}
修改javascript文件js\mage\adminhtml\form.js
trackChange : function(e, idTo, valuesFrom)
{
// define whether the target should show up
var shouldShowUp = true;
for (var idFrom in valuesFrom) {
if (valuesFrom.hasOwnProperty(idFrom)) {
if (typeof(valuesFrom[idFrom])=="object") {
shouldShowUp = false;
for(var idVal in valuesFrom[idFrom]) {
if (valuesFrom[idFrom].hasOwnProperty(idVal)) {
if (typeof(idVal)!="undefined" && ($(idFrom).value == valuesFrom[idFrom][idVal])) {
shouldShowUp = true;
}
}
}
} else if (typeof(valuesFrom[idFrom])=="string") {
if ($(idFrom).value != valuesFrom[idFrom]) {
shouldShowUp = false;
}
}
}
/*
if ($(idFrom).value != valuesFrom[idFrom]) {
shouldShowUp = false;
}
*/
}
// toggle target row
if (shouldShowUp) {
$(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item) {
if (!item.type || item.type != 'hidden') { // don't touch hidden inputs, bc they may have custom logic
item.disabled = false;
}
});
$(idTo).up(this._config.levels_up).show();
} else {
$(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item){
if (!item.type || item.type != 'hidden') { // don't touch hidden inputs, bc they may have custom logic
item.disabled = true;
}
});
$(idTo).up(this._config.levels_up).hide();
}
}
对你的 xml 的多个值依赖使用以下语法
<depends>
<field1>
<val1>text</val1>
<val2>radio</val2>
</field1>
</depends>
【讨论】:
我不确定 Alan 的文章在哪里解释了它,但我是这样做的:它只是一点 javascript。
在您的组中,您放置了一个带有嵌入 javascript 的评论标签。
例如,这是我的代码,它检查一个字段的值以显示(或不显示)另一个:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<sections>
<points_options translate="label" module="points">
<tab>general</tab>
<label>Loyalty Points</label>
<frontend_type>text</frontend_type>
<sort_order>1002</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<config_points translate="label">
<label>Configuration</label>
<comment><![CDATA[
<script type="text/javascript">
checkExpirationPeriod = function() {
if ($('points_options_config_points_expiration_period').getValue() > 0) {
$('points_options_config_points_expiration_reminder').up(1).appear();
} else {
$('points_options_config_points_expiration_reminder').up(1).fade();
}
}
Event.observe(window, 'load', function() {
Event.observe('points_options_config_points_expiration_period', 'change', checkExpirationPeriod);
checkExpirationPeriod();
})
</script>
]]></comment>
如您所见,我编写了一个小函数来检查一个字段的值以确定是否显示另一个字段。然后我将 onchange 事件链接到函数并触发函数以在页面加载时显示正确的字段。
根据您的需要,只需在 js 函数中添加条件即可。
希望有帮助
【讨论】:
<depends><field>v1,v2</field></depends> 和<depends><field>v1</field><field>v2</field></depends>。如果我能找到它在代码中的实现位置,也许它可以对完整的语法有所了解。