J4 Tag Form Ajax

49 views
Skip to first unread message

Cole Coffman (Sk8ing4Life33)

unread,
Sep 1, 2022, 1:14:56 PMSep 1
to Joomla! General Development
Good Afternoon, 
I'm in the process of developing a custom component, and have added a tags form to a view along with other input fields. Right now i am wanting to make it so as the user types in populates with categories from my MySQL database table. I have looked around and resources seem to be lacking for J4 or don't really suit my needs. Any guidance on correct approaches would be much helpful and please let me know if you need anymore file info. I'm also unsure of how to actually process the user's input to begin with, i have used jquery and ajax in the past but never within joomla. 
Screenshot 2022-09-01 131112.png
Screenshot 2022-09-01 131320.png

Peter Tuson

unread,
Sep 1, 2022, 2:15:54 PMSep 1
to Joomla! General Development
Hello,

The form is described in an XML form using the standard field type defined at https://docs.joomla.org/Standard_form_field_types or custom fields.

Within the src/Helper folder I create a helper to run a getForm function that creates a new form based on the XML form and then fills in the fields with the currently known information. The main function then runs 
foreach ($form->getFieldsets() as $group => $fieldset) {
            $fields = $form->getFieldset($group);
            if (count($fields)) {
                echo '<fieldset class="form-group">';
                foreach ($fields as $field) echo $field->renderField();
                echo '</fieldset>';
            }
        } ?>
where $form is returned by the helper.

When pressing the submit button the action link is enabled supplemented by the values of the fields. You can then do what you like with the data.

With custom fields, you include the field within the src/Fields folder. How the custom field works is the same as J3 but there needs to be a link on the relevant fieldset of the form as addfieldprefix="Component\Component\Site\Component\Field" for example.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 1, 2022, 2:55:22 PMSep 1
to Joomla! General Development
Ok,  I'm not sure i quite understand what you are saying. Do i not want to use <?php echo $this->form->renderField('name');  ?> to render the forms? My main issue here is like a onkeyup type of approach of updating the tags based on users input. 

Cole Coffman (Sk8ing4Life33)

unread,
Sep 1, 2022, 2:59:12 PMSep 1
to Joomla! General Development
I see that the  joomla-field-fancy-select form object for the tag field has a remote-search url of  url="/index.php?option=com_tags&task=tags.searchAjax", im not sure where to set this or how to implement this properly. 

Peter Tuson

unread,
Sep 1, 2022, 3:15:12 PMSep 1
to Joomla! General Development
If you want to dynamically change things while the user is entering stuff then I would use JQuery. Enable it using HTMLHelper::_('jquery.framework') within the class displaying the form. Then write your own js code to do it. This is then stored in the media/js folder and you have to store it and use it like you do with css.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 1, 2022, 3:32:26 PMSep 1
to Joomla! General Development
alright if i understand this right, i should use jquery to listen for changes of the forms and use ajax to connect to database. This would require a helper php file i assume. How would i setup that file? also how would i set the values of tag form input field? Sorry if this seems simple, i've never really messed around with Joomla or any other CMS before. 

Peter Tuson

unread,
Sep 1, 2022, 3:47:29 PMSep 1
to Joomla! General Development
By tags do you mean Joomla tags that are added to articles etc.

Why do you need to connect to the database while the user is accessing the form. Is this to get new data or add data to the database?

A helper php file is named according to its class name and stored within the src/Helper folder. The helper file has a namespace like Company\Component\component-name\Site\Helper; The file using the helper has a use statement for the helper, e.g. use Company\Component\component-name\Site\Helper\NameHelper.

The namespace in the component xml file needs to have the path="src" added, e.g <namepace path="src">

You understood me correctly, jQuery can be used to listen and Ajax to talk to the server.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 1, 2022, 4:21:03 PMSep 1
to Joomla! General Development
I'm using the tags input form, and i want to show a list of available categories to the user and narrow down the results as they continue to type. Right now it has no functionality and just shows no results. Screenshot 2022-09-01 161302.png
These results would pull from the database and list all the categories that are currently in the database, and even add new categories if not already there. 

