Чтобы ответить на мой собственный вопрос...
Я создал пользовательское поле формы на основе стандартного поля формы joomla типа «SQL».
В пользовательское поле формы я добавил jQuery/AJAX, который после изменения этого родительского поля выбора принимает выбранное значение, добавляет его к запросу ajax $_GET и вызывает задачу в субконтроллере. Затем субконтроллер получает выбранное значение из jinput и передает его методу в модели, который использует его для возврата данных JSON для поля child.
Я не знал об этом, когда спрашивал, но Joomla использует плагин jQuery Chosen, чтобы скрыть стандартные HTML-списки выбора болота и создать вместо них красивые живые выпадающие списки с возможностью поиска. Также я только что заметил, что joomla 3.1 теперь включает плагин Ajax Chosen, но у меня такое чувство, что его реализация предназначена только для тегов? Может быть, кто-то может пролить свет на это?
Функция getOptions пользовательского поля выглядит примерно так:
protected function getOptions()
{
// Build the script.
$script = array();
$script[] = 'jQuery(document).ready(function() { ';
$script[] = ' jQuery("#jform_child").trigger("liszt:updated"); ';
$script[] = ' jQuery("#jform_parent").chosen().change( function() { ';
$script[] = ' var selectedValue = jQuery("#jform_parent").val(); ';
$script[] = ' jQuery.ajax({ ';
$script[] = ' type: "GET", ';
$script[] = ' dataType: "json", ';
$script[] = ' url: "index.php?option=com_mycomponent&task=myview.controllerTask", ';
$script[] = ' data: { ';
$script[] = ' "selectedValue": selectedValue ';
$script[] = ' }, ';
$script[] = ' success:function(data) { ';
$script[] = ' jQuery("select#jform_child option").remove(); ';
$script[] = ' jQuery.each(data, function(i, item) { ';
$script[] = ' jQuery("select#jform_child").append( "<option value="+ i +">" + item + "</option>" ); ';
$script[] = ' }); ';
$script[] = ' jQuery("select").trigger("liszt:updated"); ';
$script[] = ' } ';
$script[] = ' }); ';
$script[] = ' }); ';
$script[] = '}); ';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
$options = array();
// Initialize some field attributes.
$key = $this->element['key_field'] ? (string) $this->element['key_field'] : 'value';
$value = $this->element['value_field'] ? (string) $this->element['value_field'] : (string) $this->element['name'];
$translate = $this->element['translate'] ? (string) $this->element['translate'] : false;
$query = (string) $this->element['query'];
// Get the database object.
$db = JFactory::getDbo();
// Set the query and get the result list.
$db->setQuery($query);
$items = $db->loadObjectlist();
// Build the field options.
if (!empty($items))
{
foreach ($items as $item)
{
if ($translate == true)
{
$options[] = JHtml::_('select.option', $item->$key, JText::_($item->$value));
}
else
{
$options[] = JHtml::_('select.option', $item->$key, $item->$value);
}
}
}
// Merge any additional options in the XML definition.
$options = array_merge(parent::getOptions(), $options);
return $options;
}
Как видите, jQuery удаляет текущие параметры выбора из дочернего поля и заполняет его новыми параметрами, полученными из субконтроллера. Выбранное значение родительского поля выбора передается субконтроллеру в виде переменной "selectedValue" data: { }. Как только новые параметры заполнены, мы вызываем .trigger("liszt:updated")
в дочернем поле, это заставит плагин Chosen перестроить меню выбора с новыми параметрами.
В любом случае - вот задача субконтроллера:
public function controllerTask()
{
JFactory::getDocument()->setMimeEncoding( 'application/json' );
JResponse::setHeader('Content-Disposition','attachment;filename="progress-report-results.json"');
$jinput = JFactory::getApplication()->input;
$selectedValue = $jinput->get('selectedValue');
$model = $this->getModel();
echo json_encode($model->modelMethod($selectedValue));
JFactory::getApplication()->close();
}
Он берет переменную «selectedValue», которую мы передали с помощью Ajax, и использует ее с помощью метода modelMethod. В нашем случае modelMethod принимает переменную «selectedValue» и возвращает список дочерних данных, которые будут отображаться в дочернем поле.
Вот этот метод модели:
public function modelMethod($selectedValue) {
$db = JFactory::getDbo();
$db->setQuery("SELECT 0 AS `id`, '- Please select a child -' AS `child` UNION SELECT id, child FROM #__mycomponent_children WHERE #__mycomponent_children.parent = " . $selectedValue);
$list = $db->loadObjectList();
foreach ($list as $option) {
$options[$option->id] = $option->child;
}
return $options;
}
Я надеюсь, что это поможет кому-то!
person
mousebat
schedule
06.08.2013