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

這個模組提供一種屬性或是附件的選擇到商品節點,目前的顯示功能只有選擇框、單選按鈕及文字欄位,我想增加一個複選框需要修改程式碼,不知道有哪位程式高手可以幫我看看要寫在哪?該怎麼寫?
那一段的程式碼如下:

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'),
  );
}

我修改了好幾次都失敗囉....

hom 的照片

Re:

試試

<?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,
    );
}
?>

dionysian 的照片

Re:

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

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

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

附加檔案大小
screenshot2.png21.18 KB
Screenshot.png18.45 KB
hom 的照片

Re:

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

hom 的照片

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

另外
不清楚你對於 drupal 的 Form API 以及 hook 瞭解的程度如何
一般如果要修改下載的模組的表單
通常是不建議直接改該模組的程式碼
透過 theme 或是 hook_form_alter 是比較建議的作法

dionysian 的照片

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

請問一下這兩種做法是將程式碼寫在哪?差別在哪裡?

dionysian 的照片

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

你說的沒錯顯示是正常的但是送出資料後會出現warning: Illegal offset type的問題.
對於的 Form API 以及 hook 我不太懂,但你建議透過theme的方式來達成這樣的功能真的可以不用修改程式碼嗎?

hom 的照片

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

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

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

dionysian 的照片

Re:

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

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

附加檔案大小
show3.png8.34 KB
hom 的照片

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

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 用來設定當被勾選的時候的傳回值

RSS feed