2012-11-21 23 views
22

我正在嘗試實現嵌入式小部件。管理員將能夠配置此小部件並將其嵌入WYSIWYG編輯器中。許多配置選項中的兩個是應顯示在前端和類別列表上的產品列表。如何在Magento窗口小部件配置中允許多種產品選擇?

我想允許這種選擇與 「adminhtml/catalog_product_widget_chooser」 和 「adminhtml/catalog_category_widget_chooser」。我試圖用網絡上可用的稀疏文檔來實現這些小部件,但我設法完成的是用於選擇一個產品或選擇一個類別的實現。我需要多重選擇行爲。

就目前的實施情況而言,我看不到多重選擇的可能性。我檢查了兩個類和grid.phtml模板的代碼,並且它嚴重寫入並且不能擴展超越當前使用意圖。例如,這是你會如何想初始化助手塊的小部件參數允許多個選擇:

<helper_block> 
    <type>adminhtml/catalog_product_widget_chooser</type> 
     <data> 
      <button translate="open"> 
       <open>Select Products...</open> 
      </button> 
      <use_massaction>1</use_massaction> 
     </data> 
</helper_block> 

但產品選擇器是硬編碼的使用沒有大規模的行動與這部分代碼:

public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) 
{ 
    $uniqId = Mage::helper('core')->uniqHash($element->getId()); 
    $sourceUrl = $this->getUrl('*/catalog_product_widget/chooser', array(
     'uniq_id' => $uniqId, 
     'use_massaction' => false, 
    )); 
    ... 

和應該有某種按鈕來確認多個選擇的grid.phtml模板只是顯示「搜索」和「重置過濾器」按鈕。沒有處理添加另一個按鈕。例如,這裏是負責打印按鈕HTML的默認代碼:

public function getMainButtonsHtml() 
{ 
    $html = ''; 
    if($this->getFilterVisibility()){ 
     $html.= $this->getResetFilterButtonHtml(); 
     $html.= $this->getSearchButtonHtml(); 
    } 
    return $html; 
} 

只有這兩個按鈕將打印默認情況下。

所以我開始基於上面提到的兩種實現我自己的實現,它變得越來越醜陋,並可能最終成爲一個難以維護的複製麪食混亂。我的工作原則是,如果事情開始變得醜陋,那麼我做錯了事。

那麼是否有一種直接的方法可以通過使用網格小部件在小部件配置屏幕上實現多個產品和多個類別選擇?

+2

很好的問題+1爲 –

回答

2

看起來好像你不是第一個開發自己的實現這個路徑。

David Manners似乎已經解決了同樣的問題,他的Manners_Widgets。在Manners_Widgets擴展的

特點:

  • 多選擇產品和類別

我已經沒有與大衛聯繫,也沒有我用這個解決方案,因此無法對此代碼的質量(或完整性)發表評論......但如果您尚未看到此解決方案,它可能會爲您節省一些時間(或者最糟糕的是,爲您提供聯繫人進行協作在這個問題上的演講)。

希望這可以幫助你,祝你好運!

+1

是的,我開始尋找到這個問題,但遺憾的是沒有太多的時間和運氣近來:(這是在GitHub上,如果有人幻想考慮看看,並幫助我會在這裏更新,如果我找到解決方案 – dmanners

+0

我剛剛嘗試了Magento 1.9x上的擴展,選擇掩碼來自產品列表並且具有諸如「更改狀態」和「更改屬性」但沒有實際「選擇「按鈕 – ScubaBen

0

下面是一個快速解決方法:不要使用產品小部件選擇器,而是使用文本字段代替以逗號分隔的SKU。

然後在您的代碼中爆炸skus並通過sku獲取產品。將其返回到您的模板。更容易:)

5

我發現了一個快速的方法來獲取基於adminhtml/system_config_source_category使用源模型的小工具參數的類別多選。我已經刪除了根級別過濾器併爲子類別添加了縮進。

widget.xml:

<widgets> 
    <my_widget type="mymodule/block" translate="name" module="mymodule"> 
     <name>Widget with Multiselect Categories</name> 
     <parameters> 
      <category_ids translate="label description"> 
       <visible>1</visible> 
       <required>1</required> 
       <label>Categories</label> 
       <type>multiselect</type> 
       <source_model>mymodule/system_config_source_category</source_model> 
      </category_ids> 
     </parameters> 
    </my_widget> 
</widgets> 

源模型:

class Mynamespace_Mymodule_Model_System_Config_Source_Category 
{ 
    public function toOptionArray() 
    { 
     $collection = Mage::getResourceModel('catalog/category_collection'); 

     $collection->addAttributeToSelect('name') 
      ->addFieldToFilter('path', array('neq' => '1')) 
      ->load(); 

     $options = array(); 

     foreach ($collection as $category) { 
      $depth = count(explode('/', $category->getPath())) - 2; 
      $indent = str_repeat('-', max($depth * 2, 0)); 
      $options[] = array(
       'label' => $indent . $category->getName(), 
       'value' => $category->getId() 
      ); 
     } 

     return $options; 
    } 
} 

其結果是:

Multiselect widget parameter

來源:http://www.magentocommerce.com/knowledge-base/entry/tutorial-creating-a-magento-widget-part-2

4

我已經爲此問題添加了答案。 Implement multiple product chooser widget Magento

我檢查了https://github.com/dio5/magento-multiproducts-widget下的模塊。

使用FORK選項而不是下載ZIP。

它的工作原理和給出了精確的結果,例如WIDGET中的多種產品選擇。如果有任何錯誤,請告訴我。

讓我知道,如果這對你有用。

謝謝!

[編輯我以前的評論,在代碼的請求,在這裏直接]

/Namespace/Modulename/etc/widget.xml

<widgets> 
    <catalog_product_multiproducts type="namespace_modulename/widget_catalog_product_multiproducts" translate="name description" module="namespace_modulename"> 
    <name>Catalog Multiple Products Widget</name> 
    <description>Select multiple products for display</description> 
    <parameters> 
     <title translate="label"> 
      <visible>1</visible> 
      <label>Title</label> 
      <type>text</type> 
     </title> 
     <products_count translate="label"> 
      <visible>1</visible> 
      <required>1</required> 
      <label>No of Products</label> 
      <type>text</type> 
     </products_count> 
     <ids translate="label"> 
      <visible>1</visible> 
      <required>1</required> 
      <label>Products</label> 
      <type>label</type> 
      <helper_block> 
       <type>namespace_modulename/adminhtml_catalog_product_widget_multiproducts_chooser</type> 
       <data> 
        <button translate="open"> 
         <open>Select Products...</open> 
        </button> 
       </data> 
      </helper_block> 
      <sort_order>10</sort_order> 
     </ids> 
     <template translate="label description"> 
      <required>1</required> 
      <visible>1</visible> 
      <label>Product Carousel Template</label> 
      <type>text</type> 
      <value>catalog/product/widget/products_carousel.phtml</value> 
      <values> 
       <default translate="label">              <value>catalog/product/widget/products_carousel.phtml</value> 
        <label>New Products Grid Template</label> 
       </default> 
       <list translate="label"> 
        <value>catalog/product/widget/new/content/new_list.phtml</value> 
        <label>New Products List Template</label> 
       </list> 
      </values> 
      <description>Template path cannot be changed/updated</description> 
     </template>  
    </parameters> 
    </catalog_product_multiproducts> 
</widgets> 

/命名空間/模塊名/座/Adminhtml/Catalog/Product/MultiProducts/Chooser.php

Thi s功能將調用DOCHOOSE()功能,這將有助於「選擇」選中/選擇的產品。

/** 
* prepare layout for products grid 
* 
* @return type Mage_Adminhtml_Block_Catalog_Product_Widget_Chooser 
*/ 
protected function _prepareLayout() 
{ 
    $this->setChild('choose_button', $this->getLayout()->createBlock('adminhtml/widget_button') 
        ->setData(array(
         'label' => Mage::helper('adminhtml')->__('Choose Selected Products'), 
         'onclick' => $this->getJsObjectName() . '.doChoose()' 
        )) 
    ); 
    return parent::_prepareLayout(); 
} 

的下面功能需要被用於製備產物元素的HTML,格式爲{1} {2}

/** 
* Prepare chooser element HTML 
* 
* @param Varien_Data_Form_Element_Abstract $element Form Element 
* @return Varien_Data_Form_Element_Abstract 
*/ 
public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) 
{ 
    $uniqueId = Mage::helper('core')->uniqHash($element->getId()); 

    $sourceUrl = $this->getUrl('*/multiproducts/chooser', array(
     'uniq_id' => $uniqueId, 
     'use_massaction' => true, 
    )); 

    $chooser = $this->getLayout()->createBlock('widget/adminhtml_widget_chooser') 
      ->setElement($element) 
      ->setTranslationHelper($this->getTranslationHelper()) 
      ->setConfig($this->getConfig()) 
      ->setFieldsetId($this->getFieldsetId()) 
      ->setSourceUrl($sourceUrl) 
      ->setUniqId($uniqueId); 

    if ($element->getValue()) 
    { 
     $label = ""; 
     $ids = explode('}{', $element->getValue()); 
     $cleanIds = array(); 
     foreach ($ids as $id) 
     { 
      $id = str_replace('{', '', $id); 
      $id = str_replace('}', '', $id); 
      $cleanIds[] = $id; 
     } 

     $products = $this->_getProductsByIDs($cleanIds); 

     if ($products) 
     { 
      $label .= '<ul>'; 
      foreach ($products as $product) 
      { 
       $label .= '<li>' . $product->getName() . '</li>'; 
      } 
      $label .= '</ul>'; 
      $chooser->setLabel($label); 
     } 
    } 

    $element->setData('after_element_html', $chooser->toHtml()); 

    return $element; 
} 