So i have added a helper php file named ajaxCategories.php in site/src/Helper with namespace ProgrammingTeam\Component\CatalogSystem\Site\Helper; which is defined in manifest.xml as <namespace path="src/">ProgrammingTeam\Component\CatalogSystem</namespace>

In my default.php view file is where i would do the use ProgrammingTeam\Component\CatalogSystem\Site\Helper\ajaxCategories. 

Then in a js file use JQuery to call ajax and what url would i use for this? and what does the helper do for me?

Peter Tuson

unread,
Sep 1, 2022, 6:07:47 PMSep 1
to Joomla! General Development
Hello Cole,

I have never used Ajax with Joomla.

When I have multiple selections of data that depend on the user selection then I use the 'showon' facility of the standard fields.

If I want the user to be able to filter as they type then I use the 'chosen' system, particularly if there are a large number of options.

Both of these use their own javascript.

I tend to use JQuery for adding hidden fields to a form to improve security.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 2, 2022, 2:20:49 PMSep 2
to Joomla! General Development
Ok, so i have managed to setup an ajax file that returns the info needed, my issue now is how to set it up so that the actual input field is being used by the tags form on the site. I'm not sure how to do this on Jquery side or if this is to be done within joomla some how. 

Peter Tuson

unread,
Sep 2, 2022, 2:45:33 PMSep 2
to Joomla! General Development

Hello Cole,

It is evening here and I am tired today.

I will try writing a plugin tomorrow morning at let you know how I get on.

Regards,

Peter.

Peter Tuson

unread,
Sep 3, 2022, 5:28:04 AMSep 3
to Joomla! General Development
Hello Cole,

I set up a plugin so that the user could type in 3 chars and the system would match that to existing tags using ajax GET. I could not get it to add extra tags.

I use a simple form.xml file:

<?xml version="1.0" encoding="utf-8"?>
<form>
  <fields name="tags">
    <fieldset name="details">
      <field name="name" id="name"  type="text" hint="Full Name" class="advancedSelect" label="Text" description="Text"/>
      <field name="tags" id="tagfield"  type="tag" label="JTAG" custom="allow" description="Tags" mode="ajax" class="inputbox small" multiple="true" />
    </fieldset>
  </fields>
</form>

and then a simple php file. This calls in the relevant joomla javascript.

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\Registry\Registry;
use Joomla\CMS\Uri\Uri;

$ajaxSettings = new Registry(array(
    'selector' => 'tagfield',
    'url'      => Uri::root() . 'index.php?option=com_tags&task=tags.searchAjax'
));

HTMLHelper::_('jquery.framework');
HTMLHelper::_('formbehavior.ajaxchosen', $ajaxSettings);

/**
 * A content plugin for adding bootstrap tabs to articles that have Regular Labs tabs
 * embedded in them.
 *
 * @since  1.6
 */
class PlgContentTestTags extends CMSPlugin
{
    /**
     * On content preparation modify urls and article text
     *
     * @param   string     $context  The context for the content.
     * @param   reference  $article  A reference to the article being rendered by the view.
     * @param   reference  $params   A reference to an associative array of relevant parameters
     * @param   integer    $page     The page of the content that is to be generated
     *
     * @return  none                 A boolean might be returned to check for success or failure
     *
     * @since   1.6
     */
    public function onContentPrepare($context, &$article, &$params, $page)
    {
        // Factory applications
        $app = Factory::getApplication();
       
        // Don't run this plugin when the content is being indexed
        if ($context != 'com_content.article') {
            return true;
        }
       
        // Simple content check to determine whether plugin should process further
        if (strpos($article->text, '{tags}') === false) {
            return true;
        }
       
        $txt = '';
        if ($form = $this->getForm()) {
            $txt .= '<form method="post" class="tagsForm form-horizontal" type="form" id="tagsForm" name="tagsForm" action="">';
            $txt .= '<fieldset class="tags_form">';
            $txt .= $form->renderFieldset('details');
            $txt .= '</fieldset">';
            $txt .= '<fieldset class="submit-tags">';
            $txt .= '<div><button class="btn btn-primary" type="submit" value="Submit" title="Subscribe request">Sign up</button></div>';
            $txt .= '</fieldset>';
            $txt .= '</form>';
        } else {
            $txt .= 'Warning: Could not find tags form!';
        }
       
        $article->text = str_replace('{tags}', $txt, $article->text);
    }
   
