Joomla JForm 带外键、Ajax 和 jQuery 的链式选择

问题描述 投票:0回答:2

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

我有 2 张桌子:

Manufacturer
Model

两个表都使用列

id
进行索引,模型表有一个外键链接到制造商的
id
列。

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

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

我见过 jQuery 插件只是根据之前选择的框过滤模型,但这似乎有点作弊,我想以“正确”的方式做到这一点。

非常感谢

php jquery ajax joomla html-select
2个回答
4
投票

回答我自己的问题...

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

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

我在询问时并不知道,但 Joomla 使用 jQuery Chosen 插件来隐藏 bog 标准 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")
,这将使选择的插件使用新选项重建选择菜单。

无论如何 - 这是子控制器的任务:

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;
}

我希望这对某人有帮助!


0
投票

首先,根据您的需要创建一个插件组,例如:

content
,然后在您的插件/模块上创建一个返回数据的方法/事件。

content
的示例:

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

相关问题

© www.soinside.com 2019 - 2024. All rights reserved.