JS爲複選框選中/取消

/** 
* Checkbox Check JS Callback 
* 
* @return string 
*/ 
public function getCheckboxCheckCallback() 
{ 
    if ($this->getUseMassaction()) 
    { 
     return "function (grid, element) { 
      $(grid.containerId).fire('product:changed', {element: element});     
     }"; 
    } 
} 

JS行/產品點擊/選中/選中

/** 
* Grid Row JS Callback 
* 
* @return string 
*/ 
public function getRowClickCallback() 
{ 
    if (!$this->getUseMassaction()) 
    { 
     $chooserJsObject = $this->getId(); 
     return ' 
      function (grid, event) { 
       var trElement = Event.findElement(event, "tr"); 
       var productId = trElement.down("td").innerHTML; 
       var productName = trElement.down("td").next().next().innerHTML; 
       var optionLabel = productName; 
       var optionValue = "product/" + productId.replace(/^\s+|\s+$/g,""); 
       if (grid.categoryId) { 
        optionValue += "/" + grid.categoryId; 
       } 
       if (grid.categoryName) { 
        optionLabel = grid.categoryName + "/" + optionLabel; 
       } 
       ' . $chooserJsObject . '.setElementValue(optionValue); 
       ' . $chooserJsObject . '.setElementLabel(optionLabel); 
       ' . $chooserJsObject . '.close(); 
      } 
     '; 
    } 
} 

