Drupal Association blog: Drupal Association Board Member Announcement - Welcome, Lynne Capozzi!

Please join the Drupal Association in welcoming our new board member:

Lynne Capozzi

Image removed.

When accepting her position, Lynne shared: “I’m excited to join the Drupal Association Board, and I’m hopeful that my past experience at Acquia and my nonprofit and marketing experience can benefit the community and help the community to grow!”

About Lynne
Most recently, Lynne was the Chief Marketing Officer (CMO) at Acquia in Boston. Lynne was at Acquia for eight years in this role.

As Acquia’s CMO, Lynne Capozzi oversaw all global marketing functions, including digital marketing, demand generation, operations, regional and field marketing, customer and partner marketing, events, vertical strategy, analyst relations, content, and corporate communications.
Lynne is one of Acquia’s boomerang stories, first serving as Acquia’s CMO in 2009. Lynne left Acquia in 2011 to pursue her nonprofit work full-time and then returned to Acquia in late 2016 to lead the marketing organization into its next growth stage.

Prior to her experience at Acquia, Lynne held various marketing leadership roles in the technology space. She served as CMO at JackBe, an enterprise mashup software company for real-time intelligence applications that Software AG acquired. Before that, Lynne was CMO at Systinet, which Mercury Interactive acquired. Lynne was also a VP at Lotus Development, which IBM later acquired.

Lynne is on the board of directors at the Boston Children’s Hospital Trust and runs a nonprofit through the hospital. She is also on the Advisory Board of Family Services of Merrimack Valley and the Board chair of the West Parish Garden Cemetery and Chapel in Andover, Mass.

We are thrilled to have Lynne on the Drupal Association Board!

Evolving Web: Customizing Web Experiences for Users with Disabilities

Image removed.

Customization touches every part of our lives, from how we take our coffee to the way we style our clothes and beyond. It’s no surprise that users want the same control over their digital experiences. Organizations that offer this control are better able to meet the different – and sometimes conflicting – needs of their various audiences. This is particularly relevant when ensuring your digital platform is accessible to users with disabilities. 

This article explores the concept of customization and why it’s a critical tool for ensuring web accessibility. 

A Quick Recap of Reasons to be Accessible

Before we get stuck into the relationship between customization and accessibility, here’s a refresher on the importance of building digital experiences for everyone.

It’s a Legal Requirement

Web accessibility is the law for many organizations. In Canada, organizations under federal jurisdiction must comply with The Accessible Canada Act, which follows the Web Content Accessibility Guidelines (WCAG.) There are also provincial accessibility acts in Ontario, Manitoba, Nova Scotia, Quebec, and British Columbia.

It’s the Right Thing to Do

People with disabilities deserve equal access to your content. Web accessibility is increasingly vital as more people rely on the internet as their primary gateway to information and services. 

It Widens Your Reach

Over 6.2 million people in Canada are living with a disability. Worldwide, that figure hits around 1.1 billion. If you haven’t made your website accessible, you’re missing out on opportunities to connect with a considerable proportion of the population. 

“I really consider the care that goes into creating an inclusive environment. Opening up about my disability has brought me liberation and support, and has driven me to be more empathetic towards other people living with disabilities – especially disabilities that are unseen.”

– Annabelle*, who lives with a disability. 

*Name has been changed to protect the person’s privacy.

The Issue of a One-Size-Fits-All Approach to Accessibility

While investing in web accessibility is a no-brainer, achieving it is rarely straightforward. One of the biggest challenges is the sheer variety of accessibility needs. 

Consider how many different types of disabilities there are. These generally fall into four categories:

  • Visual – such as blindness, low vision or color blindness
  • Auditory – such as Deaf/deaf and hard of hearing
  • Motor – such as limited fine motor controls or joint pain
  • Cognitive – such as dyslexia or autism spectrum disorders

