0. Introduction
A simple login form can have basically:
- A user name input field
- A password input field
- A submit button
- A component for showing messages
- A component for selecting the language
We are calling this class "LoginForm" and this name must be the same as the one defined in then openadmin.listeners.LoggedInListener class for redirecting to the user that has not been logged in. See this previous post.
Here is a simple sketch of the login form
+---------------------------------------------------------+
| +--------+ |
| | LOGO | 1 ENTERPRISE NAME |
| | | |
| +--------+ |
+---------------------------------------------------------+
| +---------------------------+ |
| 2 | Language selector combo | |
| +---------------------------+ |
+---------------------------------------------------------+
| 3 |
| +-------------------+ |
| User: | | |
| +-------------------+ |
| |
| |
| +-------------------+ |
| Password: | | |
| +-------------------+ |
| |
| +-------------------+ |
| | Login Button | |
| +-------------------+ |
| |
1. Designing the visual interface
Here is a simple sketch of the login form
+---------------------------------------------------------+
| +--------+ |
| | LOGO | 1 ENTERPRISE NAME |
| | | |
| +--------+ |
+---------------------------------------------------------+
| +---------------------------+ |
| 2 | Language selector combo | |
| +---------------------------+ |
+---------------------------------------------------------+
| 3 |
| +-------------------+ |
| User: | | |
| +-------------------+ |
| |
| |
| +-------------------+ |
| Password: | | |
| +-------------------+ |
| |
| +-------------------+ |
| | Login Button | |
| +-------------------+ |
| |
| +--------------------------------------------------+ |
| | Notification messages | |
| +--------------------------------------------------+ |
| |
| | Notification messages | |
| +--------------------------------------------------+ |
| |
+---------------------------------------------------------+
We are considering 3 containers indicated in yellow colour:
- Header panel
- Language selector panel
- Login panel
2. Image resources
The image resources (photos of the enterprise) are in this folder. If not exists the route from webapp folder you should create it.- Deployed Resources/webapp/frontend/img/enterprise
The images are taken from a "Whatsapp group" and are a protest against the citriculture problems in Valencia (Spain). It is a simple example. The images are the same but have different size.
About the flag images, we have talked about in a previous entry. They are in this folder:
- Deployed Resources/webapp/frontend/icon/flags
3. i18n resources
They are in this folder. If not exists i18n folder you should create it.
- src/main/resources/i18n
There are 2 groups of resources:
user = User password = Password login = Login invalid_credentials = Invalid credentials
and the contents of the English version of main is:
enterprise=The Death of Agriculture in Valencia
3. LoginForm component
Take into account that:- Is annotated by @Route("") as it is the first route Vaadin looks for.
- Extends a VerticalLayout
- Implements II18nChange (created in a previous post), to allow changing labels affected by the Locale. The method it implements is changeI18nLables()
- It has 3 parts (header panel, language selector panel and login panel)
- The language selector panel has a component that was created in the previous post that select the language and changes all labels content affected by the language change.
- The login button executes the login() procedure to test if the user can log in.
- The keyboard key "enter" also activates the login() procedure
- If the user is logged in, it is redirected to a view that is annotated by @Route("main").
- The valid user is "user" and the password is "password"
Here is the code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | ackage openadmin.ui; import javax.annotation.PostConstruct; import javax.inject.Inject; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.Html; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.html.Image; import com.vaadin.flow.component.html.Label; import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.component.orderedlayout.FlexComponent; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.PasswordField; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import openadmin.session.SessionData; import openadmin.utils.VaadinUtils; @Route("") @PageTitle("Login") @SuppressWarnings("serial") public class LoginForm extends VerticalLayout implements II18nChange{ private TextField userName; private PasswordField password; private Button login; private LocaleCombo langCombo; private Label lblUserName; private Label lblPassword; private Label lTitle; private Image imageLang; @Inject private SessionData sesData; public LoginForm() { } /** * Initialization of the 3 panels */ @PostConstruct private void init() { add(getHeaderPanel()); add(getLangSelectorPanel()); add(getLoginPanel()); } /** Enterprise header **/ private HorizontalLayout getHeaderPanel() { HorizontalLayout headerPanel = new HorizontalLayout(); Image logo = new Image("frontend/img/enterprise/enterprise04.jpg", "logo"); headerPanel.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, logo); headerPanel.add(logo); HorizontalLayout title = new HorizontalLayout(); title.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER); lTitle=new Label(getTranslation ("main.enterprise")); headerPanel.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, lTitle); title.add(lTitle); headerPanel.add(title); return headerPanel; } private HorizontalLayout getLangSelectorPanel() { HorizontalLayout langSelPanel = new HorizontalLayout(); langSelPanel.setJustifyContentMode(FlexComponent.JustifyContentMode.END); // 1. Language ComboBox. langCombo = new LocaleCombo(sesData, this); langSelPanel.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, langCombo); langSelPanel.add(langCombo); // 2.Flag Icon imageLang = new Image("frontend/icon/flags/" + sesData.getLangEnum().name() + ".png", "language"); //imageLang = new Image("frontend/icon/flags/" + lEnum.name() + ".png", "language"); // Jetty langSelPanel.setVerticalComponentAlignment(FlexComponent.Alignment.CENTER, imageLang); langSelPanel.add(imageLang); return langSelPanel; } private Component getLoginPanel() { VerticalLayout loginPanel= new VerticalLayout(); VerticalLayout loginForm = new VerticalLayout(); // 1. User lblUserName = new Label(getTranslation ("login.user")); userName=new TextField(); userName.setValue("admin"); loginForm.add(lblUserName, userName); //2. Password lblPassword = new Label(getTranslation("login.password")); password = new PasswordField(); loginForm.add(lblPassword, password); password.setWidth("15em"); //3. Line separation loginForm.add(new Html("<br/>")); //4. Buttons layout HorizontalLayout buttonsLay = new HorizontalLayout(); buttonsLay.setJustifyContentMode(FlexComponent.JustifyContentMode.END); loginForm.add(buttonsLay); buttonsLay.add(login = new Button(getTranslation("login.login"), VaadinIcon.SIGN_IN.create())); //5. Login button login.addClickListener(event -> login()); //assign action to button //6 Keyboard event listeners loginForm.getElement().addEventListener("keypress", event -> login()).setFilter("event.key == 'Enter'"); loginPanel.setHorizontalComponentAlignment(FlexComponent.Alignment.CENTER, loginForm); loginPanel.add(loginForm); return loginPanel; } /** * Try to log in if credentials are correct */ private void login() { if (userName.getValue().length()<1 || password.getValue().length()<1) { showNotification("login.invalid_credentials", 2000); userName.focus(); // user & password credentials }else if (userName.getValue().equals("user") && password.getValue().equals("password")) { VaadinUtils.setSessionAttribute("CURRENT_USER", userName.getValue()); getUI().get().navigate("main"); }else { showNotification("login.invalid_credentials", 2000); userName.focus(); } } /** * Show notification * @param i18nKey * @param duration */ public void showNotification(String i18nKey, int duration) { String translatedMessage=this.getTranslation(i18nKey); Notification not=new Notification(translatedMessage); not.setDuration(duration); not.open(); } /** * Change labels according to Locale */ @Override public void changeI18nLabels() { lTitle.setText(getTranslation ("main.enterprise")); lblUserName.setText(getTranslation("login.user")); lblPassword.setText(getTranslation("login.password")); login.setText(getTranslation("login.login")); imageLang.setSrc("frontend/icon/flags/" + sesData.getLangEnum().name() + ".png"); //imageLang.setSrc("frontend/icon/flags/" + lEnum.name() + ".png"); //Jetty } } |
Here is the result in the browser
In the next post, we are adding style.
No hay comentarios:
Publicar un comentario