web-dev-qa-db-ja.com

Ajaxスクリプトを実行して、Akeeba FOFによってレンダリングされた.xmlファイルのフォームフィールドを更新する方法

_#__gscrm_accounts_テーブルからowner列を選択して、「所有者」選択オプションリストにデータを入力します。ここで、_gscrm_account_id_(主キー)は、選択された「個人またはビジネス」の値です。

このajaxは、_<field name="account">_のonchange()イベントによってトリガーされ、次に_<field name="owner">_に入力する必要があります。

enter image description here

明確にするために、これがSimpleCRMの「新しい」コピーか「変更された」コピーかはわかりません。これは、SimpleCRMを使用したことがなく、このプロジェクトが私に投げられただけだからです。

components/com_gscrm/View/Notes/tmpl/form.form.xmlでは、「Person or Business」選択フィールドは以下から生成されます。

_<field name="account" class="high28" labelclass="label_left" label_placement="top"
    label="COM_GSCRM_NOTES_ACCOUNT_LABEL" tooltip="COM_GSCRM_NOTES_ACCOUNT_DESC"
    type="Model"
    model="Accounts"
    key_field="gscrm_account_id"
    value_field="title"
    apply_access="true"
    apply_enabled="true"
    none="GS_SELECT"
>
    <state key="code">[ITEM:CODE]</state>
</field>
_

「この連絡先の所有者」フィールドは次のように生成されます:

_<field name="owner" emptylabel="1" class="high28" labelclass="label_left" label_placement="top" label="COM_GSCRM_NOTES_OWNER_LABEL"
    type="Model"
    model="Beads"
    key_field="gscrm_bead_id"
    value_field="user_name"
    apply_access="true"
    apply_enabled="true"
    none="GS_NOT_AVAILABLE"
>
    <state key="code">[ITEM:CODE]</state>               
</field>
_

実際に必要なクエリに少し複雑さを追加する必要があることはわかっていますが、返すのは単一の「所有者」値ではない可能性がありますが、私の質問はです。可能な場合は、ベストプラクティスと既存のクラス/メソッドを使用してajaxプロセスを実行しますか?

https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Adding_AJAX を確認しましたが、これは特に_<field>_タグを扱っていません。

これはよく見えます: AJAX)を使用して別のリストから選択リストを変更する方法 ですが、ファイルの最適な配置がわからず、選択されたものを処理していません要素。

ソレンの答え は、次のようなURLを作成する必要があることを示しています。

_index.php?option=com_gscrm&task=ajax.getOwners&format=raw&var=[the_selected_value]
_

もしそうなら、どこにgetOwners()メソッドを駐車すればいいですか?

jQuery Ajaxを介して選択フォームフィールドのオプションをロードする は似ていますが、ほとんどの場合、私が必要とする基本的な部分についてはyatta-yattasです:

すべての投稿にはかなりの年齢があり、このプロセスで使用されるトークンが表示されることを期待しています。

2
mickmackusa

_.json_サフィックスを追加し、URLのformatjsonに変更することで、コントローラーでJSON形式を直接使用できます。この場合、コントローラーは_/administrator/components/com_example/controllers/ajax.json.php_に配置されます。それは内容です:

_defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Response\JsonResponse;

class ExampleControllerAjax extends JControllerLegacy
{
    public function getOwners()
    {
        // Check for request forgeries.
        $this->checkToken();

        // Get our stuff.
        $db = Factory::getDbo();
        $query = $db->getQuery(true)
            ->select($db->quoteName(['name', 'id']))
            ->from($db->quoteName('#__example'))
            ->where($db->quoteName('id') . ' = ' . $this->input->getInt('exampleId'));
        $result = $db->setQuery($query)->loadObject();

        // Output as JSON
        echo new JsonResponse($result);
    }
}
_

フォームビューのレイアウト:

_use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;

// Add session token script.
HTMLHelper::_('behavior.core');

// Optional AJAX error message.
Text::script('COM_EXAMPLE_AJAX_ERROR');
_

AJAXスクリプト:

_// Optional, define namespace.
Example = window.Example || {};

Example.updateOwners = function(exampleId, field) 
{
    // Get session token.
    var token = Joomla.getOptions('csrf.token');

    // Build a selector for the field we want to update. This example is for the filter form.
    var fieldId = '#filter_' + field;

    // Doing it this way so token can be submitted via POST
    var postData = {'exampleId' : exampleId};
    postData[token] = 1;

    jQuery.ajax(
    {
        url:  'index.php?option=com_example&task=ajax.getOwners&format=json',
        data: postData,
        method: 'POST',
        success: function(response, status, xhr) {

            // Clear existing value.
            jQuery(fieldId).empty();

            // Add new value.
            jQuery('<option />', {value: response.data.id, text: response.data.name}).appendTo(fieldId);

            // Update chosen.
            jQuery(fieldId).trigger("liszt:updated");
        },
        error: function() { Joomla.renderMessages({"warning":[(Joomla.Text._('COM_EXAMPLE_AJAX_ERROR'))]}); },
    });

    return false;
}
_

XMLフォームで、これをイベントをトリガーするフィールドに追加します。ここで、fieldToUpdateは更新されるフィールドの名前です。

_onchange="Example.updateOwners(this.value, 'fieldToUpdate');"
_

