Forms and their validation using Semantic UI in Open Event Frontend

A web form acts as a communication bridge that allows a user to communicate with the organisation and vice versa. In the Open Event project, we need forms so users can contact the organisation, to register themselves, to log into the website, to order a ticket or to query for some information. Here are a few things which were kept in mind before we designed forms in the Open Event Frontend Project:

  • The forms were designed on the principle of keeping it simple which means that it should ask only for the relevant information which is required in actual.
  • They contained the relevant fields ordered in a logical way according to their importance.
  • They offered clear error messages instantly to give direct feedback and allow users to make instant corrections.
  • The clear examples were shown in the front of the field.
  • Proper spacing among the fields was maintained to display proper error messages to the respective form fields.
  • The mandatory fields are highlighted using ‘*’ to avoid confusion.
  • Proper colour combinations have been used to inform the user about the progress while filling the form. For eg. red for any ‘error or incomplete’ information while green signifies ‘correct’.
  • Saving the current data in case the user has to go back to make any corrections later.
  • Allowing to toggle through the form using the keyboard.

The above designing principles helped in avoiding the negative user experience while using the forms.

Let’s take a closer look at the form and the form validation in case of purchase a new ticket form on the Orders page in Open Event Front-end application.

Creating a form

Let’s start by writing some HTML for the form:

<form class="ui form" {{action 'submit' on='submit' }}>
  <div class="ui padded segment">
    <h4 class="ui horizontal divider header">
      <i class="ticket icon"></i>
      {{t 'Ticket Buyer'}}
    </h4>
    <div class="field">
      <label class="required" for="firstname">{{t 'First Name'}}</label>
      {{input type='text' name='first_name' value=buyer.firstName}}
    </div>
    <div class="field">
      <label class="required" for="lastname">{{t 'Last Name'}}</label>
      {{input type='text' name='last_name' value=buyer.lastName}}
    </div>
    <div class="field">
      <label class="required" for="email">{{t 'Email'}}</label>
      {{input type='text' name='email' value=buyer.email}}
    </div>
    <h4 class="ui horizontal divider header">
        <i class="ticket icon"></i>
        {{t 'Ticket Holder\'s Information'}}
    </h4>
    {{#each holders as |holder index|}}
      <div class="inline field">
        <i class="user icon"></i>
         <label>{{t 'Ticket Holder '}}{{inc index}}</label>
      </div>
      <div class="field">
        <label class="required" for="firstname">{{t 'First Name'}}</label>
        {{input type='text' name=(concat 'first_name_' index) value=holder.firstName}}
      </div>
      <div class="field">
        <label class="required" for="lastname">{{t 'Last Name'}}</label>
        {{input type='text' name=(concat 'last_name_' index) value=holder.lastName}}
      </div>
      <div class="field">
        <label class="required" for="email">{{t 'Email'}}</label>
        {{input type='text' name=(concat 'email_' index) value=holder.email}}
      </div>
      <div class="field">
        {{ui-checkbox label=(t 'Same as Ticket Buyer') checked=holder.sameAsBuyer onChange=(action 'fillHolderData' holder)}}
      </div>
    {{/each}}
    <p>
      {{t 'By clicking "Pay Now", I acknowledge that I have read and agree with the Open Event terms of services and privacy policy.'}}
    </p>
    <div class="center aligned">
      <button type="submit" class="ui teal submit button">{{t 'Pay Now'}}</button>
    </div>
  </div>
</form>

 

The complete code for the form can be seen here.

In the above code, we have used Semantic UI elements like button, input, label, icon, header and modules like dropdown, checkbox to create the basic structure of the form.

The form is created using the Semantic markup. Along with semantic UI collection “form”, the segment element has been used to create the grouping of similar content like we have a timer and its related description that after 10 minutes the reservation will no longer be held are put together in a segment where they are arranged using semantic UI view “statistic”. Due to the vastness of semantic UI, all the styling has been done using it like fields inlining, button styling, segment background coloring etc.

The form is created using the Semantic markup. Along with semantic UI collection “form”, the segment element has been used to create the grouping of similar content like we have a timer and its related description that after 10 minutes the reservation will no longer be held are put together in a segment where they are arranged using semantic UI view “statistic”. Semantic UI elements like button, input, label, icon, header and modules like dropdown, checkbox have been used. Due to the vastness of semantic UI, all the styling has been done using it like fields inlining, button styling, segment background colouring etc.

The page for the above HTML code looks like this:

Image for the order form

Fig. 1: Order Form to purchase a ticket

The complete form can be seen on this link.

Adding form validations

We can also add validation in HTML format but writing the validation in JavaScript file is considered good practice.

Let’s see how we can add validation to fields in Javascript.

  getValidationRules() {
    let firstNameValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your first name')
        }
      ]
    };
    let lastNameValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your last name')
        }
      ]
    };
    let emailValidation = {
      rules: [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your email')
        }
      ]
    };
    let validationRules = {
      inline : true,
      delay  : false,
      on     : 'blur',
      fields : {
        firstName: {
          identifier : 'first_name',
          rules      : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your first name')
            }
          ]
        },
        lastName: {
          identifier : 'last_name',
          rules      : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your last name')
            }
          ]
        },
        email: {
          identifier : 'email',
          rules      : [
            {
              type   : 'email',
              prompt : this.i18n.t('Please enter a valid email address')
            }
          ]
        },
        zipCode: {
          identifier : 'zip_code',
          rules   : [
            {
              type   : 'empty',
              prompt : this.i18n.t('Please enter your zip code')
            }
          ]
        } 
    };

