Imagine a use case where you want to develop a custom Multi Select component with checkboxes, animations and buttons to perform certain actions. Doesn’t it sound interesting to have a component aesthetics design meet your level of imagination. But of-course developing your thoughts into code is much more difficult and hence many developers end up using some predefined library package (which are plenty). Only if there was a simpler way to do this UX designers would love to explore such an opportunity where they can meet their design expectations.

Component based architecture has been around for ages since this could be done using our classic jQuery or vanilla JS but what changed today to encourage developers to create full-fledged applications using component-based design patterns in my short-term UI development experience my answer to this is state management. Apart from writing a lot of code to develop an element, state management is a hurdle which is difficult and cumbersome to cross as our application grows and which is also one of the main reasons why modern frameworks like React, Angular, Vue and a lot more exist. But at the core these state management systems can be developed using our old JS as well and in the present day many third-party libraries exist to help us with the same. So, the question becomes, is it worth investing your time in crossing these hurdles to develop a mini framework of your own or use existing frameworks and get on with our imaginary Multi Select component.

Development in React:

Developing components in any modern framework becomes feasible as state management is taken care of by libraries like redux, mobx and now hooks and along with that we get the facility of callback functions and props to pass data from parent to child components.

In the Multi Select component we developed, the requirement was to have an Apply and Clear button integrated into each dropdown and also the function of Clear button was to clear all the selected choices and Apply button was to render the chart after selecting any checkbox. Also, whenever we work with multi select dropdowns it is helpful for the user to know how many choices they have selected from the dropdown list.

From the discussion it seems complicated since we have to convert a simple list to multi select options. To solve this problem statement, we started with all the properties required to build the component. Firstly, we need a button to toggle the options list and an arrow button at the end which should bind to the event which toggles the options view. Secondly, we need a list which consists of a checkbox input and the option label (Note: Remember to keep the list-style-type: none). Thirdly, we need two buttons, one to capture the changes made in the list and the second to clear all the selected choices. Lastly, we need to capture checkbox changes and change the placeholder with the number of options selected from the list. The states which we used to create this component are:

Options: Array of list to be displayed as options

Placeholder: String variable to be displayed at button name

Visibility: String variable to change the visibility of the options div on button click

And that’s it.

Using only three states we created the component for our specific requirement and rest all are the event listeners bound to user interaction. And the flexibility to have callback functions which can trigger and function call in the parent component makes the use of this component even more interesting. Another interesting task was to hide other tags when we toggle the button to view options and this was made possible because we could call a function in parent component on button click which in turn could change the visibility of the other tags. We also used a callback function to update the parent state with the options selected in the Multi Select component.

The data format we used to render the options list was like {content: “Education”, selected: false}. In this the content was treated as the dropdown label and on checkbox change the value of selected changed which helped us to count the number of selected checkboxes.

With enough functionalities a developer could package such a component and use it as a packaged module in other projects as well.

function clearOption() {
        let newArr = [...option]
        newArr.forEach((item, index) =>
            newArr[index] = {content:item.content, selected:false}
        )
        setOption(newArr);
        var checkboxes = document.getElementsByClassName('test')
        for(var i=0, n=checkboxes.length;i<n;i++) {
            checkboxes[i].checked = false;
        }
        setVisibility();
    }

----------------------------------------------------------------------------------------
function applyFilter() {
        props.applyFilter(option
            .filter(function(obj) {
              return obj.selected === true;
            })
            .map(function(obj) {
              return obj.content;
            }))
    }

Development in Web Component:

Web components are the solution for integration problems with all the modern frameworks since it is built by overriding the HtmlElement class responsible for rendering all the html elements which gives us the ability to create custom html tags that can be integrated with any framework. That said, following the development principles in the web component we can add event listeners using connectedCallback(), create attributes and even integrate outside elements using <spot>. The learning curve in web components is not acute since there are only a handful of concepts to get familiar with.

We created a chart configuration to render graphs into a react application using FusionCharts in the web component. Essential functions in a web component are:

connectedCallback(): called whenever component is attached to dom

observedAttributes() : return the array of attributes to be observed for any changes

attributedChangedCallback(): triggered on attribute change, where old value is replace with new value

Apart from this, we can create functions for different requirements or code modularity and use attribute values using getters and setters.

 static get observedAttributes() {
        return ['width', 'height', 'filter'];
    }

Once the above structure is in place we can start adding the configuration in a template and wrap it like window.customElements.define(‘sfn-rc-graph’, SFNRCGraph); Now we are ready to use this component in our front end framework like <sfn-rc-graph/>. Looks awesome right! Then what is limiting the use of such a versatile API library to be used in every major UI project, the answer to this lies in interconnection. Web components are great when we need a standalone component that does not change or react upon the user interactivity with other components. But for our specific requirement we need the parent state of the Multi Select component to be changed based on the selection.

Attribute states in a web component can be managed efficiently by writing a custom library (https://css-tricks.com/build-a-state-management-system-with-vanilla-javascript/) or using third party packages since the payload of a web component is usually controlled.

Development in JavaScript:

Originating language of innumerable frameworks and libraries that are used not only in front-end development but backend as well. Anything that can be developed using any modern framework is still possible with vanilla JS as well and as long as the payload of the code is less it is preferable to stick with javascript since this avoids all the overhead required to execute the code in any other framework that’s built on top of it. But as the code grows modularity, code duplication, state management and size becomes some key issues which pushes developers to move towards pre-built frameworks.

Developing any element and listeners on top of it is quite easy with vanillaJS as long as the size of the payload is small. As the size of the state grows it becomes more and more difficult to watch the state of each variable and more often than not we end up duplicating a ton of modules just for the sake of feasibility. Developing a mini-framework using a Pub/Sub design pattern can be a good learning experience and can be used across every framework seamlessly.

For the requirements mentioned at the start of this article, if we wish to develop such a multi select component in javascript we would need to simply write a few additional map functions to render the list and keep updating the checkbox array. But if the requirements keep changing and we need to add some additional functionality on an event, we can save many lines of code using a framework whereas with additional states it will be difficult to keep the script in synchronization.