Show a Block During a Sale

Conditional rendering of a custom Block is a great use of the “dateRange” Element Proptype, which offers a built-in date range picker to the user in VOLT’s Site Designer. In this tutorial, you will learn to make a custom Block that only appears during the selected dates.

Showing a Block Only During a Sale

For sale banners and announcements on your VOLT Store, it might be nice to be able to have them only be shown during the sale. Thankfully Element makes this easy because of its superb developmental flexibility. In this tutorial, you will be making a “Date Range Banner” custom Block using Element.

  • The Block will only be shown to customers of the VOLT Store between the selected dates.
  • The Block’s banner will always be displayed in Site Designer, allowing you to preview the look of the VOLT Store during the sale, before the sale goes live.
  • The user of the Block in VOLT’s Site Designer will have a date range picker to select the dates.

What You Will Learn

In this tutorial, you will be making a sale banner that will only display in the VOLT Store during certain selected sale dates, but it will always appear in VOLT’s Site Designer.

You will learn how to conditionally display a custom Block using the “isRendering” prop. The “isRendering” prop allows you to display certain content conditionally based on whether the site is live in a VOLT Store or just being previewed in VOLT’s Site Designer. An undefined value for the “isRendering” prop indicates the Block is in VOLT’s Site Designer, but a true value indicates the Block is rendered by a live VOLT Store or a preview of a theme. This is useful when making a placeholder for content that will be loaded by the third-party script (such as ads or a form). The banner will have a message to the user in VOLT’s Site Designer letting them know whether the banner will be displayed, and during which dates.

This message will not be shown when viewing the live version of the Block, such as when using the Preview or Publish buttons inside VOLT’s Site Designer.

To keep configuration simple, you will only be working with the following Element Proptypes: 

What You Should Know

To complete the rest of this tutorial, you should be already familiar with creating a custom Block for the VOLT Store using Element.

For help learning how to make a custom Block, please refer to the article “Building An Element Page Tutorial” (15 min read) located in the Element Platform Documentation. Or, try the video playlist “Element Tutorial | VOLT Learning Center ”on YouTube (27 min total).

You will also require authorization from Volusion in order to develop custom Blocks before you can begin this tutorial. Please refer to the page in the Element Platform Documentation called “How To Get Approved To Develop Blocks.” 

This tutorial will show you how to build a custom Block that will only be shown if the current date is within the selected range of dates.

Using the Element CLI to Create a New Custom Block

Start by making a new custom Block with the Element Command Line Interface (CLI).

You should already be logged in to the Element CLI, but if you are not then enter the element login command into your terminal and log in using the username and password that you use with VOLT’s Site Designer:

element login

Once logged in, create a new custom Block in your terminal using the element new command from the Element CLI:

element new DateRangeBlock
cd DateRangeBlock
npm install

Next, you will need to create a Git repository in the directory for tracking your changes:

git init
git add -A
git commit -am "Initial Commit"

If you would like to backup the repository online, such as to GitHub, now is a good time.

Edit the /src/configs.js File for the Date Range Block

The first step is to set up the default configurations and establish the Element Proptypes you will be using.

In your preferred text editor or IDE (such as VS Code), please open up the /src/configs.js file in the DateRangeBlock directory.

Replace the entire text of that file with the following:

import { ElementPropTypes } from "@volusion/element-proptypes"

export const configSchema = {
dateRange: {
label: "Sale Dates (Start and End Dates)",
type: ElementPropTypes.dateRange,
},
text: {
label: "Text Content",
type: ElementPropTypes.string,
},
}

// Set up default configuration for the dateRange picker
const today = new Date() // start date
const nextWeek = new Date() // end date
nextWeek.setDate(nextWeek.getDate() + 7)

export const defaultConfig = {
dateRange: [today, nextWeek],
text: "50% Off All Sale Items",
}

This code establishes a “dateRange” Proptype to select the sale dates to display the Block during and a “string” Proptype 

These are the user-configurable props for use in the custom Date Range Block that will be editable by the user of VOLT’s Site Designer.

A screenshot of the date range picker that the user will have is available in the “dateRange” documentation in the Element Proptypes section of the Element Platform Documentation.

