您在這裡

如何修改attribute模組增加複選功能

dionysian's 的頭像
dionysian 在 2008-07-29 (二) 22:36 發表

這個模組提供一種屬性或是附件的選擇到商品節點,目前的顯示功能只有選擇框、單選按鈕及文字欄位,我想增加一個複選框需要修改程式碼,不知道有哪位程式高手可以幫我看看要寫在哪?該怎麼寫?
那一段的程式碼如下:
function _uc_attribute_alter_form($product) {
$nid = intval($product['nid']['#value']);
$qty = intval($product['qty']['#value']);
if (!$qty) {
$qty = 1;
}

// If we were passed an actual node object...
if ($node = node_load($nid)) {
// Load all product attributes for the given nid.
$result = db_query("SELECT * FROM {uc_product_attributes} WHERE nid = %d ORDER BY ordering", $nid);
$priced_attributes = uc_attribute_priced_attributes($nid);

// Loop through each product attribute and generate its form element.
while ($relation = db_fetch_object($result)) {
$attribute = uc_attribute_load($relation->aid, $nid, 'product');

// Build the attribute's options array.
$options = array();
foreach ($attribute->options as $option) {
switch (variable_get('uc_attribute_option_price_format', 'adjustment')) {
case 'total':
$display_price = in_array($relation->aid, $priced_attributes) ? ', '. uc_currency_format(($node->sell_price + $option->price) * $qty) : '';
if (count($priced_attributes) == 1) {
break;
}
case 'adjustment':
$display_price = ($option->price != 0 ? ', '. ($option->price > 0 ? '+' : '') . uc_currency_format($option->price * $qty) : '');
break;
case 'none':
default:
$display_price = '';
break;
}
$options[$option->oid] = $option->name . $display_price;
}

if (count($attribute->options) && $attribute->display > 0) {
if ($attribute->required) {
if ($attribute->display == 1) {
$options = array('' => t('Please select')) + $options;
}
unset($relation->default_option);
}
$product['attributes'][$attribute->aid] = array(
'#type' => $attribute->display == 1 ? 'select' : 'radios',
'#title' => $attribute->name,
'#description' => check_plain($attribute->description),
'#default_value' => $relation->default_option,
'#options' => $options,
'#required' => $attribute->required,
);
}
else {
$product['attributes'][$attribute->aid] = array(
'#type' => 'textfield',
'#title' => $attribute->name,
'#description' => check_plain($attribute->description),
'#default_value' => $attribute->required == FALSE ? $attribute->options[$relation->default_option]->name : '',
'#required' => $attribute->required,
);
}
$product['attributes']['#theme'] = 'uc_attribute_add_to_cart';
}
}
return $product;
}

// Returns an array of display types used as options when creating attributes.
function _uc_attribute_display_types() {
return array(
0 => t('Text field'),
1 => t('Select box'),
2 => t('Radio buttons'),
);
}
我修改了好幾次都失敗囉....

試試

<?php
if (count($attribute->options) && $attribute->display > 0) {
if ($attribute->required) {
if ($attribute->display == 1) {
$options = array('' => t('Please select')) + $options;
}
unset($relation->default_option);
}

$product['attributes'][$attribute->aid] = array(
//'#type' => $attribute->display == 1 ? 'select' : 'radios', 將原本設定顯示類型的部分註解掉
'#title' => $attribute->name,
'#description' => check_plain($attribute->description),
'#default_value' => $relation->default_option,
'#options' => $options,
'#required' => $attribute->required,
);
//加上下面自訂的判斷
switch($attribute->display) {
case 1:
$product['attributes'][$attribute->aid]['#type'] = 'select';
break;
case 2:
$product['attributes'][$attribute->aid]['#type'] = 'radios';
break;
case 3:
$product['attributes'][$attribute->aid]['#type'] = 'select';
$product['attributes'][$attribute->aid]['#multiple'] = TRUE;
break;
default:
$product['attributes'][$attribute->aid]['#type'] = 'select';
break;
}
//修改結束
} else {
$product['attributes'][$attribute->aid] = array(
'#type' => 'textfield',
'#title' => $attribute->name,
'#description' => check_plain($attribute->description),
'#default_value' => $attribute->required == FALSE ? $attribute->options[$relation->default_option]->name : '',
'#required' => $attribute->required,
);
}
?>

修改後看到的結果似乎不是我想的那樣

我希望像這個樣子可以複選商品附件

很感謝你撥空指導解答,這個問題在官網也有人發問但是我看不懂他們的回答^^"

你說複選框我以為是要讓下拉式選單可以複選
把 $product['attributes'][$attribute->aid]['#type'] = 'select';
改成 $product['attributes'][$attribute->aid]['#type'] = 'checkboxes'; 應該就可以
不過送出之後 原本的程式碼是否可以處理這種複選格式的送出資料 還要試試看才知道行不行

看起來應該是比較適合用 hook_form_alter 來做
不過這部份對 Form API 要比較了解才行

另外 如果改變一下作法
把一個加購的選項視為一個屬性 只有加購/不加購兩種選項
把多選改為四個單選
會不會比較簡單
不需要去改到資料處理的部份
頂多把 select 或 radio 改成 checkbox (不像 checkboxes 是多選 checkbox 只能產生一個選項 傳回是/否)

原先我只把radio改成checkbox以為可以,但是他只把標題當成選項像下圖那樣

改成checkboxes就是我要的樣子但是送出資料還是一樣的問題,除非將每個附屬商品都成為一個獨立的屬性選項,但是在後端他有一個預設的選項如何讓預設選項設為空值?我有個疑問這個流程不是先將資料放到cookies中等訂單確認後才把資料存進資料庫嗎?

radios 的格式跟 checkboxes 是一樣的
都是在 #options 內傳入一個陣列來定義要出現的選項

但是 checkbox 的格式不同
他是把 #title 當做勾選框後面要出現的文字

$form['copy'] = array(
'#type' => 'checkbox',
'#title' => t('Send me a copy.'),
);

就是
口 Send me a copy.
打勾會傳回 TRUE
不打勾會傳回 FALSE
checkbox 並不支援 #options 的屬性 用了也不會有任何反應 他就只能產生單一個勾選框而已
所以如果直接把 rasios 改成 checkbox
原本 rasios 的 #options 裡面設定了四個選項就變成只有一個選項了
應該先把每個附屬商品都成為一個獨立的屬性選項
這樣應該有四組 radios
然後在把每組 radios 改成 checkbox
才會跟原來一樣顯示四個選項

$form['copy'] = array(
'#type' => 'checkbox',
'#title' => t('Send me a copy.'),
'#return_value' => 1,
'#default_value' => 0,
);

#default_value 可以用來設定預設值
#return_value 用來設定當被勾選的時候的傳回值