Next, consider the various assistive technologies that may be used to access and navigate your site:

  • Screen readers – convert text, links, images, and other digital elements into speech 
  • Screen magnifiers – can make elements on a screen bigger
  • Head wands and mouth sticks – respond to head, mouth or chin movements to allow users to control their keyboard and cursor 
  • Refreshable braille displays – convert information into braille by electronically raising and lowering different combinations of pins

Finally, even within the same disability ‘groups’, people’s needs will vary due to factors such as:

  • Different levels of disability 
  • Different combinations and overlaps of disabilities 
  • If the disability is situational, temporary, or changing over time 

Content that’s understandable to one person may be too complex for another. The same colour can be clearly visible for one person but blend into the background for someone else. The colour pink is distinguishable for some, but it can look like a shade of blue for a person with protanopia. And a menu that’s easily navigable for one user may be a frustrating experience for the next. Some people can click linked text without a second thought, but users with fine motor difficulties often need a larger target. 

Image removed.

Someone with colour blindness sees colours differently to other people. They may not be able to see green, red, blue, or (rarely) any colour.

The issue of conflicting accessibility needs means it’s impossible to build a one-size-fits-all platform. Unfortunately, what often ends up happening is organizations focus on a select few disabilities and neglect the rest. This isn’t true accessibility and it further marginalizes certain groups of people. 

“What I need is for someone to listen to my challenges and consider my unique situation. Organizations must be open to understanding the social, economic, and environmental factors that people who live with a disability face every day.”

– Katy*, who lives with a disability. 

*Name has been changed to protect the person’s privacy. 

Providing Customization to Meet Diverse Accessibility Needs

If one size can’t fit all, how can a single platform meet the varied needs of users with disabilities? The answer is customization – allowing users to select options for how digital information is displayed, organized and communicated to them. 

For example, you could give users the option to:

  • Adjust the brightness or colours to something they can see better
  • Change the font style to something they can read more easily 
  • Turn on captions so they don’t have to rely on audio, or turn off captions to reduce visual distractions 

Customization empowers users with disabilities because it gives them control over their digital experience. After all, who better to decide what each individual user needs and prefers than the user themself?

Image removed.

Video captions are often useful for people who can’t hear the voiceover. But they may be distracting for other users, such as those with autism spectrum disorder. Credit: W3C.

Using WAI-Adapt to Let Users Shape Their Experience 

The Web Accessibility Initiative (WAI) develops standards and support materials to help people understand and implement accessibility. Its WAI-Adapt series of technical specifications enables content authors to provide customization with minimal work. Authors can add extra semantic information using a collection of new attributes and values, usually with taxonomies. 

You can use WAI-Adapt to provide better support to users who require:

  • Familiar and consistent symbols, iconography, or graphics
  • On-demand help, tooltips, or clues
  • Language that’s easier for them to understand
  • The ability to limit or hide features
  • Clearer distinctions between native and third-party content
  • Custom keyboard shortcuts

Tailoring Your Platform for Assistive Technologies

People with disabilities may customize their digital experiences by using assistive technology. Your platform needs to work hand-in-hand with these technologies to ensure accessibility. 

The WAI Accessible Rich Internet Application (ARIA) is a technical specification that allows you to specify how assistive technology should treat certain HTML elements. For example, you can use it to tell screen readers how to prioritize updates to live regions. 

Image removed.

Screen readers convert information on a screen into speech or braille for people with a visual impairment. Credit: Photo by Sigmund on Unsplash.

An easy way for non-technical people to quickly build and update accessible web pages is to use Acquia Site Studio. It includes built-in ARIA support for menus, buttons, sliders, accordions, and modals. Technical team members can also add additional syntax to elements in the Markup tab within Site Studio to support the latest standards.

Expand Your Web Accessibility Expertise

Our Drupal Web Accessibility training course guides you through accessibility fundamentals and common issues. You’ll get hands-on experience of testing and troubleshooting to meet accessibility standards. And you’ll come away with a deeper understanding of topics mentioned in this article, including WAI-ARIA.

//--> //-->

+ more awesome articles by Evolving Web

Matt Glaman: Using the new add_suggestion Twig filter in Drupal 10

