2015-06-10 2 views
0

Я разрабатываю модуль prestashop, который должен составлять списки существующих продуктов.Ввод автозаполнения продукта на модуле (Prestashop)

Для панели конфигурации модуля, используя renderForm() и getContent(), я пытаюсь повторить «Расходники» потенциал, где вы начинаете писать некоторую информацию о продукте на входе, и он показывает продукты, которые соответствуют. При выборе этого продукта он добавляется в список. Как это:

prestashop accessoreies form

Этот скриншот Каталог/Продукция/вкладки ассоциаций.

Я пытаюсь использовать PS 1.6.0.14 и PS1.6.1.0RC3. Как бы я воспроизвел эту функциональность, чтобы получить списки продуктов на панели конфигурации модуля?

Я пробовал посмотреть здесь Prestashop AdminProductsController.php, но я не совсем понимаю, откуда приходит половина этой информации.

ответ

2

Я думаю, что для достижения этой функции функция renderForm() будет недостаточной, так как вам нужно связать некоторый javascript и некоторый пользовательский html.

Процесс написания полностью функционального модуля немного длинный, но с учетом функциональности аксессуаров в качестве отправной точки это будет не так сложно, и вы всегда будете иметь ссылку на «как сделать это». Я бы с этим:

1) первым создать

getContent()

функции, чтобы иметь возможность показать собственный шаблон и продукт, связанный вашего модуль таким образом, мы будем есть что-то:

public function getContent(){ 

    //post process part to save the associations 
    if(Tools::isSubmit('saveMyAssociations'){ 
    ... //we will see it later 
    } 

    $my_associations = MyModule::getAssociationsLight($this->context->language->id,Tools::getValue('id_product')); //function that will retrieve the array of all the product associated on my module table. 

    $this->context->smarty->assign(array(
        'my_associations' => $my_associations, 
        'product_id' => (int)Tools::getValue('id_product') 
       )); 

    return $this->display(__FILE__, 'views/templates/admin/admintemplate.tpl'); //custome template to create the autocomplete 

    } 

//our little function to get the already saved list, for each product we will retrieve id, name and reference with a join on the product/product_lang tables. 
public static function getAssociationsLight($id_lang, $id_product, Context $context = null) 
    { 
     if (!$context) 
      $context = Context::getContext(); 

     $sql = 'SELECT p.`id_product`, p.`reference`, pl.`name` 
       FROM `'._DB_PREFIX_.'my_associations` 
       LEFT JOIN `'._DB_PREFIX_.'product` p ON (p.`id_product`= `id_product_2`) 
       '.Shop::addSqlAssociation('product', 'p').' 
       LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (
        p.`id_product` = pl.`id_product` 
        AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').' 
       ) 
       WHERE `id_product_1` = '.(int)$id_product; 

     return Db::getInstance()->executeS($sql); 
    } 

2) создать шаблон, который будет способен отображать автомат и список. Здесь мы перейдем через сохраненные ассоциации, чтобы создать наш список автозаполнения, и мы сделаем это с помощью некоторого скрытого поля, чтобы отслеживать идентификаторы/имя, а также видимый список: у нас будет кнопка удаления для каждой строки.

 <input type="hidden" name="inputMyAssociations" id="inputMyAssociations" value="{foreach from=$my_associations item=accessory}{$accessory.id_product}-{/foreach}" /> 
     <input type="hidden" name="nameMyAssociations" id="nameMyAssociations" value="{foreach from=$my_associations item=accessory}{$accessory.name|escape:'html':'UTF-8'}¤{/foreach}" /> 
     <div id="ajax_choose_product_association"> 
      <div class="input-group"> 
       <input type="text" id="product_autocomplete_input_association" name="product_autocomplete_input_association" /> 
       <span class="input-group-addon"><i class="icon-search"></i></span> 
      </div> 
     </div> 

     <div id="divMyAssociations"> 
      {foreach from=$my_associations item=accessory} 
       <div class="form-control-static"> 
        <button type="button" class="btn btn-default delAssociation" name="{$accessory.id_product}"> 
         <i class="icon-remove text-danger"></i> 
        </button> 
        {$accessory.name|escape:'html':'UTF-8'}{if !empty($accessory.reference)}{$accessory.reference}{/if} 
       </div> 
      {/foreach} 
     </div> 
    <input type="submit" name="submitMyAssociations" id="submitMyAssociations" value="Send"/> 
    <input type="hidden" name="productId" id="productId" value="{$product_id|escape:'html'}"/> 

3) Теперь мы можем добавить JavaScript, чтобы связать автозаполнения на главном входе и выполнять всю логику для каждого действия

