Iliad (session and statefull forms)
Hello again.
The weekend ends and I used today, to get a bit deeper into Iliad.
I created the login-dialog, which shows you, that if you open it again, the same data apears again that you already typed in and I used the session, to store a switch, if the user is logged in.
So, the first thing I did, was to overwrite the Application initialize method, to initialize the new switch, which I want to save into the session.
initialize [
super initialize.
self session preferenceAt: #userLoggedIn put: false.
]
The current session is in every subclass of IliadObject accessible throug #session.
So in every Widget or Application, the current session is available.
After the new switch is initialized, the next thing I did, was to enhance the Menu class, to have additional entries, if the user would be logged in.
I created a new instance-variable entriesLoggedIn and the appropriate #addEntryLoggedIn:withAction method. (It's the same as the addEntry:withAction method, it only accesses the new instance-variable.)
At the end of the initialize-method I added a:
self addEntryLoggedIn: 'Bla' withAction: [self redirectToLocal: '/'].
and at the end of the current contents method the following code:
(self session preferenceAt: #userLoggedIn)
ifTrue: [
entriesLoggedIn do: [ :each |
(ul listItem anchor) text: each key; action: each value
]
]
Now let's create the login dialog. Therefore I enhanced (modified) the Login class that it looks afterward like:
UrPics.PageTemplate subclass: Login [
| userName userPassword |
userName [ ^userName ifNil: [userName := '']]
userName: aName [userName := aName]
userPassword [ ^userPassword ifNil: [userPassword := '']]
userPassword: aPassword [userPassword := aPassword]
mainContent [
^[ :e |
| div form table row data |
div := e div.
div h1: 'Login'.
form := div form.
table := form table.
row := table tableRow.
row tableData text: 'Username:'.
row tableData input
value: self userName;
size: 20;
action: [:val | self userName: val].
row := table tableRow.
row tableData text: 'Password:'.
row tableData password
value: self userPassword;
size: 20;
action: [:val | self userPassword: val].
row := table tableRow.
row tableData.
data := row tableData.
data button
action: [self doLogin];
text: 'Login'.
data button
action: [self redirectToLocal: '/'];
text: 'Cancel'.
e break; break.
]
]
doLogin [
self session preferenceAt: #userLoggedIn put: true.
self redirectToLocal: '/'
]
]
Here, I setup 2 instance-variables (userName and userPassword) and created their accessor methods. Through these variables, the state will be saved through the different calls of the web-pages. (Okay, later on, we will have to make a small change in our Application, to have the state saved of the complete Login-page...)
But you can see, how to provide and save the data from and into these variables and the associated input-fields of the form. Look at the #value: and #action methods for the name and password input fields.
Additional you see how to handle a button. You can directly provide an action-block to the button, which will be evaluated, if the button is pressed. In the save-button case, we call the doLogin method of the class and in the cancel-button case, we go directly back to the homepage of our application.
If you now run the application, the login-dialog will appear and will basically do it's job, but it could not save the inputs of the dialog between subsequent displays of the different web-pages of our application. To achieve this, we have to do a littel modification in our Application-code.
We create an instance-variable for the Login class (loginView) and the accessor method:
| loginView |
loginView [
^loginView ifNil: [ loginView := Login new ]
]
And because, we are creating an instance of Login, if we need it and it doesn't currently exist, we could have a look at our old #login method, where we create every time we call login a new instance of the Login-class.
So we change the method to the following code:
login [
^[ :e |
e add: self loginView build
]
]
That's all. You saw, how to enhance the session with additional data, and how to save the state of the widgets.
Happy coding!
Joachim.
