web-dev-qa-db-fra.com

Comment exécuter un script ajax pour mettre à jour des champs de formulaire dans un fichier .xml rendu par Akeeba FOF?

Je voudrais remplir la liste d'options de sélection "Propriétaire" en sélectionnant la colonne owner dans la table #__gscrm_accounts OERE la gscrm_account_id (Clé primaire) est la "Personne ou Entreprise" sélectionnée " valeur.

Cet ajax doit être déclenché par l'événement onchange() de <field name="account"> Puis remplir <field name="owner">.

enter image description here

Pour être clair, je ne sais pas s'il s'agit d'une copie "fraîche" ou "modifiée" de SimpleCRM parce que je n'ai jamais utilisé SimpleCRM et que ce projet vient d'être lancé sur moi.

Dans components/com_gscrm/View/Notes/tmpl/form.form.xml , le champ de sélection "Person or Business" est généré à partir de:

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

Le champ "Propriétaire de ce contact" est généré par:

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

Je sais que je vais devoir ajouter un peu de complexité à la requête dont j'ai réellement besoin et ce n'est peut-être pas une seule valeur "propriétaire" que je renvoie, mais ma question est: Comment puis-je exécuter le processus ajax en utilisant les meilleures pratiques et les classes/méthodes préexistantes si possible?

J'ai jeté un œil à https://docs.joomla.org/J3.x:Developing_an_MVC_Component/Adding_AJAX mais cela ne concerne pas spécifiquement les balises <field>.

Cela semble proche: Comment changer la liste de sélection d'une autre en utilisant AJAX dans Joomla mais je ne suis pas sûr du meilleur placement des fichiers et je n'ai pas affaire à chozen éléments.

la réponse de Soren indique que je devrais créer une URL comme:

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

Si oui, où dois-je garer au mieux ma méthode getOwners()?

Chargement des options d'un champ de formulaire sélectionné via jQuery Ajax semble similaire, mais surtout des yatta-yattas sur les éléments fondamentaux dont j'ai besoin:

Tous les messages ont un peu d'âge sur eux et je m'attends à voir un jeton utilisé dans ce processus.

2
mickmackusa

Vous pouvez utiliser le format JSON dans le contrôleur directement en ajoutant le suffixe .json Et en changeant format dans votre URL en json. Dans ce cas, le contrôleur serait placé dans /administrator/components/com_example/controllers/ajax.json.php. Son contenu:

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

Dans la présentation de la vue formulaire:

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');

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

Dans le formulaire XML, ajoutez ceci au champ qui déclenche l'événement. Où fieldToUpdate est le nom du champ qui sera mis à jour.

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

Cela suppose qu'une seule ligne est attendue de la base de données. Pour plusieurs valeurs, remplacez loadObject() par loadObjectList() dans le contrôleur et exécutez une boucle dans le script:

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

La méthode du plugin. S'il s'agit d'un composant tiers, nous pouvons utiliser un plugin et interagir avec com_ajax À la place. L'avantage est que les fichiers originaux ne sont pas du tout touchés. Cela permet de mettre à jour le composant sans perdre les personnalisations. Au lieu de modifier la mise en page, le fichier de formulaire et l'ajout d'un contrôleur, nous avons juste un plugin:

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

Dans le script AJAX nous n'avons besoin que de deux ajustements:

1) Définissez l'URL de la demande sur com_ajax:

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

2) Lors de l'accès aux données de réponse, utilisez le premier élément du tableau:

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

Dans ce cas également, le formulaire n'a pas de préfixe. Le sélecteur d'ID est donc plus simple:

var fieldId = '#' + field;
4
Sharky

Ce composant est développé en utilisant Akeeba FOF , vous devez donc lire la documentation pour savoir comment terminer la tâche.

Presque tout est configuré en utilisant XML, c'est dans une certaine mesure bien sûr.

Pour ajouter le code javascript onchange à la liste déroulante: https://github.com/akeeba/fof/wiki/XML-Form-Fields#additional-attributes-for-drop-down-list-fields =

Regardez également la vue JSON pour savoir comment créer la réponse json: https://github.com/akeeba/fof/wiki/The-JSON-view

[~ # ~] modifier [~ # ~]

Pour charger un fichier js dans cette vue de formulaire, utilisez l'attribut jsfiles de l'élément form xml, donc dans le fichier components/com_gscrm/View/Notes/tmpl/form.form.xml changez la définition de formulaire pour qu'elle soit comme ça

<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"

>

assurez-vous de remplacer yourfile.js avec le nom de fichier correct.

Pour plus de détails, regardez cette page: https://github.com/akeeba/fof/wiki/XML-Forms

Mise à jour

Pour vous plaindre auprès de FOF, procédez comme suit:

  1. Créez un dossier dans la partie admin, nommez-le Controller
  2. Créez un fichier PHP à l'intérieur, nommez-le Ajax.php
  3. Le contenu du fichier doit ressembler à ceci:
<?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. Ensuite, l'appel ajax devrait ressembler à ceci:
$.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
Mohamed Abdelaziz

Si je comprends ce que vous essayez d'accomplir, le moyen le plus simple serait d'utiliser un peu de jQuery et un appel ajax. Ajoutez une méthode à l'un de vos fichiers de contrôleur qui renvoie la valeur du champ propriétaire. Publiez l'ID de la personne/entreprise déposée sur ce contrôleur à l'aide de ajax.Retournez l'ID du champ propriétaire. Utilisez jQuery pour définir l'option sur la valeur appropriée.

0
Terry Carter