Actions ======= We have now seen how to handle data exchange with the user at the basic level. However, we also want the application to be able to react to when the user instigates certain actions, such as clicking on a button or submitting a form. To handle any such kind of interaction we use the ``{{on}}`` helper. Update the ``
`` tag in the ``apps/templates/login.hbs`` to look like this: .. code-block:: handlebars The ``{{on}}`` helper is very powerful and supports a number of other parameters, but in its most basic form it has two parameters, which is when an action is triggered and the name of the action to call. The action will be called when the element emits the "submit" event. In the case of a ```` we want the action to fire when the user submits the form, thus we need to specify the property with the value "submit", so that the action is called when the user submits the form. We will cover helpers in more detail in an upcoming tutorial. The next step is to actually handle the action, which we will do in the ``app/components/login-page.js``: .. code-block:: js import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; export default class LoginPageComponent extends Component { @tracked email = ''; @tracked password = ''; @tracked loginInvalid = false; @action login(event) { event.preventDefault(); if(this.email === 'test@example.com' && this.password === 'password') { this.loginInvalid = false; } else { this.loginInvalid = true; } } }; All actions have to be specified with the ``action`` decorator and the name of the action function must be the same as the name of the action used in the ``{{on}}`` helper. The new action handler function demonstrates a few more Ember patterns. First, in the action handle ``this`` always refers to the current context. Second, to access any property on the component, we use the tracked property. This is necessary as Ember needs to know when we modify a property, so that it can update the UI. The rest of the code is relatively straight-forward. We get e-mail and password, check them and then set a new property ``loginInvalid`` to either ``true`` or ``false``. Note, that we have a parameter that is called ``event``, even though we did not pass it in the function when we called it in the ``hbs``-file. The ``on``-helper is passing this parameter automatically for us. We use this parameter to prevent the default behavior. If we did not do so, this behaviour would have caused the page to reload without setting the values of our classes. Templating Control: ``{{if}}`` ------------------------------ We can now use the new ``loginInvalid`` to only show the error message if the login failed. Update the two error message ```` elements in ``app/components/login-page.hbs`` to look like this: .. code-block:: html {{#if this.loginInvalid}} No user exists with the e-mail address {{this.email}} or the password is incorrect. {{/if}} Previously the helpers we used (such as ``{{on}}``) did not have any content. For helpers that do have a content, the opening tag is specified with a ``#`` and the closing with a ``/``. In the case of the ``{{#if}}`` statement, the next part of the opening tag is to specify the property that is tested for ``true`` or ``false``. What is important here is that we cannot specify any comparisons directly in the template. We can only specify the property to check for its truthiness. If we want to do more complex checks, these need to be performed in the controller and then the result set to a single property, which is then used in the template. Templating: Binding Attributes ------------------------------ We have now seen how to bind properties to input fields, make the template dynamic, and react to actions. The next thing we want to do is to bind a property to the attribute of one or more HTML elements, so that we can modify the HTML element attribute value. We will use this to further highlight any errors in the form. Again, we can make use of Ember's ```{{if}}``-helper, but we use it inline this time. Update the two ``