Press "Enter" to skip to content

Using ReactJs in K2 (Masonry Layout)

2

I have been a fan of ReactJs for some time so far. I like the idea, that, as well as in K2, you can also create reusable components, even though the framework allows more customizations. K2 cannot be used to build single page applications, but nobody said it is not allowed to use ReactJs to create nice UI or layouts. In this post I will show you, how you can use ReactJs to build a masonry layout for images, stored in a SmartObject. The ReactJs component will get the images from K2 and render them in a nice responsive way. By the way, the approach is also suitable for K2 Cloud, where you cannot install any custom controls. So let’s go!

1. Prepare a K2 View

Since React by default selects an HTML element, inside which the full application is rendered, I added 2 literal Data Labels onto the SmartForm:

  • react-control-js – will contain a script tag, which will load the bundle.js file, i.e. a built ReactJs app.
  • react-control-root – will be used by React to render the masonry layout inside;
Added data labels

Meanwhile, I am not sure if it is possible to make an SMO call directly from the custom script in the DOM context. Therefore, I will use a List Display control, which will make an SMO call and receive all images, which in their turn will be later used by the React Component. But in order to be able to have the necessary data, you need to map IMAGE property of the SMO to both – Value and Display properties of the List Display control:

List Display

Our K2 view is almost ready, so we can move on to the React Application.

2. Create a React Application

I used one of the boilerplates, available on the Internet. You can see my example on GitHub – k2-react-control. Here are some important points to take into account, when creating the React Application.

Change the element, where our application should render.

In my code you can find this in the index.js file. I am searching for the ‘react-control-root‘ element render the React application there:

React-masonry-component

In the React application I am using ‘react-masonry-component‘, which was already built for a masonry layout of images.

xml2js module

I am using ‘xml2js‘ module to parse file RequestData, returned as XML, into JS object and extract the necessary properties.

componentDidMount()

This is the standard method from the React Component life-cycle. I am using it to do the following:

  1. Find the List Display control instance.
  2. Parse the data in order to extract requestData values.
  3. Save the extracted values in the Component state.

render()

This method is also an integral part of every React Component. Here I am building an array of <img/> elements and render the Masonry layout. The interesting part is how the Image URL looks like. In my case it has the following format:

/Designer/Runtime/File.ashx?_path=NOPATH&_controltype=image&X-K2-Token=&_filerequestdata=<Request Data>&XSRFToken=11111111111

You can see in my code, how I am doing all of the mentioned above:

After the React application is ready, you need to build it in order to obtain 1 bundled js file.

3. Add ReactJs into K2

After I built everything, I committed all my code to GiHub, including the bundle.js file in the Public folder. With the help of a nice jsDelivr service, I can expose the bundle.js file as a CDN link . In my case it looks like this:

https://cdn.jsdelivr.net/gh/dudelis/k2-react-control@master/public/bundle.js

The last thing I need to do is to make sure the bundle.js is run only after our List Display control loads all Images from the SMO. For this I am creating an expression with the <script>…</script>:

Script tag

And I am sending this expression into the literal ‘react-control-js‘ Data Label after the SMO call:

Configure Data Label

And finally, you can run the K2 view and/or the form with the ReactJs component and enjoy the result:

Masonry Layout

Check also my previous posts, so that certain steps can become more clear for you:

  1. Nice article, I’m trying to do the same with Angular 6/7,…Is it possible???

    Thanks ind advance

    • Konstantin Fukszon Konstantin Fukszon

      Hi Cristian,
      As far as I remember, Angular does the same. I mean, it also finds the root tag and renders the whole application there. And when you build it, it should also be a single bundled file. If it is not, it’s better to modify webpack and try to make 1, cause it it easier to load 1 file into K2.
      So it should be possible.
      Best regards,
      Konstantin

Leave a Reply

Your email address will not be published. Required fields are marked *

16 − 9 =