How I customized Ionic’s AlertController to use custom toggles

Bend the component to your will!

E.Joo
4 min readSep 7, 2018

The Ionic framework comes with a nice collection of pre-built UI components straight out of the box, but as with many pre-built UI components, there is sometimes a lot left to be desired regarding customization, especially if something simply isn’t supported.

I needed to create an alert popup, that allowed the user to email generated PDFs, based on the options that they choose. I started off with Ionic’s AlertController, and created something like this:

Actual option names replaced with generic “option #”

There was already some CSS styling that carried over from my global styles for alerts, but as you can see, these aren’t toggles, these are checkboxes. I’m not sure why Ionic chose to not support toggles in their component (especially since toggles are literally everywhere now), but as shown in their API, only radio and checkbox inputs are acceptable, which is not acceptable to me, nor my client.

So what’s next? Scrap using Ionic’s component, and build a custom modal? Possibly, but I had other plans.

Since I started working more and more with CSS/SASS, I realized quickly how much you can really do with CSS. Now, by no means would I consider myself fluent in CSS, but I like to think that I at least get by.

So first things first, I added some styling to arrange some things, and make it look nicer. This isn’t the interesting part, but simply setting the stage for the toggles to come.

Now, here are my steps to make them toggles happen:

Convert the blue checkbox circles to become the “slider”
This was the easy part. Simply hide the checkmarks with CSS, and I threw in some CSS for styling.

.alert-checkbox-icon {
height: 1.5rem;
width: 1.5rem;
transform: translateX(-2.7rem);
border-color: map-get($colors, light);
background-color: map-get($colors, light);
box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.2), inset 0px -1px 0px
0px rgba(0,0,0,0.15);
@include transition(all 0.5s);
.alert-checkbox-inner {
visibility: hidden; < -- hides the hideous checkmarks
}
}

.

.

At this point, they already almost look like toggles. So far so good!

.

Create the ‘playpen’ for the toggles to move around in
Not sure if there’s a technical term for this ‘playpen’, but that’s what I’ll call them from now on.

If you look into the logic behind the checkboxes (soon to be toggles), you see that there’s ARIA logic for the checkboxes, which we can take advantage of to trigger the CSS toggling magic.

So by combining this, along with the always amazing CSS ::after selectors, you can do something like this:

Beautiful. But incomplete.
[aria-checked=false] .alert-checkbox-label::after {
position: absolute;
content: "Off";
font-family: $font-family-bold;
font-size: mapGet($basefont, size, small);
color: white;
height: 2.25rem;
width: 5rem;
box-shadow: inset 0px 2px 0px 0px rgba(0,0,0,0.15);
border-radius: 2.25rem;
z-index: -1;
left: 12.5rem;
transform: translateY(-0.5rem);
background-color: rgb(148,148,154);
text-indent: 2.2rem;
line-height: 2.2rem;
@include transition(all 0.5s);
}

Move that dang toggle
Now we have to make the toggle itself move to the right. Simple-ish.

.alert-ios [aria-checked=true] .alert-checkbox-icon {
border-color: map-get($colors, light);
background-color: map-get($colors, light);
transform: translateX(0rem);
@include transition(all 0.5s);
}

The transform: translateX(0rem) may be confusing, but this actually puts the ‘toggle’ back to its original position, since previously, this had been applied to it transform: translateX(-2.7rem);

::after selector for checked=false
The final step, similar to checked=true.

[aria-checked=true] .alert-checkbox-label::after {
position: absolute;
content: "On";
font-family: $font-family-bold;
font-size: mapGet($basefont, size, small);
color: white;
height: 2.25rem;
width: 5rem;
box-shadow: inset 0px 2px 0px 0px rgba(0,0,0,0.15);
border-radius: 2.25rem;
z-index: -1;
left: 12.5rem;
transform: translateY(-0.5rem);
background-color: map-get($colors, primary);
text-indent: 1rem;
line-height: 2.2rem;
@include transition(all 0.5s);
}

Fin.

And there you have it. This article may definitely feel rushed if you’re new to CSS, or this article may make you pull your hair out if you’re an expert at CSS (my CSS probably leaves much to be desired). But the purpose of this article wasn’t to show great CSS, but to show that with some “hacking”, a pre-built UI component can be bent to your will, even if it isn’t supported! Take that, Ionic!

Thanks for reading! I appreciate any feedback on what I could do better, and will answer any questions!

Cheers,
Elliott

--

--