Dynamic website content includes page elements that change as a result of visitor interaction. The purpose of an image slider, for example, is to let the visitor switch to the next or the previous image by clicking a button.
Dynamic website content includes page elements that change as a result of visitor interaction. The purpose of an image slider, for example, is to let the visitor switch to the next or the previous image by clicking a button.
In this tutorial, we will show you how to use event handlers in widgets. Based on the Scrivito Example App, we’re going to develop a disclosure widget that requires visitors to click a button to open a panel containing some details they didn’t want to see before, e.g., the solution to a riddle, or the end of a story or movie. Similar use cases would be, for example, displaying product details or shipping costs on the same page after clicking a link.
Our DisclosureWidget
will be equipped with a button for showing and hiding the information provided by an editor. Depending on its current state, this button should be labeled accordingly. Additionally, we want the information to be disclosed to have a heading and to be freely composable using widgets.
So let’s first create the widget model class to make the pieces of content (the attributes) we want to have for each actual DisclosureWidget
known to Scrivito. Next, we’ll configure how the widget and which of its attributes should show up in Scrivito’s user interface. After that, we’ll take care of rendering an actual disclosure widget. This is where a click event comes into play.
In a Scrivito-based app, every widget is represented by a folder in the “src/Widgets” folder of the app, so simply create a subfolder named DisclosureWidget
first, and add to it the files we are going to put together here.
Each actual DisclosureWidget
has a heading
and a body
(we wanted it to be a widgetlist
attribute), and button labels for the two states, labelHidden
and labelDisclosed
.
Now that we have the model, let’s figure out what needs to be configured for editors to use the widget. First, an editor should be enabled to recognize the widget when wanting to select one using the widget selection dialog. For this, we’re going to provide a title
, a short description
, and a thumbnail
attribute for it.
Second, regarding the attributes of a widget, some are predestined for being edited in place, while others should be made editable on the widget’s properties dialog. In general, all attributes that don’t require an editor to select something (e.g. a style or a color) and don’t respond to clicks (as opposed to buttons, tabs, and the like) can be conveniently edited in place, first of all string
, html
, and widgetlist
attributes.
Thus, in the case of our DisclosureWidget
, the button texts should not be made editable directly on the page because, as indicated, the click needed to focus the button for editing one of its texts would trigger the button’s click event. For this reason, we’re going to add the button texts to the widget’s properties dialog. Such details about editing attributes, as well as the widget’s appearance in the selection dialog, can be specified using Scrivito.provideEditingConfig
:
This is what the above configuration effects on the widget selection and properties dialogs:
For rendering DisclosureWidget
s based on the model class we provided above, we’ll pass a React component to Scrivito that implements the behavior and the appearance we want these widgets to have. The widget
instance to be rendered is passed directly to the React component as a function argument.
As you can see from the code below, the component is centered around a JavaScript onClick
event and its handler inside a <button>
element. The button’s text and whether the panel should be rendered or not depends on the component’s isDisclosed
state variable which is set to false
at the beginning using React’s useState hook. This causes the value of the labelHidden
attribute to be used as the button label, and the panel heading
and body
to not be rendered initially.
Clicking the button triggers the onClick
event handler. It toggles the component’s state through a call to the set
function of the isDisclosed
state variable, setIsDisclosed
.
If isDisclosed
is true, the widget’s heading
and body
attributes are finally rendered using the Scrivito.ContentTag
React component. The very last statement connects the DisclosureWidget
component class to Scrivito using Scrivito.provideComponent
to make it available in the user interface.
This is what the widget may look like after adding some content to it:
Just remember to implement widgets as React components, and to connect them to Scrivito. Regarding events, changing what a widget renders as a response to, for example, a button click, can easily be accomplished using React’s useState hook. For this, provide a state variable and an event handler, and use the set
function of this variable to change the component’s state and have its view updated.