Dynamic Widget Communication

In modern web development, ensuring that widgets communicate smoothly and update dynamically based on user actions is crucial. I achieved this in the ABP.IO Widgets by leveraging an event-driven approach, allowing widgets to interact seamlessly without the need for complex dependencies.

The Core Idea

Rather than having widgets tightly coupled—where one directly manipulates another—you can have them emit and listen for events. This approach keeps your code clean and your widgets reusable.

For example:

  1. Categories Widget: Displays categories and triggers an event when a category is selected.
  2. Courses Widget: Listens for the category selection event and refreshes the course list accordingly.
  3. Courses Number Widget: Updates the course count based on the refreshed list.

widgets-communication

Quick Implementation

Here's a brief overview of how it works:

  • Categories Widget triggers a category-selected event:
(function ($) {
    abp.widgets.Categories = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name="Categories"]',
            filterCallback: function () {
                return {
                    // returned values here
                };
            }
        });

        async function init() {
            // ...
            // Emit that the category selected
            $(".category-tab").off('click').on('click', function () {
                var categoryName = $(this).attr('category-name');
                $(document).trigger('category-selected', { category: categoryName });
            });
        }

        return {
            init: init,
        };
    };
    
})(jQuery);
  • Courses Widget listens for this event and updates the courses:
(function ($) {
    let category = 'All'; // initial category
    abp.widgets.Courses = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name="Courses"]',
            filterCallback: function () {
                return {
                    category: category
                };
            }
        });

        async function init() {
            //...
            $(document).trigger('courses-updated', { courses: filteredCourses });
        }

        function refreshCourses(_category) {
            category = _category;
            widgetManager.refresh();
        }
       
        return {
            init: init,
            refreshCourses: refreshCourses
        };
    }

})(jQuery);
  • Courses Number Widget listens for the courses-updated event to update the course count:
(function ($) {
    let number = 0;
    abp.widgets.CoursesNumber = function ($widget) {
        var widgetManager = new abp.WidgetManager({
            wrapper: '.abp-widget-wrapper[data-widget-name="CoursesNumber"]',
            filterCallback: function () {
                return {
                    number: number
                };
            }
        });
        async function init() {
            $('#number').text(number);
        }
        async function refreshCoursesNumber($number) {
            number = $number;
            widgetManager.refresh();
        }
        return {
            init: init,
            refreshCoursesNumber: refreshCoursesNumber
        };
    };
})(jQuery);

To link the widgets and ensure they refresh based on emitted events, you can hard-code this on the page containing the widgets or use the script field if you’re working within the ABP CMS Kit pages feature.

widgets-communication-script

This setup makes your widgets flexible and easy to manage. Place them anywhere on the page, and they’ll work together effortlessly.

By using event-driven communication, you simplify your development process and make your application more scalable and easier to maintain. Try it in your next project!

Happy coding 😁❤️

Achim Ismaili 2 weeks ago

Hello Suhaib, thank you for documenting this elegant way of solving the communication between the widgets.

I can't see the two images you were trying to insert in your post. Are they only available for PRO-ABP-Users?

Also, I am asking myself, why there is (jQuery) mentioned at the end of each function. Are these widgets running with jQuery? Is the whole Abp-CMS-Kit based on jQuery logic?

Kind Regards, Achim

ps. I am new to abp and I don't have a PRO license, so I am sorry if I am asking stupid questions.

Suhaib Mousa 2 weeks ago

Hello Achim,

Welcome to the ABP community! 😁❤️ I hope you have an amazing experience exploring the rich features and modules of ABP.IO.

The issue with the images isn't related to licensing; it’s just a technical glitch that I hope gets fixed soon. You can view the post with the images here.

To address your question about jQuery: The ABP CMS Kit does support jQuery, but it’s not entirely built on it. In my example, I used jQuery to handle some client-side interactions within the widgets. This is why you see jQuery mentioned in the functions.

The script field in the CMS Kit’s pages feature is rendered in the script section after global scripts like jQuery, this allows the widgets to utilize jQuery if needed, but it’s not a requirement. The CMS Kit is designed to be flexible, so you can use other approaches if you prefer.

You can see the full code in the ABP repository.

Kind Regards

Suhaib Mousa 2 weeks ago

You can find additional details on using JavaScript with widgets in the ABP documentation here: Widgets Documentation.