Well after a hell of a struggle and no help here whatsoever I can finally say that I have done it. Here is the process for any googlers in the future:
To build a dynamic dropdown you have to do a bunch of thing right for it to be pulled together by Joomla finally.
Also remember to read the documentation carefully, This answer's methods are not contained in it but maybe someone will wake up and put it there someday.
So after inspection of how the 1.6 architecture puts module variables together using the XML build file here we go.
The XML will look something like this :
<?xml version="1.0" encoding="UTF-8"?>
<extension type="module" version="1.6.0" client="site">
<name>...</name>
<author>...</author>
<creationDate>April 2011</creationDate>
<copyright>Copyright (C) 2011 ... All rights reserved.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>...</authorEmail>
<authorUrl>...</authorUrl>
<version>1.6.0</version>
<description>
...
</description>
<files>
<filename module="mod_your_mod">mod_your_mod.php</filename>
<filename>helper.php</filename>
<filename>index.html</filename>
<folder>tmpl</folder>
<folder>elements</folder>
<folder>lib</folder>
</files>
<languages />
<help />
<config>
<fields name="params">
<fieldset name="basic">
<!-- Custom field, list selection from API -->
<!-- Path to module external parameters -->
<field addfieldpath="/modules/mod_your_mod/elements"
name="mod_your_mod_id_selection" <!-- Name of variable -->
type="lists" <!-- New variable type -->
default=""
label="Select lists"
description="This is the list selection, where you select the list a contact can subscribe to." />
</fieldset>
<fieldset
name="advanced">
<field
name="layout"
type="modulelayout"
label="JFIELD_ALT_LAYOUT_LABEL"
description="JFIELD_ALT_MODULE_LAYOUT_DESC" />
<field
name="moduleclass_sfx"
type="text"
label="COM_MODULES_FIELD_MODULECLASS_SFX_LABEL"
description="COM_MODULES_FIELD_MODULECLASS_SFX_DESC" />
<field
name="cache"
type="list"
default="1"
label="COM_MODULES_FIELD_CACHING_LABEL"
description="COM_MODULES_FIELD_CACHING_DESC">
<option
value="1">JGLOBAL_USE_GLOBAL</option>
<option
value="0">COM_MODULES_FIELD_VALUE_NOCACHING</option>
</field>
<field
name="cache_time"
type="text"
default="900"
label="COM_MODULES_FIELD_CACHE_TIME_LABEL"
description="COM_MODULES_FIELD_CACHE_TIME_DESC" />
<field
name="cachemode"
type="hidden"
default="itemid">
<option value="itemid"></option>
</field>
</fieldset>
</fields>
</config>
</extension>
So after following the Joomla way of implementing a module here and here, I added the new parameter variable type into the elements
folder as lists.php
, see the name is the same as the type you declared in the XML file.
The class inside of this file looks like this :
<?php
// No direct access
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
jimport('joomla.html.html');
//import the necessary class definition for formfield
jimport('joomla.form.formfield');
// Include API utility file
require_once(dirname(__FILE__) . '/../lib/your_api.php');
class JFormFieldLists extends JFormField
{
/**
* The form field type.
*
* @var string
* @since 1.6
*/
protected $type = 'lists'; //the form field type see the name is the same
/**
* Method to retrieve the lists that resides in your application using the API.
*
* @return array The field option objects.
* @since 1.6
*/
protected function getInput()
{
$options = array();
$attr = '';
$attr .= ' multiple="multiple"';
$attr .= ' style="width:220px;height:220px;"';
// Get the database instance
$db = JFactory::getDbo();
// Build the select query
$query = 'SELECT params FROM jos_modules'
. ' WHERE module="mod_your_mod"';
$db->setQuery($query);
$params = $db->loadObjectList();
// Decode the options to get thje api key and url
$options = json_decode($params[0]->params, true);
// Gracefully catch empty fields
if ( empty($options['api_key']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add an API key'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
if ( empty($options['url']) === true )
{
$tmp = JHtml::_(
'select.option',
0,
'No lists available, please add the enterprise URL'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
// Create a new API utility class
$api = new APIClass(
$options['url'],
$options['api_key']
);
try
{
// Get the lists needed for subscription
$response = $api->getLists();
}
catch ( Exception $e )
{
$tmp = JHtml::_(
'select.option',
0,
'Could not connect to the API'
);
$lists[] = $tmp;
// The dropdown output, return empty list if no API key specified
return JHTML::_(
'select.genericlist',
$lists,
$this->name,
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
$lists = array();
// Builds the options for the dropdown
foreach ( $response['data'] as $list )
{
// Build options object here
$tmp = JHtml::_(
'select.option',
$list['list_id'],
$list['list_name']
);
$lists[] = $tmp;
}
// The dropdown output
/* The name of the select box MUST be the same as in the XML file otherwise
* saving your selection using Joomla will NOT work. Also if you want to make it
* multiple selects don't forget the [].
*/
return JHTML::_(
'select.genericlist',
$lists,
'jform[params][mod_your_mod_id_selection][]',
trim($attr),
'value',
'text',
$this->value,
$this->id
);
}
}
?>
So you will know when everything is working because your selection of the drop down list, built by the API(hence completely dynamic), will save into the module database entry with the name of the select box which you can easily retrieve by calling:
$api_key = $params->get('api_key', '');
in your module file. In this case its called mod_your_mod.php
.
I really hope that this helps you when defining customized parameters in the back end of your Joomla 1.6 modules. This allows for extreme customizations and integrates tightly with whatever application you like to use's API.
The only downside is that it might be slow, but using a bunch of checks it fails gracefully when the API is down or not pulling data through correctly. All in all a very unpleasant CMS to work with but that is only my opinion.