Manually Control Responsiveness with Elm classifyDevice

Flavio Corpa
InstructorFlavio Corpa
Share this video with your friends

Social Share Links

Send Tweet

We will make all the necessary changes to keep track within our model of the device and orientation that the user is using, and change our UI according with that information, adding responsiveness and multiple columns (at last!) to our dashboard.

To do this, we'll need to modify our app state to track the device height and width (which we expose from JavaScript). Then we can use the classifyDevice function to pattern match the devices we want to handle, in our case, Desktop and everything else (as mobile). We will add a Browser.Events subscription that sends a ResizedApp message to our model that defines what device we are on.

Flavio Corpa: [0:00] Now that our app is working great, let's make it responsive. We need to do a couple changes in our model. We need to store the device and for setting the initial device in which we are right now, we need to do a small tweak to our index.js JavaScript file.

[0:15] Here, we're going to pass some flags, which are going to be window.innerHeight, and a window.innerWidth. Great. Now we need to go to our main application and say that the image is going to receive some flags and the flags that we're passing are an int and an int for the height and width of the screen.

[0:34] We go back to our init function and here we say that now we start up with two ints. We destructure them height, width. Then for the initial device, we're going to call the classifyDevice() function and pass it the height that we received from JavaScript and the width that we received from JavaScript. Awesome.

[0:51] Right now, we have in our model the device in which we are. We can proceed to our dashboard() function and here we're going to move these cards to their own binding, category1, category2, and finally category3. Great.

[1:10] With this change, now, it's easier to go here and say case model.device.class of, and if it is desktop, we want to render one way, and if it's any other device, we render as in we have it right now.

[1:25] We can copy this and paste it here and say that if it's desktop, we want some extra attributes. We want the width to be pixels 800, and the font size to be a bit smaller.

[1:37] For displaying category1, we want to display it in a row. If we fill adding XY 20 and , here we're going to show category1. Category2 and 3 are going to be inside the same row, will also be filled. We're padding each, top , right 20, bottom 20, and left 20, and the spacing is going to be 15.

[2:01] We're going to display another column with width fill, with category2. Finally, the second column with category3. Nice. Now, we're pattern matching on the device and saying, if it's desktop, I want to display category2 and 3 in two columns, and in any other device and orientation, I want to just display one column.

[2:21] We need one small change more. We need to create an additional message, which we're going to call resizeApp, which is going to take the height and the width.

[2:30] We're going to import browser events, exposing the onResize event. We're going to go down to our subscriptions and add an additional one that says onResize app, call the resizeApp message.

[2:44] We need to go to our update function and say onResize app we get the width and the height, and we update the model correspondingly again, coding classify device. We pass the height as h and the width as w. We don't want to call any message. Nice.

[3:04] Let's give it for a spin. The app knows that we are in phone mode. As we make it wider and wider, it hits the point, and width becomes desktop. Now, it's 800 pixels. As you see, two columns are being displayed, and the rest is working accordingly.

[3:26] We resize back to a smaller resolution. We made our app completely responsive.