Let’s break this up, first, we have an array of validation rules.

  zipCode: {
     identifier : 'zip_code',
        rules   : [
        {
          type   : 'empty',
          prompt : this.i18n.t('Please enter your zip code')
         }
      ]
   }

The first part zipcode is the identifier in Semantic.

The next bit of the identifier, this can match against either id, name or data-validate attributes on the element. We have here picked up the name which we’re using on our labels.

Next bit of the rules, which is an array of objects defining the type of validation, and the message to prompt the user with.

The second part is the settings:

inline : true,

delay : false,

on : 'blur',

This part says we want validation to occur on blur, delayed and to be inline. This gives us the following effect:

Fig. 2: Order Form after validation

To summarise the post, one can say we have seen here how the form to purchase the event ticket has been designed, coded and styled. The complete form can be seen on this link and the complete code can be seen here. The entire form has been designed in such a way to keep it simple, clear and trustworthy without losing the user interaction.

References:

Continue ReadingForms and their validation using Semantic UI in Open Event Frontend

Diving into the codebase of the Open Event Front-end Project

This post aims to help any new contributor to get acquainted with the code base of the Open Event Front-end project.

The open event front-end is primarily the front-end for the Open Event API server. The project provides the functionality of signing up, add, update and view events details and many other functions to the organisers, speakers and attendees of the event which can be concert, conference, summit or a meetup. The open event front-end project is built on a JavaScript web application framework Ember.js. Ember uses a library Ember data for managing the data in the application and for communicating with server API via endpoints. Ember is a battery included framework which means that it creates all the boilerplate code required to set up the project and create a working web application which can be modified according to our needs.

The open event front-end is primarily the front-end for the Open Event API server. The project provides the functionality of signing up, add, update and view events details and many other functions to the organisers, speakers and attendees of the event which can be concert, conference, summit or a meetup. The open event front-end project is built on a JavaScript web application framework Ember.js. Ember uses a library Ember data for managing the data in the application and for communicating with server API via endpoints. Ember is a battery included framework which means that it creates all the boilerplate code required to set up the project and create a working web application which can be modified according to our needs.

For example: When I created a new project using the command:

$ ember new open-event-frontend

It created a new project open-event-frontend with all the boilerplate code required to set up the project which can be seen below.