JS代碼,如果用戶有興趣從特定類別中選擇產品。

/** 
* Category Tree node onClick listener js function 
* 
* @return string 
*/ 
public function getCategoryClickListenerJs() 
{ 
    $js = ' 
     function (node, e) { 
      {jsObject}.addVarToUrl("category_id", node.attributes.id); 
      {jsObject}.reload({jsObject}.url); 
      {jsObject}.categoryId = node.attributes.id != "none" ? node.attributes.id : false; 
      {jsObject}.categoryName = node.attributes.id != "none" ? node.text : false; 
     } 
    '; 

    $js = str_replace('{jsObject}', $this->getJsObjectName(), $js); 

    return $js; 
} 

用於準備帶產品ID的POST元素的附加JS。

/** 
* return additional JS for controls 
* 
* @return JS 
*/ 
public function getAdditionalJavascript() 
{ 
    $chooserJsObject = $this->getId(); 

    $js = '  
     {jsObject}.initChecked = function() { 
      $$("#' . $chooserJsObject . '_table tbody input:checkbox").each(function(element, i) { 
       var values = ' . $chooserJsObject . '.getElementValue(); 
       var capture = values.replace("{"+element.value+"}", "match");      
       var searchValue = "match"; 

       if(capture.search(searchValue) != -1) 
       { 
        element.checked = true; 
       } 
      }); 
     } 

     {jsObject}.initChecked(); 

     var values = ' . $chooserJsObject . '.getElementValue(); 

     $("' . $chooserJsObject . '").insert({bottom: "<div class=\"filter\"><input type=\"hidden\" value=\"+values+\" name=\"selected_products\" /></div>"}); 

     $$("#' . $chooserJsObject . '_table tbody input:checkbox").invoke("observe", "change", function(event) { 
      var element = Event.element(event); 
      var label = element.up("td").next().next().next().innerHTML; 
      label = label.replace(/^\s\s*/, "").replace(/\s\s*$/, ""); 
      if(element.checked) 
      { 
       {jsObject}.addValue(element.value); 
       {jsObject}.addLabel(label); 
      } else { 
       {jsObject}.removeValue(element.value); 
       {jsObject}.removeLabel(label); 
      } 
     }); 

     {jsObject}.removeValue = function(value) { 
      var currentValue = ' . $chooserJsObject . '.getElementValue(); 
      currentValue = currentValue.replace("{"+value+"}", ""); 
      ' . $chooserJsObject . '.setElementValue(currentValue); 
     } 

     {jsObject}.addValue = function(value) { 
      var currentValue = ' . $chooserJsObject . '.getElementValue(); 
      currentValue = currentValue.replace("{"+value+"}", ""); 
      currentValue = currentValue + "{"+value+"}"; 
      ' . $chooserJsObject . '.setElementValue(currentValue); 
     } 

     {jsObject}.removeLabel = function(label) { 
      var currentLabel = ' . $chooserJsObject . '.getElementLabelText(); 
      currentLabel = currentLabel.replace("<li>"+label+"</li>", ""); 
      ' . $chooserJsObject . '.setElementLabel(currentLabel);   
     } 

     {jsObject}.addLabel = function(label) { 
      var currentLabel = ' . $chooserJsObject . '.getElementLabelText(); 
      if(currentLabel.search("ul") != -1) 
      { 
       currentLabel = currentLabel.replace("</ul>", ""); 
       currentLabel = currentLabel.replace("<li>"+label+"</li>", ""); 
      } else { 
       currentLabel = "<ul>"; 
      }  
      currentLabel = currentLabel +"<li>"+label+"</li></ul>"; 
      ' . $chooserJsObject . '.setElementLabel(currentLabel); 
     } 

     {jsObject}.doChoose = function(node,e) { 
      ' . $chooserJsObject . '.close(); 
     } 
    '; 

    $js = str_replace('{jsObject}', $this->getJsObjectName(), $js); 

    return $js; 
} 

以上是主要功能,它將幫助您在彈出窗口中從GRID中選擇多個產品。

還有更多的可以在這裏檢查一下代碼:https://github.com/dio5/magento-multiproducts-widget

步驟:

  1. 導航到一個CMS頁面的管理面板
  2. 點擊「插入控件」在所見即所得編輯器
  3. 選擇小工具類型 - 目錄多個產品小工具
  4. 輸入標題,產品計數
  5. 選擇一個模板(可以添加所需的一種選擇,因爲許多模板)
  6. 點擊「選擇產品」按鈕,從電網
  7. 選擇產品
  8. 點擊「選擇選用產品」按鈕

希望這可以幫助別人!

編碼快樂......

+0

請分享您的答案中的代碼,而不是鏈接到它們,至少是必不可少的部分 – hotzst

+0

已嘗試編輯我的答案並提供主要代碼塊,這可能對前進的人有幫助,謝謝! – Shivani

+0

此代碼工作正常。但它有一個像小部件左側的問題,我們無法制作具有類別的過濾器產品。 – krutssss

相關問題