# Frontend components Frontend components are JavaScript modules that can be required directly through the HTML markup of your view, to provide additional functionality for the user. Although its best practice to make all features available without JavaScript, these components can be used to provide a richer and more comfortable user experience in case JavaScript is available. There is a certain set of frontend components which come directly with the Icinga2-Web core application, but it is also possible to define new components directly in Icinga2-Web modules. ## How do components work? Components are defined in JavaScript files that provide a set of functionality that will be added to the targeted HTML node. Icinga2-Web uses [RequireJS](http://requirejs.org) to load all frontend components, so each frontend component is in fact [defined exactly like a RequireJS-Module](http://requirejs.org/docs/api.html#define) . The important difference to plain RequireJS is, that the loading and execution of these components is done automatically through the HTML markup. The attribute *data-icinga-component* in a DIV element will indicate that this element is a container for a frontend component and will trigger the component loader to create a component instance for this HTML node. The component loader keeps track of all available components and makes it possible to retrieve this instance when needed. ### Component names A component name consists of two parts: the namespace and the name of the component itself. The component is named exactly like its JavaScript file, while the namespace is the name of the Icinga2-Web module that contains the component. Each Icinga2-Web module can contain its own components in the folder *public/js*. / NOTE: The namespace used for modules defined in the Icinga2-Web core application is "app". In opposition to the modules the core application keeps its modules located in *public/js/icinga/components* instead of *public/js*. #### Example Names The full name for the component *modules/monitoring/public/js/someComponent.js* in the module "monitoring" would be: "monitoring/someComponent" The full component name for the component *public/js/icinga/components/datetime.js* in the Icinga2-Web core application would: "app/datetime" ## Creating a component As described in the chapters above, components are defined exactly like RequireJS modules, but with the additional requirement that they must always return a class constructor. The component below will search all date pickers, set the time format and create a JavaScript date picker when there is no native one available. /** * Ensures that our date/time controls will work on every browser (natively or javascript based) */ define(['jquery', 'datetimepicker'], function($) { "use strict"; var DateTimePicker = function(target) { $(target).find('.datetime input') .attr('data-format', 'yyyy-MM-dd hh:mm:ss'); $(target).find('.datetime') .addClass('input-append') .append('' + '') .datetimepicker(); }; return DateTimePicker; }); ## Loading a component The following code will load the module *datetime*, which will ensure that there is always a datetime-picker with right time-format available.
### Component ids When an ID is assigned to the HTML element, it will be used by the component loader to reference this component. Otherwise an ID in the form "icinga-component-<ID>" will be created and the ID attribute in the HTML Element will be updated accordingly. ### Component "target" The div-element with the *data-icinga-component* will be used as the "target" for the loaded component, which means that the component will perform its actions on this HTML node. # Retrieving a component Sometimes it can be necessary to retrieve the instances of the components itself, for example when they implement additional functions that can be called. The component loader is available in the Icinga object and can be used to retrieve component instances using their ID or their full component name. ## By component id var component = Icinga.components.getById("component-id"); component.doSomething(); ## By full component name var components = Icinga.components.getByType("app/datetime"); // ... do something with every component of the type app/datetime ## All components var components = Icinga.components.getComponents(); // ... do something with every component