7. View State

To maintain the state of the scroll position of an HTML element, the zoom position of a chart, or any state that is specific to the view when the widget needs to be redrawn, we can use the view state. This state is accessible when the widget is rendered on a template but is destroyed when the widget is no longer rendered. We will discuss this in more detail in later chapters. For now, let's extend our previous "Message" widget to include the ability to collapse and expand.

Extending the Message Widget

  1. Copy and paste the following script:

<?
	register event @ToggleCollapseState
	@Collapsed := @Collapsed ? false
?>
<div class="message <?attr @Style ?> <?attr if @Collapsed then "collapsed" else "expanded" ?>" onclick="<?attr @ToggleCollapseState ?>">
	<span class="box ellipses">
		<span class="glyphicon glyphicon-comment"></span> 
		...
	</span>
	<span class="box text">
		<span class="glyphicon glyphicon-heart-empty"></span>
		<?= @Text ?>
	</span>
</div>

Notice that we are registering an event again using register event @ToggleCollapseState. We will create an event later that will change the view state. In the second line, you will notice the @Collapsed variable. This is a view state variable (also called a view state field). We assign the @Collapsed variable to its original value, but when it is unknownboolean, we assign it the value false. This ensures that the toggle behavior functions correctly. More on that in the event we will create shortly.

Creating the View State Field

To create the view state field:

  1. Click the "View state" tab.

  2. Click on "New field" in the toolbar.

  3. Name it "Collapsed."

  4. Select "Boolean" as the type.

Creating the Toggle Event

Now let's create the event:

  1. Create the "ToggleCollapseState" event.

  2. Copy and paste the following event code:

@Collapsed := not @Collapsed

Notice that if we did not assign @Collapsed to false when it was unknownboolean, this event would not work, because assigning a variable with not unknownboolean still results in unknownboolean.

Updating the Less Style

The Less style of the widget has also been updated. Replace the existing style with the following:

.message {
	display: flex;

	> .box {
		border: 1px solid transparent;
		border-radius: 4px;
		cursor: pointer;
	}
	
	&.danger > .box {
		background: lighten(@brand-danger, 25%);
		border-color: lighten(@brand-danger, 10%);
		color: darken(@brand-danger, 23%);
	}

	&.info > .box {
		background: lighten(@brand-info, 25%);
		border-color: lighten(@brand-info, 10%);
		color: darken(@brand-info, 23%);
	}

	&.success > .box {
		background: lighten(@brand-success, 25%);
		border-color: lighten(@brand-success, 10%);
		color: darken(@brand-success, 23%);
	}

	&.collapsed > .box {
		padding: 5px;

		&.text {
			display: none;
		}
	}

	&.expanded > .box {
		padding: 15px;

		&.ellipses {
			display: none;
		}
	}
}

Now, preview the widget, and you will see that it is clickable and toggles between an expanded and a collapsed state. Notice that if you refresh the page, the view state still exists. Maintaining the view state is essential for creating a good user experience (UX).

These are just the basics of view state. For instance, you can also manage view state via JavaScript, which we will explore in more detail in later chapters.

Last updated