これは、データベースから単一の行が予想されることを前提としています。複数の値の場合、コントローラーでloadObject()loadObjectList()に変更し、スクリプトでループを実行します。

_jQuery.each(response.data, function(){
    jQuery('<option />', {value: this.id, text: this.name}).appendTo(fieldId);
});
_

プラグインメソッドこれがサードパーティのコンポーネントである場合、プラグインを使用して、代わりに_com_ajax_とやり取りできます。これの利点は、元のファイルがまったく変更されないことです。これにより、カスタマイズを失うことなくコンポーネントを更新できます。レイアウト、フォームファイルを変更してコントローラーを追加する代わりに、プラグインは1つだけです。

_defined('_JEXEC') or die;

use Joomla\CMS\Form\Form;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Session\Session;

class PlgContentExample extends CMSPlugin
{
    protected $app;

    protected $db;

    public function onContentPrepareForm(Form $form, $data)
    {
        // Check that we're manipulating the correct form.
        if ($form->getName() !== 'com_gscrm.Notes.form.form')
        {
            return true;
        }

        // Run only on HTML document.
        if ($this->app->getDocument()->getType() !== 'html')
        {
            return true;
        }

        // Load form token script.
        HTMLHelper::_('behavior.core');

        // Load AJAX script.
        HTMLHelper::_('script', 'plg_content_example/ajax.js', ['version' => 'auto', 'relative' => true]);

        // Add error message string.
        Text::script('PLG_CONTENT_EXAMPLE_AJAX_ERROR');

        // Add onchange attribute to the field.
        $form->setFieldAttribute('type', 'onchange', 'Example.updateOwners(this.value, \'owner\');');
    }

    public function onAjaxExample()
    {
        if (!Session::checkToken())
        {
            throw new \Exception('JINVALID_TOKEN');
        }

        // Get our stuff.
        $query = $this->db->getQuery(true)
            ->select($this->db->quoteName(['name', 'id']))
            ->from($this->db->quoteName('#__example'))
            ->where($this->db->quoteName('id') . ' = ' . $this->app->input->getInt('exampleId'));
        $result = $this->db->setQuery($query)->loadObject();

        return $result;
    }
}
_

AJAXスクリプトでは、2つの調整のみが必要です。

1)リクエストURLを_com_ajax_に設定します。

_url:  'index.php?option=com_ajax&plugin=example&group=content&format=json',
_

2)応答データにアクセスするときは、最初の配列要素を使用します。

_jQuery('<option />', {value: response.data[0].id, text: response.data[0].name}).appendTo(fieldId);
_

また、この特定のケースでは、フォームには接頭辞がありません。したがって、IDセレクターの方が簡単です。

_var fieldId = '#' + field;
_
4
Sharky

このコンポーネントは Akeeba FOF を使用して開発されているため、ドキュメントを読んでタスクを完了する方法を知る必要があります。

ほとんどすべてがXMLを使用して構成されていますが、これはもちろんある程度です。

Onchange JavaScriptコードをドロップダウンリストに追加するには、次のようにします。 https://github.com/akeeba/fof/wiki/XML-Form-Fields#additional-attributes-for-drop-down-list-fields =

また、JSONビューを見て、json応答の作成方法を確認します。 https://github.com/akeeba/fof/wiki/The-JSON-view

[〜#〜]編集[〜#〜]

このフォームビューにjsファイルをロードするには、フォームのxml要素のjsfiles属性を使用して、ファイルcomponents/com_gscrm/View/Notes/tmpl/form.form.xmlでフォームの定義を次のように変更します。このような

<form 
    validate="true"
    jsfiles="media://com_gscrm/js/yourfile.js"
    lessfiles="media://com_gs_bootstrap337/css/gs.less||media://com_gs_bootstrap337/css/bootstrap.css"

>

yourfile.jsを正しいファイル名に置き換えてください。

詳細については、このページをご覧ください: https://github.com/akeeba/fof/wiki/XML-Forms

更新

FOFに準拠するには、次の操作を行います。

  1. 管理パーツにフォルダーを作成し、Controllerという名前を付けます
  2. その中にPHPファイルを作成し、Ajax.phpという名前を付けます
  3. ファイルの内容は次のようになります。
<?php
/**
 * 
 */

namespace Gs\Gscrm\Admin\Controller;
use FOF30\Controller\Controller;

defined('_JEXEC') or die;

class Ajax extends Controller
{
  function getOwners()
  {
      // Token check
      $this->csrfProtection();
        /* insert your code to get owners in json format*/
      $this->container->platform->closeApplication();
  }
}
  1. その後、ajax呼び出しは次のようになります。
$.get(
              'index.php',
              {
                  'option':     'com_gscrm',
                  'view':       'Ajax',
                  'format':     'json',
                  'task':       'getOwners',
                  '<?php echo $this->container->platform->getToken(true) ?>':   1,
                  'id':    id
              },
              function (data, textStatus)
              {
                  // insert here the code to populate the owners list
              }           )
3

私があなたが簡単な方法を達成しようとしていることを理解しているなら、これは少しのjQueryとajax呼び出しであるでしょう。所有者フィールドの値を返すメソッドをコントローラーファイルの1つに追加します。 ajaxを使用して、そのコントローラーに提出された個人/ビジネスのIDを投稿します。所有者フィールドのIDを返します。 jQueryを使用して、オプションを適切な値に設定します。

0
Terry Carter