Sweetalert as UI Framework
With this article I want to share with you a funny idea to build UIs, that is different from the todays declarative web frontend frameworks.
tlrd; It is based on sweetalert and flow from page to page is completely in functional style. Development is very fresh and satisfying but not necessarily an alternative to established frameworks.
background history with alert
I think for many javascript developers, one of the first functions we learn to know is alert
. It opens a small box with text and the user can click it away. And also most people directly learn that we should not use it to much.
But, what is that advice of best practise, *not to use alert’, worth anyway? how would it feel to have an application entirely of alert boxes?
To be honest, with just alert the alert function you can not do much. because you do not get any input from the user. We can however get some input from two friends of the alert box.
First is ‘confirm’. It let the user choose between ‘ok’ and ‘abort’. And the return value is a boolean, depending on which button was clicked. The ‘prompt’ function let the user input some text that is then returned.
With this we have in theory everything needed to build complex applications.
We can use ‘prompt’ for navigations, list out application modules and let the user choose. Maybe by typing a number.
We can let the user input data, validate the data, process it and display using na ‘alert’.
In fact, I made it, here is a complete Create-Update-Delete (CRUD) application, that let you manage user accounts.
Is that a good experience? No. This is where SweetAlert comes in.
application flow in the functional programming paradigm
But first, I want you to see the programming style. Everything is functional programming. There are modules and these modules are functions themselves.
The main function is a menu, presenting the user with choices in a infinite loop.
1 | function main() { |
The aboutAuthor module shows a good fact about me.
1 | function tobiasView() { |
The usersModule is also showing a menu with the CRUD operations and an option to return, its structure is similar to the main function. You also see that in this demo, our database is just going to be a javascript array.
1 | const userDB = []; |
At the listUser view the user can see of all users. noted how I used the word view?
1 | function listUserView() { |
create Users askes the user to insert all properties, present a complete user and store the user in the db. And yes, the database is a plain old Array
.
1 | function createUserView() { |
Updating is almost the same, but it has the current value as default and only update the value.
1 | function updateUserView() { |
DeleteUser allow the user to remove a user from db by typing the users index.
1 | function deleteUserView() { |
You get the point, right? When navigating in the application, the user is navigating through these functions. When a module is finished, the parent module can continue. And I believe this is a very interesting programming paradigm. When coding in this way, the flow within the application is very clear.
Using this paradigm with sweetalert
Sweetalert is a little library that provides a single function called swal
. With it you can open a modal dialog box. Depending on the options passed in, the dialog can have a title
, text
, buttons
or any custom content. Within a created dialog, you can show images, complete forms (instead of a single input field in prompt).
My favorite feature of the swal function however is that it returns a promise, that will resolve once the user close the modal, or clicked one of the buttons. Once the promise is resolved, values can be read from a shown form or the choice that a user made can be processed.
Now. Before I show you how to make a similar application as before, an app to organize users. I want to you experience it yourself and take a look at the swalapp.
When you open this app in a new page, you will see that it even has routing. When you navigate to the users module, the route in the browsers URL bar is /users
and when you navigate to the create user
page the route is /users/create
. And when refreshing the browser the app can bring you right back where you left of.
Also after storing the user, it is easy to display a success screen for a very breve moment. When opening the app there is a little splash screen, that shows a picture.
Implementation with sweetAlert2
The main function again let the user choose a module. But in this solution the it also need to handle routing:
1 |
|
With all that routing this function look much more ugly from before, but the routing is worth it. And the core loop is basically the same. You see instead of prompt we can use sweetalert
s buttons.
The aboutPage
and the tobiasView
, both are very similar and showing a simple message just that the tobiasView is allowing to show more texts.
1 | export async function tobiasView() { |
For the users module, we again need a menu page that give access to read, create, update and delete functions. With the routing functionality this function looks similar to the main function. Each sub module is in its own function.
1 | const userDB = []; |
The list users page, is showing the users in a unordered html list. The element function is similar to jQuery, it creates an element from html.
1 | async function listUsers(){ |
The createUsers page is also using the element function. This time it creates a complete form, to input name, email and password. The getFormValues function makes it very convenient to read the data form the form. This is so much better than having a separate prompt window for each field.
1 | async function createUser() { |
To delete a user, we show the user a select box where the user can choose which user to delete.
1 | async function deleteUser(){ |
The updateUser view is like a combination of delete and create. First let the user select a user, then show the form with the selected users data prefilled. I do not show the source here. Do you want to implement this function yourself?
How do you like this coding style? quite fun right? I really like to have to follow only a single flow throughout the application. Please note: I do not want to promote describing the views with html strings. Feel free to use react, or any other ui library to build a pages UI.
how to do better
Now I want to show you two helpers that will make developing these kind of apps much more efficient. One is to a menuFactory function that takes a configurations for routing, navigation buttons and views that can be routed to.
1 | export function menuViewFactory(config) { |
it can be used like this:
1 | const appView = menuViewFactory({ |
This helper is ok and when working with it, I am sure we can still improve on it. For example: to make route and button text be able to be different.
The second helper that can help us to make the routing between modules possible. It consists of two parts.
sweetAlertApp
is the entry into the app. It takes the main view of the app, and handles an error with a dedicated redirect property.redirect
is meant to be used for redirecting the user to a different part of the application. It does so, by throwing an error with a.redirect
property so that the current views get exited and the application can route fresh to a new location.
1 | export async function sweetAlertApp(view: (...args: any) => any) { |
With this, we can provide cross navigation. The user can go from the selfDescription view directly to the userList view, without navigating through the main menu and the user menu.
conclusion
Wow, if you kept reading up until this point, I guess you like the idea. I believe it is so surprisingly effective. It was really quick to bring these peaces together. At least for building application prototypes, I have never experienced anything more effective.