Motivation

Some time ago I had been working on a search feature. The UI was designed on a fullscreen page.
As hiding navbar and footer or providing separate layout was tricky and not intuitive I decided to use fullscreen modal dialog.

Generally, modal dialogs have become a ubiquitous feature of mobile web design, but designers need to put more thought into when to use them, and when to leave them.
You can read more here: https://uxmag.com/articles/modals-on-mobile-how-to-use-them-wisely

By the way, you would ask why the designer planned interface as a full-page view?

From the usability perspective modal rendered in fullscreen have a few advantages:

  • it keeps users focus only on a particular task. We don’t want to distract the user with the content “behind” the modal
  • it will work on mobile devices as modal size will adapt to every screen size
  • there are opinions that fullscreen modals look better and cleaner

Summing up requirements are as following:

  • Implement modal dialog responsible for data searching;
  • Render modal dialog in fullscreen;
  • Modal dialog should be accessible from everywhere in the application;
  • It should be possible to close search modal dialog and bring back the user to the home view.

We need to keep in mind a few things:

  • Users will hit the back button in the browser when modal is opened;
  • Process of loading data asynchronously should be done in “background”, we want to show render modal smoothly
  • URL should store the state. Thanks to this, it will work nicely with the user refreshes the page.
  • We want to stick to Ember convention (route based model fetching) to prevent problems in future ***

*** New stuff, must check it out:

Code

Enough talking, based on what has been said let’s allow tests drive us:

tests/acceptance/search-test.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { test } from 'qunit';
import moduleForAcceptance from 'notes/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | Search');

test('layout contains link to search', function(assert) {
visit('/');

andThen(function() {
assert.equal(currentURL(), '/');
assert.equal(find('.navigation a#search').text(), 'Search');
});
})

test('click on search link redirect to search page', function(assert) {
visit('/');
click('.navigation a#search');

andThen(function() {
assert.equal(currentURL(), '/search');
assert.equal(find('h1').text(), 'Search Page');
});
});

So let’s make it green:

app/templates/application.hbs

1
2
3
4
5
6
7
<div class="navigation">
{{#link-to "search" id="search"}}Search{{/link-to}}
</div>

<div class="page-content">
{{outlet}}
</div>

app/templates/search.hbs

1
<h1>Search Page</h1>

It works, but it’s just a simple page.
There is a great addon for modals dialogs, it also allows us to use a routable approach! Excellent!
So let’s add it to our package.json by running:

1
$ ember install ember-modal-dialog

app/styles/app.scss

1
2
@import "ember-modal-dialog/ember-modal-structure";
@import "ember-modal-dialog/ember-modal-appearance";

app/templates/search.hbs

1
2
3
{{#modal-dialog}}
<h2>Fullscreen Search Page</h2>
{{/modal-dialog}}

Now, let’s modify our test a little:

tests/acceptance/search-test.js

1
2
3
4
5
6
7
8
9
10

test('click on search link opens modal dialog', function(assert) {
visit('/');
click('.navigation a#search');

andThen(function() {
assert.equal(currentURL(), '/search');
assert.equal(find('.ember-modal-dialog h2').text(), 'Fullscreen Search Page');
});
});

It’s much better, we have the king of the routable modal.
However, this needs to be done to display it in fullscreen:

app/components/full-screen-modal-dialog.coffee

1
2
3
4
5
6
import ModalDialog from 'ember-modal-dialog/components/modal-dialog.js'

export default ModalDialog.extend(
containerClassNames: "full-screen-modal",
targetAttachment: "none"
)

app/styles/app.scss

1
2
3
4
.full-screen-modal {
width: 100%;
height: 100%;
}

And finally, in our template we do small change:

app/templates/search.hbs

1
2
3
{{#full-screen-modal-dialog}}
Fullscreen Screen Page
{{/full-screen-modal-dialog}}

Let’s say, now we have fullscreen modal and some acceptance tests, which we can simply run in a browser by:

$ ember test --server --filter="search"

  • where search needs to be the module name or test name.

That’s the first step. In the next post we will focus on extending functionality by building search form and list items using Ember components. We will provide some virtual backend to make it behaves like a real app.

Stay tuned!