Modal
Introduction
IHP provides support to render Bootstrap 4 Modals out of the box. Here’s how the result can look like:

Layout Setup
Before we can build our modal, we have to make sure that your current application layout has modal rendering enabled.
Open your Web/View/Layout.hs and add a {modal} just before the closing </body> tag:
defaultLayout :: Html -> Html
defaultLayout inner = [hsx|
<!DOCTYPE html>
<html lang="en">
<body>
{inner}
{modal}
</body>
</html>
|]
In case there is a {modal} already you can skip this step. Don’t add the {modal} twice.
Rendering Modal Views
Let’s say we have a ProjectsAction displaying a list of projects. We have a NewProjectAction that you can use to add projects.
data ProjectsController
= ProjectsAction
| NewProjectAction
Let’s turn the NewProjectAction into a modal that renders on top of the projects list.
First we need to modify our NewProjectAction. It currently looks like this:
action NewProjectAction = do
let project = newRecord
render NewView { .. }
We need to call setModal NewView { .. } to turn the NewView into a modal. We also need to call jumpToAction ProjectsAction to render the NewView on top of the ProjectsView which is going to be rendered by the ProjectsAction:
action NewProjectAction = do
let project = newRecord
setModal NewView { .. }
jumpToAction ProjectsAction
Let’s take a look at /NewPost, it now looks like this:

The NewView is now rendered inside the ProjectsView (it’s rendered where the {modal} is placed). Next, we’re going to add the modal styling.
Modal Styling
The Web/View/Projects/New.hs view looks like this at the moment:
module Web.View.Projects.New where
import Web.View.Prelude
data NewView = NewView { project :: Project }
instance View NewView where
html NewView { .. } = [hsx|
<div class="container">
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href={ProjectsAction}>Projects</a></li>
<li class="breadcrumb-item active">New Project</li>
</ol>
</nav>
<h1>New Project</h1>
{renderForm project}
</div>
|]
We’re going to use renderModal inside the html NewView { .. } definition to turn this into a bootstrap-styled Modal view:
module Web.View.Projects.New where
import Web.View.Prelude
data NewView = NewView { project :: Project }
instance View NewView where
html NewView { .. } = renderModal Modal
{ modalTitle = "New Project"
, modalCloseUrl = pathTo ProjectsAction
, modalFooter = Nothing
, modalContent = [hsx|
{renderForm project}
|]
}
After that our /NewProject view looks like this:

The call to renderModal Modal { .. } returns the HTML code for the bootstrap modal. You can think of it as a template function where modalTitle, modalCloseUrl, etc. just fill in the placeholder variables for the modal.
Common Issues
Could not deduce (Controller ProjectsController) arising from a use of ‘jumpToAction’
This error comes up when you try to render a modal on top of another controllers action.
To fix this error you need to add an import statement to the file where jumpToAction is called:
import Web.Controller.Projects () -- <----- ADD THIS LINE
instance Controller DeploymentsController where
action MyAction = do
jumpToAction ShowProjectAction { projectId }