1 # BookStack JavaScript Code
3 BookStack is primarily server-side-rendered, but it uses JavaScript sparingly to drive any required dynamic elements. Most JavaScript is applied via a custom, and very thin, component interface to keep code organised and somewhat reusable.
5 JavaScript source code can be found in the `resources/js` directory. This gets bundled and transformed by `esbuild`, ending up in the `public/dist` folder for browser use. Read the [Development > "Building CSS & JavaScript Assets"](development.md#building-css-&-javascript-assets) documentation for details on this process.
9 This section details the format for JavaScript components in BookStack. This is a really simple class-based setup with a few helpers provided.
11 ### Defining a Component in JS
16 this.container = this.$el;
17 this.menu = this.$refs.menu;
18 this.toggles = this.$manyRefs.toggle;
20 this.speed = parseInt(this.$opts.speed);
25 All usage of $refs, $manyRefs and $opts should be done at the top of the `setup` function so any requirements can be easily seen.
27 Once defined, the component has to be registered for use. This is done in the `resources/js/components/index.js` file. You'll need to import the component class then add it to `componentMapping` object, following the pattern of other components.
29 ### Using a Component in HTML
31 A component is used like so:
34 <div component="dropdown"></div>
36 <!-- or, for multiple -->
38 <div components="dropdown image-picker"></div>
41 The names will be parsed and new component instance will be created if a matching name is found in the `components/index.js` componentMapping.
43 ### Element References
45 Within a component you'll often need to refer to other element instances. This can be done like so:
48 <div component="dropdown">
49 <span refs="dropdown@toggle othercomponent@handle">View more</span>
53 You can then access the span element as `this.$refs.toggle` in your component.
55 Multiple elements of the same reference name can be accessed via a `this.$manyRefs` property within your component. For example, all the buttons in the below example could be accessed via `this.$manyRefs.buttons`.
58 <div component="list">
59 <button refs="list@button">Click here</button>
60 <button refs="list@button">No, Click here</button>
61 <button refs="list@button">This button is better</button>
68 <div component="dropdown"
69 option:dropdown:delay="500"
74 Will result with `this.$opts` being:
83 #### Component Properties
85 A component has the below shown properties available for use. As mentioned above, most of these should be used within the `setup()` function to make the requirements/dependencies of the component clear.
88 // The root element that the compontent has been applied to.
91 // A map of defined element references within the compontent.
92 // See "Element References" above.
95 // A map of defined multi-element references within the compontent.
96 // See "Element References" above.
99 // Options defined for the compontent.
103 ## Global JavaScript Helpers
105 There are various global helper libraries in BookStack which can be accessed via the `window`. The below provides an overview of what's available.
109 window.$http.get(url, params);
110 window.$http.post(url, data);
111 window.$http.put(url, data);
112 window.$http.delete(url, data);
113 window.$http.patch(url, data);
115 // Global event system
116 // Emit a global event
117 window.$events.emit(eventName, eventData);
118 // Listen to a global event
119 window.$events.listen(eventName, callback);
120 // Show a success message
121 window.$events.success(message);
122 // Show an error message
123 window.$events.error(message);
124 // Show validation errors, if existing, as an error notification
125 window.$events.showValidationErrors(error);
128 // Take the given plural text and count to decide on what plural option
129 // to use, Similar to laravel's trans_choice function but instead
130 // takes the direction directly instead of a translation key.
131 window.trans_plural(translationString, count, replacements);
134 // Parse and initialise any components from the given root el down.
135 window.components.init(rootEl);
136 // Get the first active component of the given name
137 window.components.first(name);