Dirplay Suite (http://drupal.org/project/ds) と Ubercart advanced catalog (http://drupal.org/project/uc_advanced_catalog) を使用すると、ドラッグ&ドロップ操作で商品ページのフィールド配置を自在に構成できるので便利。
ところが、Ubercart Ajax Attribute Calculations (http://drupal.org/project/uc_aac) を組み合わせてオプション選択と価格表示を連動させようとすると、正常に動作しないことが判明。調べてみると、ajax のレスポンスでフィールド表示を更新するコードはこんなふう:
function ucAacCalculate(element) {
var form = $(element).parents('form');
form.ajaxSubmit({
url: Drupal.settings.uc_aac_path,
dataType: 'json',
success: function(data) {
// Replace HTML elements with new values.
var node = $('#node-' + data.nid);
for (var i in data.replacements) {
var replacement = $(data.replacements[i]);
$(node).find('.' + i).after(replacement).remove();
}
// Update the add to cart form.
if (data.form) {
var action = form.attr('action');
$(form).after(data.form).next().attr('action', action);
form.remove();
Drupal.attachBehaviors();
}
}
});
}
更新対象のフィールドは id 属性の値が node-<nid> である div 要素の子でないとまずいらしい。だがしかし、Display Suite (というか Node displays http://drupal.org/project/nd) が出力したコンテンツにはこの記述がない。これが原因その1。
対策として、Node displays のテンプレート templates/nd.tpl.php を、使用している theme のディレクトリにコピーし、冒頭と末尾に次のコードを追加:
<div id="node-<?php print $node->nid; ?>">
・・・
</div>
これで $(node) にはコンテンツの DOM がセットされるはず。再度読み込んでテスト。・・・やっぱりダメ。
次に疑われるのは .after(replacement)。replacement とマッチするコンテンツがなくて置換されていない可能性。Firebug でレスポンスの replacement を見てみると "div.product-info" となっている。Ubercart advanced catalog が出力する価格フィールドの div を見ると product-info なんていう class 属性はない。当然 .after() の置換は行われない。これが原因その2。
aac の出力を真似て次の code フィールドを自分で書き、
<div class="product-info product sel">
<?php print $object->sell_price; ?>
</div>
Ubercart advanced catalog の価格フィールドに置き換える。再度テスト。・・・やっと動きました。
SKU を連動させたければ次の code フィールドでOK。
<div class="product-info model">
<?php var_dump($object->model); ?>
</div>
これでなんとか。