A nifty jQuery function called trigger()

jQuery is a simple and efficient javascript library. I do most of the front-end related magic using jQuery & CSS alone, with minimal intervention from server side. This is because, in CMS/Frameworks like WordPress, Drupal, the UX actions would already be defined, and it would only make the entire system complex to re-design those.

A similar case happened in Drupal. In my last post, I mentioned working on a project on Drupal 8. Well, as I mentioned there, we use Drupal Webform module to create the form. This is a great module, with so much example modules pre-packaged with it, which I used to create a custom composite element.

A custom composite in Webforms refer to a collection of elements, packaged as a single element, such as address. We know address requires some common elements, like address line, street, city, postcode and so on. Instead of adding multiple fields into the webform, it would be easier to add one element. The reason I did is because we need an option to add multiple products, which was only possible with custom composite element.

Coming back to the point, an element was added with 4 fields, and the submission for the element set to ‘Unlimited’. This makes it possible to add infinite number of fields for the composite element ( like adding multiple address in a single form ). However, the form had a small trouble. Adding a new product means creating 3 rows under the previous row, which was making the form lengthy, and that was an issue.

In order to resolve this issue, we used a computed twig element. It is basically used for performing complex calculation dynamically within the form, but can be used to do much more. You will need some trial and errors to make it working. I created a HTML table and set it to display the entries in the composite element, with a delete button in the end.

Now that everything is set in place, there was the main problems:

  1. Newly added product needs to be populated in the table.
  2. Delete a row from the selected products.
  3. Update the Computed table with products
  4. Hide the first set of elements.

As we were on a multi-step ajax driven webform, I had no idea how to get this done programatically. Went in hours of research which yielded nothing. Then it struck me, the actions are already there for the user to perform, such as adding or removing products. The problem was that, we cannot use their buttons for the user experience. So came along the trigger() function. I only need to figure out which action triggers the ajax requests.

Using the Web Inspector tool, I was able to determine that the mouseover event triggers the add new item action, and delete action. I created two new buttons for add and delete, and for the onclick action, triggered the original action as seen below

$(function(){
$('body').on('click', '.my-add-btn', function(e){
e.preventDefault();
$($selector).trigger('mouseover');
$($computed_twig).trigger('click');
});
})

  • $selector is the button which is used to add new row.
  • $computed_twig is the button used for updating the twig element ( usually hidden in the theme )
  • e.preventDefault() to prevent page reload as the button will be considered an action button due to the placement beside Save & Next buttons.

You would also notice that I added the ‘click’ for the body. It is because the page is ajax driven, and the .my-add-btn class do not have any event listeners. By passing the element as a selector for the on() function, it will ensure that the action will be triggered regardless the element being dynamically generated by AJAX.

This same logic was applied to the delete button, which triggers the mouseover on the actual delete button, and performs the deletion operation, though I had to use ajaxStart() and ajaxStop() global handlers to disable and enable the button during the course of deletion.

To conclude, trigger() function manipulates the system to think that an actual person performed the action, and it would proceed accordingly. One needs to find the actual trigger and apply it to the trigger function. This would reduce the development time as we wouldn’t need to re-invent the wheel…

How I created custom HTML Tables in Drupal 8 using views module

Drupal is a complex framework for a beginner. It is not only because of the advanced documentation, but the lack of it. I had recently started out on Drupal, and it was an entirely different experience than the WordPress or Opencart which I was used to in the course of time.

Unlike WordPress, there are not many modules that we can use in Drupal to get something to work. But there are hooks, templates and a useful utility called drush in Drupal which helps you to keep moving.

Consider the Views module in Drupal. It has been included in the core version of Drupal. I am relatively new to this system, but this module is fun to create pages from other contents in the site with ease. In my recent project, we were using Drupal Webforms for generating a complex form for accepting orders. The requirements for the submissions were as follows

  1. List all orders in a page
  2. User can change the status of an order without going to any other page
  3. User & Administrator can exchange comments in the page
  4. Show a tooltip in the header

Although, the above might seem simple, it is difficult to achieve in Drupal. This is because, the webform module doesn’t have connection to the internal Comments module. We cannot comment on the submissions individually out of the box, and probably cannot be achieved as per the reply quoted below ( Drupal Webform Issue )

Comments are not (and will not) be supported. As noted on the project page, submissions are not nodes, which are the only thing that can be commented on in Drupal.

So in order to add comments, I first converted the webform submission to a node using a module Webform Content Creator. Comments can be easily added to the nodes, and order listing pages can be generated using the Drupal Views Module.

However, in the views module, with the display format as Table, we cannot set the view to be shown in multi-lines. ( Know about creating a page here ). After much research, I stumbled across the View Field Templates in an article for Drupal 7, I decided to give it a try. We could easily find the templates used for the view using the web inspector by enabling Twig Debugging in Drupal. It can either be done via enabling the Twig Debugging in sites/default/services.yml or by installing a module. I went for the second route.

The succeeding steps were simple enough. Copy the template for the required field, and put it in the custom theme’s template folder and rename the template files ( Pretty much explained in detail here ). For putting the comments column in next row, all I had to do was prepend the following before the {{ output- }} in the twig file

</td>
</tr>
<tr class=’new_row’>
<td colspan=”10″>

The colspan is to make the row stretch full span instead of limiting to one row.

We can add custom HTML elements, such as select boxes in these template files, and output it into the table. So I created a select box to change status and update it dynamically using Ajax. I had created a custom module to function as the ajax callback, which would update the status.

In conclusion, by editing the View Fields template & View Page templates, we can achieve any custom requirement that is needed. All that is required is the twig debugger, which will show the template in use, copy it into the sub-theme where all the customisations are made.