2

我想知道如何在组件的管理员编辑视图中集成链式选择列表。

我有 2 张桌子:Manufacturer&Model

两个表都使用一列进行索引,id并且 Model 表具有链接到制造商id列的外键。

目前,选择字段是 JForm“sql”类型字段,在 xml 中有查询以从数据库中提取所有模型。

我知道我需要在控制器中添加一个基于制造商获取模型值的函数,并使用带有 POST 的 AJAX 调用它(使用“task=myFunction”)。我只是想不出如何将返回的值返回到 JForm 中,因此 getInput 函数可以基于它们创建一个选择字段。

我已经看到 jQuery 插件仅根据先前选择的框过滤模型,但这似乎有点像作弊,我想以“正确”的方式来做。

非常感谢

4

2 回答 2

4

要回答我自己的问题...

我基于“SQL”类型的 joomla 标准表单域创建了一个自定义表单域。

在自定义表单字段中,我添加了 jQuery/AJAX,一旦此选择字段发生更改,将获取所选值,将其添加到 ajax $_GET 请求并调用子控制器中的任务。然后子控制器从jinput中获取选定的值,并将其传递给模型中的一个方法,该方法使用它为字段返回 JSON 数据。

我在询问时并不知道,但 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”数据传递给子控制器:{}。一旦填充了新选项,我们将调用.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();
}

它采用我们通过 Ajax 传递的“selectedValue”变量并将其与 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;
}

我希望这可以帮助别人!

于 2013-08-06T09:14:33.007 回答
0

首先,根据您的需要创建一个插件组,例如:content,然后在您的插件/模块上创建一个返回数据的方法/事件。

示例content

BASE / index.php?option=com_ajax&plugin=manufacturer&format=raw&group=content

相关问题

于 2016-03-09T09:50:30.327 回答