    /**
     * Prepare the form for display
     */
    private function getForm() {
        $form = new Form('tagsForm');
        $form->addFormPath(JPATH_BASE . '/plugins/content/testtags/forms');
        $form->loadFile('form', false);
        return $form;
    }
}

I didn't bother with helper files and the js is part of joomla.

I hope that helps.

Regards,

Peter.

Peter Tuson

unread,
Sep 3, 2022, 3:36:16 PMSep 3
to Joomla! General Development

Hello Cole,

Having looked at it, I think that for a user to add tags they need to be logged in and have permission to add them.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 3, 2022, 11:25:52 PMSep 3
to Joomla! General Development
I think we are going in the wrong direction, i think what i need is a custom field with fancy select layout. I've got the layout working but am working on how to make it work. From what i have found it looks like i need to set up another php in models/fields and use its getOptions function but im having trouble getting that to work. 

Peter Tuson

unread,
Sep 4, 2022, 4:43:44 AMSep 4
to Joomla! General Development
Hello Cole,

You haven't really explained what categories from a tags field means? A tags field returns tag names and values.

The core to a custom field is similar to J3.
Locate it in the src/Field folder and name it {Custom}Field.php.
Give it a namespace related to the overall namespace in the component xml file, e.g. Name/Component/Name/Site/Field
Extend it from the standard field that it is based on normally ListField, so 'use Joomla\CMS\Form\Field\ListField;'
Then define the class with 'class {Custom}Field extends ListField'.
Then you use the getOptions function as before.
If you are accessing a database then remember to use $db = Factory::getContainer()->get('DatabaseDriver');
Then remember to add the addFieldPrefix to the fieldset in the form.

That should work.

Regards,

Peter.

Peter Tuson

unread,
Sep 5, 2022, 4:22:09 AMSep 5
to Joomla! General Development
Hello Cole,

I can confirm that if you change the tag permissions for pubic users to create allowed then the plugin extension I did does enable the user the create new tags by typing them in and entering return or separating them with a comma.

Regards,

Peter.

Cole Coffman (Sk8ing4Life33)

unread,
Sep 5, 2022, 11:00:32 AMSep 5
to Joomla! General Development
Hello Peter, 
Categories doesn't really refer to anything Joomla related, I'm creating a filter search for a table of data from a database, and one of the columns is category, I want to be able to filter on multiple categories. So i want to use the fancy select to be able to select multiple in a 'tags' style. Then i need to return all the categories that are currently stored in the database on initial load and start narrowing down as user types. 

Cole Coffman (Sk8ing4Life33)

unread,
Sep 5, 2022, 11:09:02 AMSep 5
to Joomla! General Development
This is what i have so far in categoryField.php located in site/models/fields, and forms are in site/models/forms, but it looks like the categoryField.php is never used. Not sure why?

catergoryField.php https://pastebin.com/7tm2CP4b
catalog_search_form.xml https://pastebin.com/EgayVzvm

Peter Tuson

unread,
Sep 5, 2022, 12:28:53 PMSep 5
to Joomla! General Development
Hello Cole,

addfieldprefix in the xml should actually be addFieldPrefix, and you shouldn't need the addfieldpath. However, I note that one points to administrator and the other to site - is this correct? Is your component site or administrator? - the namespace needs to be consistent.

Also use $db = Factory::getContainer()->get('DatabaseDriver'); 

If the Joomla code can't find the custom field is assumes that the field is text without producing an error so we don't know why it can't find it.

Regards,

Peter.

Reply all
Reply to author
Forward
0 new messages