create .editorconfig
create .ember-cli
create .eslintrc.js
create .travis.yml
create .watchmanconfig
create README.md
create app/app.js
create app/components/.gitkeep
Installing app
create app/controllers/.gitkeep
create app/helpers/.gitkeep
create app/index.html
create app/models/.gitkeep
create app/resolver.js
create app/router.js
create app/routes/.gitkeep
create app/styles/app.css
create app/templates/application.hbs
create app/templates/components/.gitkeep
create config/environment.js
create config/targets.js
create ember-cli-build.js
create .gitignore
create package.json
create public/crossdomain.xml
create public/robots.txt
create testem.js
create tests/.eslintrc.js
create tests/helpers/destroy-app.js
create tests/helpers/module-for-acceptance.js
create tests/helpers/resolver.js
create tests/helpers/start-app.js
create tests/index.html
create tests/integration/.gitkeep
create tests/test-helper.js
create tests/unit/.gitkeep
create vendor/.gitkeep
NPM: Installed dependencies
Successfully initialized git.

Now if we go inside the project directory we can see the following files and folders have been generated by the Ember-CLI which is nothing but a toolkit to create, develop and build ember application. Ember has a runtime resolver which automatically resolves the code if it’s placed at the conventional location which ember knows.

➜ ~ cd open-event-frontend
➜ open-event-frontend git:(master) ls
app  config  ember-cli-build.js  node_modules  package.json  public  README.md  testem.js  tests  vendor

What do these files and folders contain and what is their role in reference to the project, “Open event front-end”?

Directory structure of open event frontend project

Fig 1: Directory structure of the Open Event Front-end project

Let’s take a look at the folders and files Ember CLI generates.

App: This is the heart of the project. It is responsible for deciding how our application will look and work. This is the place where folders and files for models, components, routes, templates and styles are stored. The majority of our application’s code is written in this folder. The adapter directory contains the application.js file which is responsible for authorising all outgoing API requests. Since our application is an event application so it has various screens which display the list of events, sessions, schedule, speakers, functionality to add, delete, modify the event details etc. Most of the screens have some features in common which can be reused everywhere inside the application which is kept in components directory. The controllers directory contains the files which will be responsible for the front-end behaviour which is not related to the models of our application. For example actions like sharing the event details. The data of the event is fetched by API but when the share functionality has to work is decided by the controller. Models directory helps in mapping the format of data i.e. in which format the data is fetched from the API. As we interact with the application, it moves through many different states/screens using different URLs. The routes directory decides which template will be rendered and which model will be loaded to display the data in the current template. The services directory contains the services which kept on running in the application like authentication service to check whether the current user has logged in or not, translation service to translate the details into some other language other than English which is supported by the app if required. The styles directory contains .scss files for styling of layouts. The template directory contains the layouts for the user interface of the application in form of Handlebar Templates which contains the HTML code which will be rendered on the screen when the template will be called via routes. The utils directory contains all the utility files like the format of date and time, demographic details, event type, type of topics etc.   

Directory structure of App folder

Fig 2: Directory structure of the app folder

Config: It contains files where we can we configure the settings of our application. The environment.js file contains the details like application name and API endpoints and other details required to configure the application. The deploy.js file contains the configurational details about the deployment.

Directory structure of config folder

Fig 3: Directory structure of config folder

Mirage: It contains the files which are required to mock the API server. Since we need to fetch the data from the server so whenever we make a request to get and post the data, mirage will respond to that data. It also contains the file which helps in seeding fake data for the application. Here mocking means creating objects that simulate the behaviour of real objects. The default.js application handles the seeding the fake data but currently, we don’t require that hence it’s empty. The config.js file has the method which sets the API host and namespace of the application.

Directory structure of mirage folder

Fig 4: Directory structure of mirage folder

Node_modules: As we know that Ember is built with Node and uses various node.js modules for functioning. So this directory contains all the files generated from the running the npm package manager which we run at starting while installing and setting up the project on the local device. The package.json file contains all the file maintains the list of npm dependencies for our app.

Public: This directory contains all the assets such as images and fonts related to the application. In the case of our application, to add images apart from the ones that are fetched from the API, they have to be placed here.

Directory structure of public folder

Fig 5: Directory structure of public folder

Translations: Since our application provides various languages support so this directory contains the files to translate the messages.

Directory structure of translations folder

Fig 6: Directory structure of translations folder