Explaining the “dateRange” Proptype Used in the Block

The values for the “dateRange Proptype can be configured using JavaScript Date objects, as is shown above and in the Element Platform Documentation. 

However, when the user picks a date in VOLT’s Site Designer, the Date will be stored in the props as an “ISO string” (ISO 8601format), such as:

"2020-06-05T04:00:00.000Z"

This ISO string can be used to build a JavaScript Date by calling the Date() constructor with this timestamp string as its parameter.

For more information, please refer to the MDN Docs for the Date() constructor. 

This article does not cover handling timezones, so this Date Range Block is best suited for sales that start and end at approximate times, not exact times. 

Edit the /src/getStyles.js File for the Date Range

Open up the custom Block’s /src/getStyles.js file in your IDE or text editor.

Replace that file’s contents with the code:

export const getStyles = (blockConfig) => ({
bannerWrapper: {
backgroundColor: "#EEEEEE",
border: "1px solid black",
},
bannerIsLiveText: {
color: "rgba(238,174,202,1)",
fontStyle: "italic",
fontWeight: "bold",
},
bannerIsLiveDateRange: {
fontWeight: "normal",
},
bannerText: {
fontSize: "2rem",
},
})

In this file, you create some basic CSS styles to apply to the Date Range custom Block:

  • The “bannerWrapper” will have a gray background and 1 pixel solid black border.
  • The conditionally-displayed “bannerIsLiveText” will be pink, bold, and italicized.
  • The date range displayed in that conditional text will not be italicized.
  • The text for the sale banner itself will be 2rem.

In Element, custom CSS styles are handled by the “CSS-in-JS” (or “JSS”) package Aphrodite. For more information on customizing styles using Aphrodite in Element, please see the Element Platform Documentation’s article How To Style a Block With Aphrodite.

Note that the JSS class names are in camelCase and not hyphenated like CSS class names.

Edit the /src/GetDataProps.js File for the Date Range Block

It is time to open the Block’s /src/getDataProps.js file in your text editor or IDE.

Replace that code with the following:

export const getDataProps = (utils, props) => {
const { isRendering } = utils
return Promise.resolve({ isRendering })
}

This passes the “isRendering” prop as data into the Block, so that the Block can access it.

Specifically, this code will make the “isRendering” prop available as props.data.isRendering in the /src/Block.js file.

For details, please refer to the section ‘isRendering’ Availability in the Element Platform Documentation.

Edit the /src/Block.js file for the Date Range Block

Next, open up the custom Block’s /src/Block.js file in your text editor or IDE.

Replace the entire code of that file with the following:

import React from "react"
import { css, StyleSheet } from "aphrodite/no-important"
import { getStyles } from "./getStyles"
import { defaultConfig } from "./configs"

const Block = (props) => {
// Destructure the helper functions from the props
const { data, joinClasses } = props
// isRendering gets passed to the Block through /src/getDataProps.js
const { isRendering } = data
// isRendering is true in a live VOLT Store or a store's preview, and
// it is undefined in VOLT's Site Designer or when developing locally

// Get the CSS styles from Aphrodite
const classes = StyleSheet.create(getStyles(props))

// Destructure the Element props
const { dateRange, text } = props
// Destructure the dateRange array
const [startDateProp, endDateProp] = dateRang
// The dates in VOLT's Site Designer are stored as ISO strings
// e.g. "2019-10-05T14:58:00.000Z" so make them into Date objects:
const startDate = new Date(startDateProp)
const endDate = new Date(endDateProp)
// Fetch the current date and time
const currentDate = new Date()

// Set a boolean to display the banner only during the selected dates
const bannerIsLive = currentDate > startDate && currentDate < endDate
return (
<React.Fragment>
{(bannerIsLive || !isRendering) && (
<div className={joinClasses("pa3", css(classes.bannerWrapper))}>
{!isRendering && (
<div className={joinClasses("pb1", css(classes.bannerIsLiveText))}>
The sale banner is {bannerIsLive && "live"}
{!bannerIsLive && "not live"}
{". "}
<span className={css(classes.bannerIsLiveDateRange)}>
It will be displayed from {startDate.toDateString()} to{" "}
{endDate.toDateString()}.
</span>
</div>
)}
<div className={css(classes.bannerText)}>{text}</div>
</div>
)}
</React.Fragment>
)
}

