Creating a page view counter
Introduction
In this first part we'll create a view that displays the number of times it has been shown. Those old enough to remember webpages from the late 90's know what we're talking about.
We will use the State context object to save and load values from disk on the server.
Note
The complete view can be downloaded from here, but you will still need to follow some of the setup steps for it to work.
Setup
- In SSF_Tutorials, create a new
User Area
called PageViewCounter. - Open Folder Views Tool and remove all the default
Widgets
andLink Icons
. - Create a new
Link Icon
and leave the default name as is (UnnamedLinkIcon_1).
In the File
attribute, select Create a new view in this user area..., change the name to PageViewCounter.Rwav and save the the changes in Folder Views Tool.
Open the newly created view for editing.
- Remove the default elements.
- Add a
Numeric
element with the name NumberOfPageViews. - Save the file.
In your browser, navigate to the new User Area and make sure the Numeric element displays correctly.
Note
You will see an error in the Numeric
element (< Invalid value >) since we haven't defined a value yet.
Adding the server-side code
In the view root object, on the Javascript tab, open up the ServerSideJS
editor and paste the following code. Make sure to save the view when done:
// We register two server-side functions and
// return them (to the server-side context)
return {
// All registered functions must be async and they all must
// declare 'args' and 'callInfo' as params.
getPageViews: async (args, callInfo) => {
// console.log's in server-side code can be seen by opening
// the Arrigo Log Viewer in Project Builder:
// * Select the 'Arrigo BMS' node
// * Open the Tools menu and select 'Arrigo - View logs'
// * Enter the number for 'arrigo-services-ssf' and press Enter
console.log("Getting page views");
// Just get the single value from the default state file for the path.
// These files live in Proj:\Arrigo\state
return await callInfo.context.state.get();
},
// 'getPageViews' can now be invoked from client-side code
setPageViews: async (args, callInfo) => {
// Set a single value in the default state file for the path.
// 'pageViews' is the named arg we passed from the client-side code,
// so therefor it can be found in the args object.
return await callInfo.context.state.set({data: args.pageViews});
}
// 'setPageViews' can now be invoked from client-side code
}
Tip
Read more about logging and server side output in Troubleshooting - Server side logs
Adding the client-side code
Open the OnOpen
editor for the root object and paste the following code. Make sure to save the view when done:
// The dot (.) before the server-side function name implicitly adds
// the current path (where the view resides).
//
// 'getPageViews' doesn't take any arguments but we're still required
// to pass an empty object ({})
this.view.call('.getPageViews', {}).then((result) => {
// Get the result (number) or default to 0 if the result was null/undefined.
let pageViews = result || 0;
// Increase the value by one
pageViews++;
// Set the new pageViews value to the Numeric
this.view.NumberOfPageViews.value(pageViews);
// Save the new value to the state file
this.view.call('.setPageViews', { pageViews }).then((result) => {
// console.log's in client-side code will appear in the
// dev-tools console of the browser
console.log("New page view value saved");
});
});
The result
Open your browser and navigate to the area. The first time your view loads it should look like this:
Reload the browser a couple of times and verify that the counter increases:
Quick review
In this part we registered two ServerSideFunctions which used the State object to set and get data from disk on the server. Since we didn't specify a file when using the State object the data was stored in the default file for the path:
Proj:\Arrigo\state\PageViewCounter.AreaFolderView.File.UnnamedLinkIcon_1.File.json
Ideas and improvements
In the next part you will learn how to get/set data in a specific file. Using this technique you could create counters in all areas (sharing a single file) and then create a view that displays a summary of which areas in your project that are most viewed/used.
Hint
You would need to store the counter for each area under separate keys (in the file) to achieve this. Read more about this in the State context object reference.