Tests: This is the best feature which Ember has provided. We don’t have to generate test they are automatically generated by the Ember-CLI which can be modified according to our requirements. Ember generates three types of test which are Acceptance, Integration and Unit tests. Other than that Ember offers testing for helpers, controllers, routes and models. Test runner of Ember-CLI testem is configured in testem.js. All three types of test have been used in our application.

Directory structure of test folder

Fig 7: Directory structure of test folder

ember-cli-build.js: This file contains the detail how Ember CLI should build our app. In the case of our project, it contains all the metadata such as app imports and other details to build the app.   

Vendor: This directory usually contains all the front-end dependencies (such as JavaScript or CSS) which are not managed by Bower go (which is a package manager for managing components that contain HTML, CSS, JavaScript, fonts). But in the case of our project, we have only kept .gitkeep inside this since we have not included any dependency which Bower doesn’t maintain.

To summarise, this post explains about the content and the role of different files and folders in the directory structure of the Open Event Front-end Project which may help a new contributor to get started by getting a basic understanding of the project.

Continue ReadingDiving into the codebase of the Open Event Front-end Project

Creating nested routes in Open Event Front-end and Navigating them with Tabs via semantic UI – Ember Integration

Semantic UI is a modern development framework which helps build responsive and aesthetically beautiful layouts. While it is a really powerful framework in itself, it additionally offers seamless integrations with some of the other open source frameworks including ember js.

Open Event Front-end is a project of FOSSASIA organisation, which was created with the aim of decoupling the front end and the back end for the open event orga server. It is primarily based on ember JS and uses semantic UI for it’s UI.

Here we will be making a nested route /events/ with /events/live/, events/draft, events/past , events/import as it’s subroutes.

To get started with it, we simply use the ember CLI to generate the routes

$ ember generate route events

Then we go on to generate the successive sub routes as follows

$ ember generate route events/live
$ ember generate route events/past
$ ember generate route events/draft
$ ember generate route events/import

The router.js file should be looking like this now.

this.route('events', function() {
    this.route('live');
    this.route('draft');
    this.route('past');
    this.route('import');
  });

This means that our routes and sub routes are in place. Since we used the ember CLI to generate these routes, the template files for them would have generated automatically. Now these routes exist and we need to write the data in the templates of these routes which will get displayed to the end user.

Since the routes are nested, the content of the parent route can be made available to all the children routes via the outlet in ember js.

Next, we go to the template file of events/ route which is at templates/events.hbs And write the following code to create a menu and use ember integration of semantic UI link-to to link the tabs of the menu with the corresponding correct route. It will take care of selecting the appropriate data for the corresponding route and display it in the correct tab via the outlet