Block.defaultProps = defaultConfig
export default Block

The Date Range Block uses the short-circuit operator, the logical AND (&&) operator, to only display the banner if the current date is between the start and end dates.

The dates are compared using the Date prototypes relational operators, less than (<) and greater than (>), which compare the Dates as numeric values based on their timestamps.

This same conditional logic is used to display a message to local users stating whether or not the sale banner is live.

This is achieved using the logical NOT (!) operator to only show the block when isRendering is falsy. When developing locally we expect that isRendering should have an undefined value.

This code also uses Element’s joinClasses() helper function (retrieved from props.joinClasses) in order to combine Aphrodite custom styles with Element’s built-in Atomic CSS classes. 

The Date Range Block uses the “pa3” and “pb1” CSS classes from the Atomic CSS spacing.css file. This improves the spacing of the Block by setting the padding CSS attributes to 1rem and 0.25rem, respectively.

Start the Local Server to View the Date Range

Now it is time to examine the custom Block. You should launch your local development environment by entering the npm run start (npm start) terminal command:

npm run start

This will open a new window in your local browser to http://localhost:4000/ in order to try out your new custom Block.

After previewing the Block, it is time to manually test the behavior of the Block.

You will be adding some local props to make sure that everything works correctly.

Test Out Local Prop Data in /local/index.js

To check that props set by the user will successfully change the behavior of the custom Block, you can set up local environment props by editing in the /local/index.js file. This will let you test the Block locally, observing the effect on the Block when you edit its props.

In your IDE or text editor, open the file /local/index.js, and replace both the lines const localEnvPropOverrides = { … } and const dataUtils = { isRendering: true,} with the following code:

// Set up local configuration for the dateRange picker
const yesterday = new Date() // start date
const nextWeek = new Date() // end date
yesterday.setDate(yesterday.getDate() - 1)
nextWeek.setDate(nextWeek.getDate() + 7)
const localEnvPropOverrides = {
// text: "Custom prop value for local testing",
dateRange: [yesterday, nextWeek],
}

/* Alternative configuration starting tomorrow:
const tomorrow = new Date() // start date
const nextWeek = new Date() // end date
tomorrow.setDate(nextWeek.getDate() + 1)
nextWeek.setDate(nextWeek.getDate() + 7)
const localEnvPropOverrides = {
text: "Custom prop value for local testing",
dateRange: [tomorrow, nextWeek],
} */

const dataUtils = {
// Try uncommenting the following line to set isRendering to be true:
// isRendering: true,
}

Save the file, then view the Block in the local browser again using npm start.

This code turns off the “isRendering” prop by making it an undefined value with the above change to the “dataUtils” local configuration in the /src/index.js file.

With “isRendering” off, you will now see the Block as it will be displayed in VOLT’s Site Designer, including the message regarding whether or not the banner is live.

Alternate Local Prop Data for /local/index.js

Feel free to change the other configuration in the /local/index.js file to manually test how the Block responds. Changes to the /local/index.js file should result in immediate changes in your web browser, but reload if they don’t. The above code sample provides an example of setting a start date of tomorrow, which will turn the Block off, so that you can test out that behavior.

To do so, simply swap the const localEnvPropOverrides with the version below it in the code comments.

Preview it, and you should see the message telling you that the Block is not live.

You might then want to try uncommenting the “isRendering: true” statement with the just to confirm that the Block will not be shown in a live store outside the sale dates.

Now you need to update the custom Block’s test files in order to publish it to the VOLT Store.

Unit Testing the Date Range Block

Open up the /__tests__/Block.spec.js file and replace the “data: {}” statement (line 13) with the following code:

   data: { isRendering: true },

This will cause the test to display (or render) the version of the page that is shown in the live store, when the “isRendering” prop is true.

To run the tests, enter the npm run test command in a terminal window:

npm run test