$(document).ready(function(){ 
//our function wrapper. 
      var initMyAssociationsAutocomplete = function(){ 
//initialize the autocomplete that will point to the default ajax_products_list page (it returns the products by id+name) 
       $('#product_autocomplete_input_association') 
         .autocomplete('ajax_products_list.php', { 
          minChars: 1, 
          autoFill: true, 
          max:20, 
          matchContains: true, 
          mustMatch:true, 
          scroll:false, 
          cacheLength:0, 
          formatItem: function(item) { 
           return item[1]+' - '+item[0]; 
          } 
         }).result(addAssociation); 
    //as an option we will add a function to exclude a product if it's already in the list 
       $('#product_autocomplete_input_association').setOptions({ 
        extraParams: { 
         excludeIds : getAssociationsIds() 
        } 
       }); 
      }; 
    //function to exclude a product if it exists in the list 
      var getAssociationsIds = function() 
      { 
       if ($('#inputMyAssociations').val() === undefined) 
        return ''; 
       return $('#inputMyAssociations').val().replace(/\-/g,','); 
      } 
    //function to add a new association, adds it in the hidden input and also as a visible div, with a button to delete the association any time. 
      var addAssociation = function(event, data, formatted) 
      { 
       if (data == null) 
        return false; 
       var productId = data[1]; 
       var productName = data[0]; 

       var $divAccessories = $('#divCrossSellers'); 
       var $inputAccessories = $('#inputMyAssociations'); 
       var $nameAccessories = $('#nameMyAssociations'); 

       /* delete product from select + add product line to the div, input_name, input_ids elements */ 
       $divAccessories.html($divAccessories.html() + '<div class="form-control-static"><button type="button" class="delAssociation btn btn-default" name="' + productId + '"><i class="icon-remove text-danger"></i></button>&nbsp;'+ productName +'</div>'); 
       $nameAccessories.val($nameAccessories.val() + productName + '¤'); 
       $inputAccessories.val($inputAccessories.val() + productId + '-'); 
       $('#product_autocomplete_input_association').val(''); 
       $('#product_autocomplete_input_association').setOptions({ 
        extraParams: {excludeIds : getAssociationsIds()} 
       }); 
      }; 
    //the function to delete an associations, delete it from both the hidden inputs and the visible div list. 
      var delAssociations = function(id) 
      { 
       var div = getE('divMyAssociations'); 
       var input = getE('inputMyAssociations'); 
       var name = getE('nameMyAssociations'); 

       // Cut hidden fields in array 
       var inputCut = input.value.split('-'); 
       var nameCut = name.value.split('¤'); 

       if (inputCut.length != nameCut.length) 
        return alert('Bad size'); 

       // Reset all hidden fields 
       input.value = ''; 
       name.value = ''; 
       div.innerHTML = ''; 
       for (i in inputCut) 
       { 
        // If empty, error, next 
        if (!inputCut[i] || !nameCut[i]) 
         continue ; 

        // Add to hidden fields no selected products OR add to select field selected product 
        if (inputCut[i] != id) 
        { 
         input.value += inputCut[i] + '-'; 
         name.value += nameCut[i] + '¤'; 
         div.innerHTML += '<div class="form-control-static"><button type="button" class="delAssociation btn btn-default" name="' + inputCut[i] +'"><i class="icon-remove text-danger"></i></button>&nbsp;' + nameCut[i] + '</div>'; 
        } 
        else 
         $('#selectAssociation').append('<option selected="selected" value="' + inputCut[i] + '-' + nameCut[i] + '">' + inputCut[i] + ' - ' + nameCut[i] + '</option>'); 
       } 

       $('#product_autocomplete_input_association').setOptions({ 
        extraParams: {excludeIds : getAssociationsIds()} 
       }); 
      }; 

    //finally initialize the function we have written above and create all the binds. 
       initMyAssociationsAutocomplete(); 
//live delegation of the deletion button to our delete function, this will allow us to delete also any element added after the dom creation with the ajax autocomplete. 
       $('#divMyAssociations').delegate('.delAssociation', 'click', function(){ 
        delAssociations($(this).attr('name')); 
       }); 
     }); 

4) Теперь вам просто нужно сохранить ассоциации, сделанные ваш автозаполнение модуля, и я предлагаю выполнить его, сначала удалив любую ассоциацию, сделанную на данном продукте, а затем сохранит все из них. так что вам не придется заботиться о вставке или обновлении записи

public function getContent(){ 

//post process part 
if(Tools::isSubmit('saveMyAssociations'){ 

     $product_id = (int)Tools::getValue('productId'); 
// see the function below, a simple query to delete all the associations on a product 
      $this->deleteMyAssociations($product_id); 
      if ($associations = Tools::getValue('inputMyAssociations')) 
      { 
       $associations_id = array_unique(explode('-', $associations)); 
       if (count($associations_id)) 
       { 
        array_pop($associations_id); 
        //insert all the association we have made. 
        $this->changeMyAssociations($associations_id, $product_id); 

       } 
      } 
} 

} 

protected function deleteMyAssociations($product_id){ 
return Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'my_associations` WHERE `id_product_1` = '.(int)$product_id); 
} 

protected function changeMyAssociations($associations_id, $product_id){ 
     foreach ($associations_id as $id_product_2) 
      Db::getInstance()->insert('my_associations', array(
       'id_product_1' => (int)$product_id, 
       'id_product_2' => (int)$id_product_2 
      )); 
} 

Я надеюсь, что это может помочь вам пройти через все это.

+0

Извините за задержку, я был занят другим проектом, и этот человек понес много задержек. Большое спасибо за длительный отклик. В ближайшие дни я попытаюсь понять это. – TJSoler

+0

Единственное, чего не хватало вашему прекрасному объяснению, это то, что вы использовали таблицу «моих асоциаций» в базе данных, не говоря о том, что вам нужно создать это, если оно не существует, когда вы «устанавливаете» модуль. – TJSoler

3

Существует плагин автозаполнения в preashashop, который вы должны использовать для этого. Его в js-> jquery-> плагинах вы должны добавить этот плагин в свой модуль, чтобы он работал.

Смежные вопросы