<.div class="row">
  <.div class="sixteen wide column">
    <.div class="ui fluid pointing secondary menu">
      {{#link-to 'events.live' class='item'}}
        {{t 'Live'}}
      {{/link-to}}
      {{#link-to 'events.draft' class='item'}}
        {{t 'Draft'}}
      {{/link-to}}
      {{#link-to 'events.past' class='item'}}
        {{t 'Past'}}
      {{/link-to}}
      {{#link-to 'events.import' class='item'}}
        {{t 'Import'}}
      {{/link-to}}
    <./div>
  <./div>
<./div>
<.div class="ui segment">
  {{outlet}}
<./div>

So finally, we start filling in the data for each of these routes. Let’s fill some dummy data at templates/events/live.hbs

<.div class="row">
  <.div class="sixteen wide column">
    <.table class="ui tablet stackable very basic table">
      <.thead>
        <.tr>
          <.th>{{t 'Name'}}<./th>
          <.th>{{t 'Date'}}<./th>
          <.th>{{t 'Roles'}}<./th>
          <.th>{{t 'Sessions'}}<./th>
          <.th>{{t 'Speakers'}}<./th>
          <.th>{{t 'Tickets'}}<./th>
          <.th>{{t 'Public URL'}}<./th>
          <.th><./th>
        <./tr>
      <./thead>
      <.tbody>
        <.tr>
          <.td>
            <.div class="ui header weight-400">
              <.img src="http://placehold.it/200x200" alt="Event logo" class="ui image">
              Sample Event
            <./div>
          <./td>
          <.td>
            March 18, 2016 - 09:30 AM
            <.br>(to)<.br>
            March 20, 2016 - 05:30 PM
          <./td>
          <.td>
            <.div class="ui ordered list">
              <.div class="item">sample@gmail.com ({{t 'Organizer'}})<./div>
              <.div class="item">sample2@gmail.com ({{t 'Manager'}})<./div>
            <./div>
          <./td>
          <.td>
            <.div class="ui list">
              <.div class="item">{{t 'Drafts'}}: 0<./div>
              <.div class="item">{{t 'Submitted'}}: 0<./div>
              <.div class="item">{{t 'Accepted'}}: 0<./div>
              <.div class="item">{{t 'Confirmed'}}: 0<./div>
              <.div class="item">{{t 'Pending'}}: 0<./div>
              <.div class="item">{{t 'Rejected'}}: 0<./div>
            <./div>
          <./td>
          <.td>
            2
          <./td>
          <.td>
            <.div class="ui bulleted list">
              <.div class="item">{{t 'Premium'}} (12/100)<./div>
              <.div class="item">{{t 'VIP'}} (10/15)<./div>
              <.div class="item">{{t 'Normal'}} (100/200)<./div>
              <.div class="item">{{t 'Free'}} (100/500)<./div>
            <./div>
          <./td>
          <.td>
            <.div class="ui link list">
              <.a class="item" target="_blank" rel="noopener" href="http://nextgen.eventyay.com/e/ecc2001a">
                http://nextgen.eventyay.com/e/ecc2001a
              <./a>
            <./div>
          <./td>
          <.td class="center aligned">
            <.div class="ui vertical compact basic buttons">
              {{#ui-popup content=(t 'Edit event details') class='ui icon button'}}
                <.i class="edit icon"><./i>
              {{/ui-popup}}
              {{#ui-popup content=(t 'View event details') class='ui icon button'}}
                <.i class="unhide icon"><./i>
              {{/ui-popup}}
              {{#ui-popup content=(t 'Delete event') class='ui icon button'}}
                <.i class="trash outline icon"><./i>
              {{/ui-popup}}
            <./div>
          <./td>
        <./tr>
      <./tbody>
    <./table>
  <./div>
<./div>

 Similarly we can fill the required data for each of the routes.And this is it, our nested route is ready. Here is a screenshot what you might expect.

Screenshot highlighting the tabs

Resources

Continue ReadingCreating nested routes in Open Event Front-end and Navigating them with Tabs via semantic UI – Ember Integration

ember.js – the right choice for the Open Event Front-end

With the development of the API server for the Open Event project we needed to decide which framework to choose for the new Open Event front-end. With the plethora of javascript frameworks available, it got really difficult to decide, which one is actually the right choice. Every month a new framework arrives, and the existing ones keep actively updating themselves often. We decided to go with Ember.js. This article covers the emberJS framework and highlights its advantages over others and  demonstrates its usefulness.

EmberJS is an open-source JavaScript application front end framework for creating web applications, and uses Model-View-Controller (MVC) approach. The framework provides universal data binding. It’s focus lies on scalability.

Why is Ember JS great?

Convention over configuration – It does all the heavy lifting.

Ember JS mandates best practices, enforces naming conventions and generates the boilerplate code for the various components and routes itself. This has advantages other than uniformity. It is easier for other developers to join the project and start working right away, instead of spending hours on existing codebase to understand it, as the core structure of all ember apps is similar. To get an ember app started with the basic route, user doesn’t has to do much, ember does all the heavy lifting.

ember new my-app
ember server

After installing this is all it takes to create your app.

Ember CLI

Similar to Ruby on Rails, ember has a powerful CLI. It can be used to generate boiler plate codes for components, routes, tests and much more. Testing is possible via the CLI as well.

ember generate component my-component
ember generate route my-route
ember test

These are some of the examples which show how easy it is to manage the code via the ember CLI.

Tests.Tests.Tests.

Ember JS makes it incredibly easy to use test-first approach. Integration tests, acceptance tests, and unit tests are in built into the framework. And can be generated from the CLI itself, the documentation on them is well written and it’s really easy to customise them.

ember generate acceptance-test my-test

This is all it takes to set up the entire boiler plate for the test, which you can customise

Excellent documentation and guides

Ember JS has one of the best possible documentations available for a framework. The guides are a breeze to follow. It is highly recommended that, if starting out on ember, make the demo app from the official ember Guides. That should be enough to get familiar with ember.

Ember Guides is all you need to get started.

Ember Data

It sports one of the best implemented API data fetching capabilities. Fetching and using data in your app is a breeze. Ember comes with an inbuilt data management library Ember Data.

To generate a data model via ember CLI , all you have to do is

ember generate model my-model

Where is it being used?

Ember has a huge community and is being used all around. This article focuses on it’s salient features via the example of Open Event Orga Server project of FOSSASIA. The organizer server is primarily based on FLASK with jinja2 being used for rendering templates. At the small scale, it was efficient to have both the front end and backend of the server together, but as it grew larger in size with more refined features it became tough to keep track of all the minor edits and customizations of the front end and the code started to become complex in nature. And that gave birth to the new project Open Event Front End which is based on ember JS which will be covered in the next week.

With the orga server being converted into a fully functional API, the back end and the front end will be decoupled thereby making the code much cleaner and easy to understand for the other developers that may wish to contribute in the future. Also, since the new front end is being designed with ember JS, it’s UI will have a lot of enhanced features and enforcing uniformity across the design would be much easier with the help of components in ember. For instance, instead of making multiple copies of the same code, components are used to avoid repetition and ensure uniformity (change in one place will reflect everywhere)

<.div class="{{if isWide 'event wide ui grid row'}}">
  {{#if isWide}}
    {{#unless device.isMobile}}
      <.div class="ui card three wide computer six wide tablet column">
        <.a class="image" href="{{href-to 'public' event.identifier}}">
          {{widgets/safe-image src=(if event.large event.large event.placeholderUrl)}}
        <./a>
      <./div>
    {{/unless}}
  {{/if}}
  <.div class="ui card {{unless isWide 'event fluid' 'thirteen wide computer ten wide tablet sixteen wide mobile column'}}">
    {{#unless isWide}}
      <.a class="image" href="{{href-to 'public' event.identifier}}">
        {{widgets/safe-image src=(if event.large event.large event.placeholderUrl)}}
      <./a>
    {{/unless}}
    <.div class="main content">
      <.a class="header" href="{{href-to 'public' event.identifier}}">
        <.span>{{event.name}}<./span>
      <./a>
      <.div class="meta">
        <.span class="date">
          {{moment-format event.startTime 'ddd, MMM DD HH:mm A'}}
        <./span>
      <./div>
      <.div class="description">
        {{event.shortLocationName}}
      <./div>
    <./div>
    <.div class="extra content small text">
      <.span class="right floated">
        <.i role="button" class="share alternate link icon" {{action shareEvent event}}><./i>
      <./span>
      <.span>
        {{#if isYield}}
          {{yield}}
        {{else}}
          {{#each tags as |tag|}}
            <.a>{{tag}}<./a>
          {{/each}}
        {{/if}}
      <./span>
    <./div>
  <./div>
<./div>

This is a perfect example of the power of components in ember, this is a component for event information display in a card format which in addition to being rendered differently for various screen sizes can act differently based on passed parameters, thereby reducing the redundancy of writing separate components for the same.

Ember is a step forward towards the future of the web. With the help of Babel.js it is possible to write ES6/2015 syntax and not worry about it’s compatibility with the browsers. It will take care of it.

This is perfectly valid and will be compatible with majority of the supported browsers.

actions: {
  submit() {
    this.onValid(()=> {
    });
  }
}

 

Some references used for the blog article:

  1. https://www.codeschool.com/blog/2015/10/26/7-reasons-to-use-ember-js/
  2. https://www.quora.com/What-are-the-advantages-of-using-Ember-js
  3. Official Ember Guides: https://guides.emberjs.com

 
This page/product/etc is unaffiliated with the Ember project. Ember is a trademark of Tilde Inc

Continue Readingember.js – the right choice for the Open Event Front-end