This code only tests the behavior of the dangerouslySetInnerHTML method by making sure that the HTML is being correctly stripped out (or removed) from the displayed text.

To test the CSS is being rendered (displayed) correctly, please refer to the previous article on Unit Testing CSS in Custom Blocks.

To fix the tests the Google AMP (Accelerated Mobile Pages) version of your site, repeat the same process with the file /__tests__/AMP.spec.js file, changing line 13.

These tests render the AMP version instead of the usual version of the custom Block.

Once you are done with both test files, you can build and publish the Date Range Block.

Build and Publish the Date Range

It is time to publish your custom Block, which will make it available to use in a Theme in the VOLT Store.

npm run build

You already updated the tests, which is necessary before you can build the Block.

Next, use the Element CLI to publish your custom Block with the element publish command, using the required -n (“name”) flag:

element publish -n "Date Range Block"

Please note the double quotes around the name of your custom Block.

When publishing, the Element CLI will prompt you to select a category for the Block. Do so using the arrow keys. Choose Promos & Announcements using the down key; then hit Enter.

You will see a warning that no image exists as a “thumbnail.png” file because there is currently no thumbnail image for the custom Block to display in VOLT’s Site Designer.

For help with adding a thumbnail, please refer to the 4-minute YouTube video How to Create a Thumbnail for Your Block | Element Tutorial | VOLT Resource Center or take a look at the documentation for Element CLI’s publish command. 

Your Date Range Block will now be available in “staging” inside VOLT’s Site Designer. It will not work on live stores until you release it, which will be covered in the next section.

For more information on publishing Blocks, please read the Element Platform Documentation about the Element CLI’s publish command. 

Release the Date Range Block to Production

Your newly published Block starts out in development mode (“staging”) in VOLT’s Site Designer.

This means that the custom Block is only visible on preview versions of the VOLT Store while working in VOLT’s Site Designer. 

The Block will not show on public (or live) VOLT Stores until you release it with the element release command (being sure to include the -n “Notes” flag):

element release -n "Release Notes for this Version"

As before, the release notes should be surrounded by quotes. Including optional release notes is highly recommended when releasing a Block.

The element CLI will ask you to confirm by entering “Y” for yes or “n” for no.

When you confirm, this will release the first public version of the custom Block, and the Block will immediately appear in all public VOLT stores that installed it.

It is a smart to mark the release of the public version using Git tag:

git commit -am "Public Version 1.0"
git tag 1.0

For more information on releasing Blocks publicly and version control, please refer to the Element Platform Documentation pages about the Element CLI’s release command and How To Track Block Versions.

Conclusion

Conditionally displaying an Element Block during certain dates lets you make a sale banner that automatically appears and disappears.

This tutorial demonstrated how to build a basic sale banner that will only be shown in the VOLT Store during the dates selected. The built-in date picker conveniently lets you select a range of dates for the block to be shown when editing the Block in VOLT’s Site Designer. When building the Block, you pass the “isRendering” prop into the Block from the data props. It needs to come in as data so that the live version of the store can trigger it properly. Once you are able to check the value of the “isRendering” prop, you simply set up conditional statements to check the dates using React’s short-circuit operator, as discussed.

Another thing to remember is that the dates are saved as ISO strings when they are set in Site Designer, so they need to be changed into JavaScript Date objects for comparison purposes.

You should be aware that comparing JavaScript strings directly using the relational operators uses String.prototype.toLocaleCompare() for lexicographical (or dictionary-order) comparison, which will not work correctly for dates. You need to compare JavaScript Date objects instead.

Having completed this tutorial, you have mastered the “isRendering” prop and the “dateRange” Proptype when making custom Blocks for the VOLT store using Element.

Further Reading

For instructions on adding additional Element Proptypes to the sale banner, please see the previous article “How to Mix Element Proptypes to Make a ‘Sale Banner.’” 

For information on what Proptypes are available and how they work, please refer to “Element Proptypes Explained: How to Store Data in Custom Blocks for the VOLT.”

For more information on formatting the sale banner using Element’s styling tools (Atomic CSS and Aphrodite), please see the article “How to Make a Hero Image Modal Block using Atomic CSS.”