Building CampaignHawk: Making Modals (Part 6)

Time to make some modals. You’ll recall that our modals need to look something like the image below from our wireframes in the first part of this series.

Modal content will change based on context and will get it’s data from Meteor at some point.

I’m going to put everything that has to do with modals in a separate file called Modal.jsx and create a component called Modal which will be the outer container for all our modals.

Modal is going to darken the background and disable events behind the background, and give us a nice white background on which we can add content.

Step 1: Making Modals

First we need to set up our content area within Map. Right now the whole thing is 60 pixels off because of our absolutely positioned sidenav. A div that wraps the area should fix that.

<div className="content-wrapper">
<h1>This is where the map goes</h1>
</div>

Then let’s define content-wrapper as having a width that is 100% minus 60 pixels, and left padding of 60 pixels.

.content-wrapper {
width: calc(100% - 60px);
padding-left: 60px;
}
Placeholder text is no longer hidden behind the sidenav.

That should move the placeholder text out from behind the sidenav.

Then we need to give some thought to the modal. Every good modal should darken the background and disable events behind the modal.

This will be accomplished almost entirely in CSS, but first we need to create the divs and the classes on which we will apply the styling. In our Modal component, replace what you render with the following content:

<div className="modal-active-darken">
<div className="modal-container">

</div>
</div>

Then we need to style these elements. In style.scss, add the following, which will blacken the background with 50% opacity, strech across the container, disable pointer events, and center the modal once we create it.

.modal-active-darken {
background-color: rgba(0,0,0,.5);
width: 100%;
height: 100vh;
pointer-events: none;
display: flex;
justify-content: center;
align-items: center;
}

Then within modal-active-darken, add the styling for the modal:

.modal-container {
width: 60%;
min-height: 500px;
background-color: white;
pointer-events: all;
border-radius: 2px;
box-shadow: 5px 8px 10px 0px #565656;
}
Empty modal container.

The empty modal container now looks like the image above.

Step 2: Filling Modals

Now that we have the container in place, we need to fill it in with content. The first modal is just a form that is split into three sections:

The top two sections are split roughly 55–45 and the top and bottom are split 50–50.

Let’s start by creating a new modal component that has a form for adding a new volunteer called AddVolunteerModalContent.

AddVolunteerModalContent = React.createClass({
render() {
return (
<div>
<div className="volunteer-form-row">
<div className="volunteer-form-column-55">

</div>
<div className="volunteer-form-column-45">

</div>
</div>
<div className="volunteer-form-row">
<div className="volunteer-form-column-100">

</div>
</div>
<div className="submit-modal-buttons">

</div>
</div>
)
}
})

This should give us the basic structure of our modal. Note that there is now a place for buttons on the bottom. Now we need to set the styling on those pieces so they section the modal properly. Let’s start with volunteer-form-row:

.volunteer-form-row {
height: 225px;
width: 100%;
padding: 10px 20px;
display: flex;
align-items: center;
box-sizing: border-box;
}

Since our modal is 250 pixels, we want our rows to be 225 pixels to give us room on the bottom for our buttons. We also want each row to span 100% of the width with some padding around the edges, which means we need box-sizing set to border-box so our containers work properly. Lastly, we’re setting display to flex and aligning items to the center.

NOTE: We’re going to use a lot of flexbox. I don’t always recommend reading the entirety of the docs for something, but when I do, I recommend reading the docs for flexbox. This will save you a lot of CSS headache.

Within volunteer-form-row, we want to set up our columns. Our first column will be 55% of the width. We’re also going to use flex with flex-direction set to column to align the items vertically.

.volunteer-form-column-55 {
width: 55%;
display: flex;
flex-direction: column;
padding: 0 20px;
box-sizing: border-box;
}

The volunteer-form-column-45 will be very similar with a couple exceptions. We need to set the height so flexbox knows how much space to fill and we need to align the items in the center because unlike our list of inputs, these will be horizontally centered as well. We also need to set the position to relative because we will eventually want an absolutely positioned “x” in the top right to close the modal.

.volunteer-form-column-45 {
width: 45%;
position: relative;
height: 225px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

And for volunteer-form-column-100, we’re going to do roughly the same thing as we did for the first column:

.volunteer-form-column-100 {
width: 100%;
display: flex;
justify-content: center;
box-sizing: border-box;
align-self: center;
height: 150px;
}

And the last column is for the buttons, which we want to display flex with flex-direction as row-reverse so they start from the right and move to the left.

.submit-modal-buttons {
display: flex;
flex-direction: row-reverse;
}

So at this point the modal looks like the image below when placeholder text is inserted.

That’s a good place to take a break. We’ll go over inserting actual content in the next article.

Next Steps

The next thing we need to do is insert the content for the form in our AddVolunteerModalContent component. Once we do that, we’ll need to create some functions to show and hide the modal and render it with the proper content.