When building my wife's web store, I used a new feature in Drupal 10 when templating her product display pages. Drupal 10 introduced a new Twig filter called add_suggestion. Drupal's render array output is templated through Twig and provides a base template name and more refined alternatives for controlled templating. Here's a list of template suggestions for outputting an image field from a product entity, from the most generic to the most specific.

Specbee: Taming JavaScript in Drupal (Includes FAQs)

Taming JavaScript in Drupal (Includes FAQs) Sagar Chauhan 07 Feb, 2023 Subscribe to our Newsletter Now Subscribe Leave this field blank

Interactive web experiences provide a more engaging and enjoyable experience for users. It leads to increased user satisfaction and a positive perception of a website. For example, a form that provides instant feedback and validation, rather than making the user wait for a page refresh, can significantly improve the user experience.

JavaScript plays an important role in Drupal by providing the means to create dynamic and interactive experiences for users on the frontend of a Drupal website. It enables developers to modify the behavior of certain elements on a page, such as forms, links, or any other DOM elements, without having to refresh the entire page. Drupal Behaviors are JavaScript functions that get executed when specific events occur on a page. Behaviors make it easy for developers to maintain and upgrade a site as they don’t need to change any underlying HTML code. Find out all you wanted to know about Drupal Behaviors in the article.

Image removed.

What are Drupal Behaviors?

Drupal.behaviors is an object inside the Javascript structure in Drupal, which allows us to attach functions to be executed at certain times during the execution of the application. It is called when the DOM is fully loaded, but these behaviors can be called again. Drupal’s official JavaScript documentation suggests that modules should implement JavaScript by attaching logic to Drupal.behaviors.

Why do we need Drupal behaviors?

The advantage of Behaviors is that they are automatically re-applied to any content that is loaded through AJAX. They can be called at any time with a context that represents new additions or changes to the DOM. This is better than $(document).ready() or document DOMContentLoaded where the code is just run once.

When are Drupal behaviors unwanted?

Drupal behaviors are not always the perfect solution for writing Javascript in Drupal. In some cases, as stated below Drupal behaviors are not needed at all!

  • When we need to execute some code that does not affect the DOM. Eg. Initializing an external script like Google Analytics
  • When some JS operation needs to be performed on the DOM just once knowing that the element will be available when the page loads (This scenario is different from using Once).

When are Drupal Behaviors called?

  • After an administration overlay has been loaded into the page.
  • After the AJAX Form API has submitted a form.
  • When an AJAX request returns a command that modifies the HTML, such as ajax_command_replace().

Other times when Drupal Behaviors are invoked

  • CTools calls it after a modal has been loaded.
  • Media calls it after the media browser has been loaded.
  • Panels calls it after in-place editing has been completed.
  • Views calls it after loading a new page that uses AJAX.
  • Views Load More calls it after loading the next chunk of items.
  • JavaScript from custom modules may call Drupal.attachBehaviors() when they add or change parts of the page.

Writing code without Drupal behaviors

In this code, we are adding a click event listener to the .views-row class which calculates the number of times we are clicking on this row. But it is added only once to the elements which come in the DOM during the initial page load. After clicking on Load More and loading more items, the click listener does not work on the newly loaded items.

// No Drupal Behaviors (function () { let header = document.querySelector(".food-list-header"); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = document.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); })(); Image removed.

How do we use Drupal Behaviors?

Answer: Using the attach method

Things to remember:

  • The new object needs to have at least an attach method. 
  • Anytime Drupal.attachBehaviors is called, it will iterate through all behavior objects and call their respective attach methods.

Adding Drupal behavior to our code

After adding Drupal Behaviors, the code looks something like this.

