VirtueMart Forum

VirtueMart 2 + 3 + 4 => Virtuemart Development and bug reports => Topic started by: Genius WebDesign on March 08, 2015, 01:40:58 AM

Title: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 08, 2015, 01:40:58 AM
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.
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 09, 2015, 11:29:07 AM
Hello,

Please someone advice on this matter.
I´m kinda stuck with my development if I do not get this solved..
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: GJC Web Design on March 09, 2015, 14:53:26 PM
should it be set to multiple in administrator\components\com_virtuemart\fields\vmcategories.php?
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 09, 2015, 15:11:05 PM
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.
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 09, 2015, 15:26:58 PM
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..
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 09, 2015, 22:17:18 PM
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.

Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Milbo on March 10, 2015, 00:59:23 AM
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.
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 10, 2015, 01:13:10 AM
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 :)
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Genius WebDesign on March 10, 2015, 04:13:12 AM
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 :)
Title: Re: Trying to add "Multiple categories" selector to custom product module parameter
Post by: Milbo on March 10, 2015, 10:34:54 AM
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