Trying to add "Multiple categories" selector to custom product module parameter

Started by Genius WebDesign, March 08, 2015, 01:40:58 AM

Previous topic - Next topic

Genius WebDesign

Hi,

I´m working on developing a custom Virtuemart product module, but I have 1 simple problem.

I need to add a multi-select form field in the module XML file, so that the user can select one or more product categories in the module manager settings.

In the standard product module there is only a single select for product category..

In the module XML file the form input looks like this:

<param name="virtuemart_category_id" type="vmcategories"  value_field="category_name" label="MOD_VIRTUEMART_PRODUCT_CATEGORY_ID" description="MOD_VIRTUEMART_PRODUCT_CATEGORY_ID_DESC" />

But I need it to be multi-select.
I have tried to add multiple="true" to the param and field element, but that does not work..

Please help.

Genius WebDesign

Hello,

Please someone advice on this matter.
I´m kinda stuck with my development if I do not get this solved..

GJC Web Design

should it be set to multiple in administrator\components\com_virtuemart\fields\vmcategories.php?
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

Genius WebDesign

Yes I think so.
But in that file it says:

$categorylist = ShopFunctions::categoryListTree(array($this->value));

$html = '<select class="inputbox"   name="' . $this->name . '" >';
$html .= '<option value="0">' . vmText::_('COM_VIRTUEMART_CATEGORY_FORM_TOP_LEVEL') . '</option>';
$html .= $categorylist;
$html .= "</select>";
return $html;


This seems incorrect..
I have tried doing a hack and changing it to <select class="inputbox"   name="' . $this->name . '" multiple>

But then the module parameters are not stored when saving module.

Genius WebDesign

I will try experimenting with coding my own custom field for parameters.
I could try and add this in module XLM file

<fields name="params" addfieldpath="/modules/mod_mymodule/models/fields">

and then create a PHP file producing the category multi select field and store it in that folder.
Should be able to do it that way, I guess.

I will get back on this when I have worked on it..

Genius WebDesign

Ok, now I have tried a few thing and I have almost found a solution.. but not quite.

I can produce a multiselect drop down for Virtuemart categories in the module manager settings, but it only saves 1 category, even if I select 2 or more categories..

So if I select "Category 1" and "Category 2" and clicks save, then it only saves "Category 2"
So my guess is that somehow the module field values are not processed and stored as an array.

Here is my modifyed field model:

$categorylist = ShopFunctions::categoryListTree(array($this->value));

$html = '<select name="jform[params][gvmprgalcategories]" class="inputbox" multiple size="10">';
$html .= '<option value="0">' . vmText::_('COM_VIRTUEMART_CATEGORY_FORM_TOP_LEVEL') . '</option>';
$html .= $categorylist;
$html .= "</select>";
return $html;


I have tried changing to: <select name="jform[params][gvmprgalcategories][]" class="inputbox" multiple size="10"> - adding [] to the name attribute, but then none of the chosen categories are saved.


Milbo

Quote from: Genius WebDesign on March 08, 2015, 01:40:58 AM
type="vmcategories"
should indeed work for multiple categories and for single category it should vmcategory :-) I would search for any component in joomla using an array.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Genius WebDesign

Hello Milbo! :)

I could not get the native vmcategories to work, so I ended up constructing my own model for my module.

Here is how it turned out:

1. I created a new folder "fields" in my module main folder, like this: /modules/mod_mymodule/fields

2. I created a new PHP model file called "gvmprgalcategories.php" and stored it in the "fields" folder.

I then edited the "gvmprgalcategories.php" file with this code (In my case I chose field type name "Gvmprgalcategories"):

<?php
// no direct access
defined'_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.html.html');
jimport('joomla.form.formfield');//import the necessary class definition for formfield


class JFormFieldGvmprgalcategories extends JFormField {

 protected 
$type 'Gvmprgalcategories';


 protected function 
getInput() {
 
// Initialize variables.
 
$session JFactory::getSession();
 
$options = array();
 
 
$attr '';


 
$attr .= $this->element['class'] ? ' class="'.(string) $this->element['class'].'"' '';

 if ( (string) 
$this->element['readonly'] == 'true' || (string) $this->element['disabled'] == 'true') {
 
$attr .= ' disabled="disabled"';
 }

 
$attr .= $this->element['size'] ? ' size="'.(int) $this->element['size'].'"' '';
 
$attr .= ' multiple="multiple"';

 
$attr .= $this->element['onchange'] ? ' onchange="'.(string) $this->element['onchange'].'"' '';
 
 

defined('DS') or define('DS'DIRECTORY_SEPARATOR);
if (!
class_exists'VmConfig' )) { require(JPATH_ROOT.DS.'administrator'.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php'); }

if (!
class_exists('ShopFunctions')) {
require(VMPATH_ADMIN DS 'helpers' DS 'shopfunctions.php');
}
if (!
class_exists('TableCategories')) {
require(VMPATH_ADMIN DS 'tables' DS 'categories.php');
}

VmConfig::loadConfig();
VmConfig::loadJLang('com_virtuemart');
$categorylist ShopFunctions::categoryListTree(array($this->value));

$categorylist '<html><head><meta http-equiv="Content-Type" 
content="text/html; charset=utf-8">
</head><body>'
.$categorylist.'</body></html>';

$articles=array();
 
 

$doc = new DOMDocument();
$doc->loadHTML($categorylist);
$divs $doc->getElementsByTagName('option');

$counternr 0;
foreach(
$divs as $node) {
$optionvalue $node->getAttribute('value'); 
$optiontext $node->nodeValue;

$articles[$counternr]->id $optionvalue;
$articles[$counternr]->title $optiontext;
$counternr $counternr 1;
}
 
 return 
JHTML::_('select.genericlist'$articles$this->nametrim($attr), 'id''title'$this->value );
 
 }
}


3. Now in my modules XML file I simply added this field element:
<field name="multicatselect" type="Gvmprgalcategories" default="0" label="JGLOBAL_TITLE" description="JFIELD_TITLE_DESC" multiple="true"/>

And the element: <fields name="params"> I changed to <fields name="params" addfieldpath="/modules/mod_mymodule/fields">


Voila, now I have a working Virtuemart category multi-select with select options HTML output generated by your: ShopFunctions::categoryListTree  and JHTML::
Very sweet :)

Genius WebDesign

As you can see I had to be a little "creative" and parse the HTML of the category list with DOMDocument in order to finally make use of JHTML to generate the proper select field output.

I hope this will come in handy to others along the way. It took me some time doing research around the Joomla documentation before I had it all put together..
At least I think I might use this for future reference myself :)

Milbo

Great work, looks clean.

I would like to add it native, in our categories, and if you use

multiple="true"

it should just work directly that way. You did already most of the work, doing the last finish and implement it back is the way to GPL  :-)
http://dev.virtuemart.net/projects/virtuemart/wiki/Setting_up_a_Development_Environment
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/