(function (Drupal) { Drupal.behaviors.exampleBehaviour1 = { attach: (context, settings) => { // Add a delicious text to the top of the document let header = document.querySelector(".food-list-header"); // jQuery Equivalent // $(".food-list-header"); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = document.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal);

 But something odd appears in the top when we click on Load More:

Image removed.

 

This is because Drupal behavior is called a lot of times and subsequently we get some unintended behavior.

What is Context in “Drupal context”?

  • When calling the attach method for all behaviors, Drupal passes along a context parameter. 
  • The context parameter that is passed can often give a better idea of what DOM element is being processed.
  • During the initial page load this will be the complete HTML Document; during subsequent calls, this will be just the elements that are being added to the page or get modified.

How to add Context?

The previous problem can be solved by using the context parameter that is provided by Drupal Behaviors. In this case, the first time the page loads, we get the whole HTML Document as context and that’s when we attach the header. For further operations, it will be the part of the code which is affected by Drupal Behaviors and hence that part of the code is safely controlled.

(function (Drupal) { Drupal.behaviors.exampleBehaviour2 = { attach: (context, settings) => { // Add a delicious text to the top of the document. // The context parameter now can be used for adding // certain functionality which removes unwanted repeatability let header = context.querySelector(".food-list-header"); // jQuery Equivalent // $(".food-list-header", context); if (header) { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } // Add the event listener for each click on the food let foods = context.querySelectorAll(".views-row"); foods.forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal);

Again there is some odd behavior when we click on Load More. The food items which were initially loaded work fine. But After clicking on Load More, the new items get the click listener and work normally. But the initially loaded items get the listener attached again and clicking on them calls the click event more than once!

Image removed.

 

When do Drupal Behaviors start misbehaving?

  • Writing all the event listeners inside Drupal behaviors without using Once and Context.
  • Declaring unwanted functions inside Drupal behaviors which leads to the redeclaration of functions every time the attach method is called.

“Once” to the rescue

  • Once ensures that something is processed only once by adding a data-once attribute in a DOM element after the code has been executed.
  • If the behavior is called again, the element with the data-once attribute is skipped for further execution.
  • Once is a modern implementation of jQuery.once (which is an endeavor to move away from jQuery)
  • Once, in combination with context, controls the entire functionality perfectly as we need it.

Adding Once to fix the event listeners in our code

(function (Drupal, once) { Drupal.behaviors.exampleBehaviour3 = { attach: (context, settings) => { once("food-header-initialized", ".food-list-header", context).forEach( (header) => { let greatFoodSpan = document.createElement("span"); greatFoodSpan.textContent = "Get ready for great food!!!!!!"; header.append(greatFoodSpan); } ); // jQuery Equivalent // $(".food-list-header", context).once("food-header-initialized", function (header) { // // }); // Add the event listener for each click on the food once("food-initialized", ".views-row", context).forEach((food) => { food.addEventListener("click", () => { let foodCounter = food.querySelector(".food-click-counter"); let timesClicked = parseInt(foodCounter.textContent.trim()); foodCounter.textContent = ++timesClicked; }); }); }, }; })(Drupal, once); Image removed.

 

Now everything works as intended. We get a data-once attribute to the elements where the event listeners are attached and newly loaded elements and previously loaded elements function properly.

The Need for Detach method

The Detach method acts like an anti-hero (not evil), removing whatever we did in the attach method. Any code in the detach method will be called whenever content is removed from the DOM. This helps us to clean up our application. For example, Detach method enables us to remove unwanted event listeners which consume resources like a continuous polling situation.

Examples of Detach

Assume that we have an ajax form to fill and we are using a timer to show the time elapsed. We use setTimeOut to manage the timer. We log this timer in the console for monitoring.

(function (Drupal, once) { let counter = 0; Drupal.behaviors.exampleBehaviour4 = { attach: (context, settings) => { once("timer-initalized", ".contact-timer", context).forEach((ele) => { const timer = context.querySelector(".contact-timer-sec"); timer.textContent = counter; // Set the timer for user to see the time elapsed setInterval(() => { console.log("This is logging"); const timer = document.querySelector(".contact-timer-sec"); timer.textContent = ++counter; }, 1000); }); }, }; })(Drupal, once); Image removed.

 

On form submission, the timer on DOM gets removed but the console starts throwing an error. This is because the element on which the setTimeOut is acting has been removed from DOM:

Image removed.

 

To avoid this we can use the detach method like this:

(function (Drupal, once) { let counter = 0; let intervalStopper; Drupal.behaviors.exampleBehaviour4 = { attach: (context, settings) => { // Set the timer for user to see the time elapsed once("timer-initialized", ".contact-timer", context).forEach((ele) => { const timer = context.querySelector(".contact-timer-sec"); timer.textContent = counter; intervalStopper = setInterval(() => { const timer = document.querySelector(".contact-timer-sec"); timer.textContent = ++counter; console.log("This is logging"); }, 1000); }); }, // Clear the timer on confirmation detach: (context, settings, trigger) => { const timer = context.querySelector(".contact-timer-sec"); if (trigger == "unload" && timer) { clearInterval(intervalStopper); } }, }; })(Drupal, once);

This removes the timer on unload and as seen from the logger, the error does not occur.

Image removed.

Immediately Invoked Function Expressions (IIFE) - The wrapper for JS

We have been using IIFE to write our Drupal code. The initial opening parentheses define an anonymous function which helps prevent the function's scope from polluting the global scope of the entire application. You can pass arguments to your anonymous function by including them as arguments at the end of the function definition. 

This also helps us to namespace the parameters however we want them to be used.

Example:

// Function name crisis!!!! // The function is vulnearble to // be replaced by some other function function someFunction() { // Some code for this function } (function (Drupal) { // Function name crisis averted! function someFunction() { // Some code for this other function } Drupal.behaviors.exampleBehaviour6 = { attach: (context, settings) => { someFunction(); }, }; })(Drupal);

Final Thoughts

Implementing Drupal behaviors allows for dynamic interactivity, streamlined user interaction, improved user feedback, efficient development and overall enhanced user experience of your website. Drupal.behaviors are flexible and modular, in that they can be executed multiple times on a page, can override and extend existing behavior, and can be automatically re-applied to any content loaded through Ajax. 

Looking for a Drupal development agency to help you build interactive web experiences, making the best out of Drupal? We’d love to talk!

Author: Sagar Chauhan


Meet Sagar Chauhan, Lead Engineer, Acquia-certified Frontend Developer, soccer player, and a huge Arsenal fan. Sagar loves long train journeys and checking out latest gadget reviews. If you want to invite him for a meal (and you don’t know how to cook), Maggi would be perfect! :)

Email Address Subscribe Leave this field blank Drupal Drupal Development Drupal Planet CSS/JS

Leave us a Comment

 

Recent Blogs

Image Image removed.

Taming JavaScript in Drupal (Includes FAQs)

Image Image removed.

From Aspirations to Accomplishments - Malabya Tewari's Career Story

Image Image removed.

How to Create a Custom Module and add CSS Libraries in Drupal 9

Want to extract the maximum out of Drupal? TALK TO US

Featured Success Stories

Image removed.

A Drupal powered multi-site, multi-lingual platform to enable a unified user experience at SEMI.

Image removed.

Discover how our technology enabled UX Magazine to cater to their massive audience and launch outreach programs.

Image removed.

Discover how a Drupal powered internal portal encouraged the sellers at Flipkart to obtain the latest insights with respect to a particular domain.

VIEW ALL CASE STUDIES

Web Wash: Customize View Fields using Twig in Drupal

Views is a powerful module that allows you to create all sorts of components. It can be used to create something simple such as a list of articles, or complex such as a carousel or even an embedded map.

The Views UI can be intimidating if you’re new to Drupal, but as you use the module, you’ll find bits of functionality hidden deep in the interface.

One feature I want to discuss, which may not be evident at first, is the ability to add Twig code into view a fields.

Adding Twig code into a field allows you to change a field’s output dynamically. Which can be helpful under certain circumstances.

To add Twig code or some HTML into a field, click on the field, expand “Rewrite results”, check “Override the output of this field with custom text” and add your code into the text area.