Implementing Sponsors API in Open Event Frontend to Display Sponsors

This article will illustrate how the sponsors have been displayed on the public event page in Open Event Frontend using the Open-Event-Orga sponsors API. As we know that the project is an ember application so, it uses Ember data to consume the API. For fetching the sponsors, we would be mainly focusing on the following API endpoint:

GET /v1/events/{event_identifier}/sponsors

 

In the application we need to display the sponsors is the event’s public page which contains the event details, ticketing information, speaker details etc. along with the list of sponsors so, we will be only concerned with the public/index route in the application. As the sponsors details are nested within the events model so we need to first fetch the event and then from there we need to fetch the sponsors list from the model.

The model to fetch the event details looks like this:

model(params) {
return this.store.findRecord('event', params.event_id, { include: 'social-links' });
}

 

But we can easily observe that there is no parameter related to sponsor in the above model. The reason behind this is the fact that we want our sponsors to be displayed only on the event’s index route rather than displaying them on all the sub routes under public route. To display the sponsors on the public/index route our modal looks like this:

model() {
    const eventDetails = this._super(...arguments);
    return RSVP.hash({
      event   : eventDetails,
      sponsors: eventDetails.get('sponsors')
   });
}

 

As we can see in the above code that we have used this._super(…arguments) to fetch the event details from the event’s public route model which contains all the information related to the event thereby eliminating the need of another API call to fetch sponsors. Now using the ember’s get method we are fetching the sponsors from the eventDetails and putting it inside the sponsors JSON object for using it lately to display sponsors in public/index route.

Till now, we’ve fetched and stored the sponsors now our next task is to display the sponsors list on the event’s index page. The code for displaying the sponsors list on the index page is

{{public/sponsor-list sponsors=model.sponsors}} 

 

The sample user interface without  for displaying the sponsors looks like this:  

Fig. 1: The sample user interface for displaying the sponsors

After replacing the real time data with the sample one, the user interface (UI) for the sponsors looks like this.

Fig. 2: The user interface for sponsors with real time data

The entire code for implementing the sponsors API can be seen here.

To conclude, this is how we efficiently fetched the sponsors list using the Open-Event-Orga sponsors API, ensuring that there is no unnecessary API call to fetch the data.  

Resources:

Continue ReadingImplementing Sponsors API in Open Event Frontend to Display Sponsors

Customizing Serializers in Open Event Front-end

Open Event Front-end project primarily uses Ember Data for API requests, which handles sending the request to correct endpoint, serializing and deserializing the request/response. The Open Event API project uses JSON API specs for implementation of the API, supported by Ember data.

While sending request we might want to customize the payload using a custom serializer. While implementing the Users API in the project, we faced a similiar problem. Let’s see how we solved it.

Creating a serializer for model

A serializer is created for a model, in this example we will create a user serializer for the user model. One important thing that we must keep in mind while creating a serializer is to use same name as that of model, so that ember can map the model with the serializer. We can create a serializer using ember-cli command:

ember g serializer user

 
Customizing serializer

In Open Event Front-end project every serializer extends the base serializer application.js which defines basic serialization like omitting readOnly attributes from the payload.

The user serializer provides more customization for the user model on top of application model. We override the serialize function, which lets us manipulate the payload of the request. We use `snapshot.id` to differentiate between a create request & an update request. If `snapshot.id` exists then it is an update request else it is a create request.

While manipulation user properties like email, contact etc we do not need to pass ‘password’ in the payload. We make use of ‘adapterOptions’ property associated with the ‘save()’ method. If the adapterOptions are associated and the ‘includePassword’ is set then we add ‘password’ attribute to the payload.

import ApplicationSerializer from 'open-event-frontend/serializers/application';
import { pick, omit } from 'lodash';

export default ApplicationSerializer.extend({
  serialize(snapshot, options) {
    const json = this._super(...arguments);
    if (snapshot.id) {
      let attributesToOmit = [];
      if (!snapshot.adapterOptions || !snapshot.adapterOptions.includePassword) {
        attributesToOmit.push('password');
      }
      json.data.attributes = omit(json.data.attributes, attributesToOmit);
    } else if (options && options.includeId) {
      json.data.attributes = pick(json.data.attributes, ['email', 'password']);
    }
    return json;
  }
});

If we want to add the password in the payload we can simply add ‘includePassword’ property to the ‘adapterOptions’ and pass it in the save method for operations like changing the password of the user.

user.save({
  adapterOptions: {
    includePassword: true
  }
})

Thank you for reading the blog, you can check the source code for the example here.
Resources

Learn more about how to customize serializers in ember data here

Continue ReadingCustomizing Serializers in Open Event Front-end

Custom Handlebar Helpers used in Open Event Frontend

In Open Event Frontend, we are using custom handlebars like ‘confirm’, ‘css’, ‘includes’, ‘sanitize’, ‘text-color’, etc. Custom helpers are used to format any quantity for example ‘capitalizing the first letter of a word’, ‘reducing a number’s fractional part’, ‘making a text bold’, etc. Thus, with the help of Custom Helpers we can avoid manipulating data in controllers. We use Custom Helpers in the Handlebars’ braces before the property to be formatted. In this blog, I will be explaining one of the custom helpers used in Open Event Frontend.

Creation of custom helper :

Since ember provides an efficient and easy way to create components, controllers, routes through it’s ember-cli, we can also create helpers through a single command.

ember g helper url-encode

This will generate a helper in our app i.e two files. First one url-encode.js where all of our logic goes for helper and the other one url-encode-test.js where the tests for it are written.

Following are the two files you are going to see once you run above commands.

import Ember from 'ember';

const { Helper } = Ember;

export function urlEncode(params) {
  
}

export default Helper.helper(urlEncode);

      url-encode.js

import { test } from 'ember-qunit';
import moduleForComponent from 'open-event-frontend/tests/helpers/component-helper';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('url-encode', 'helper:url-encode');

test('it renders', function(assert) {
  this.set('inputValue', 'hello world');
  this.render(hbs`{{url-encode inputValue}}`);
  assert.equal(this.$().text().trim(), 'hello%20world');
});

        url-encode-test.js

Now all the logic for the helper goes in url-encode.js. But before that, we pass the helper in the template and pass the params to the url-encode.js to process the data and return it.

Use in template:

<a target="_blank" rel="noopener noreferrer" href="https://www.facebook.com/sharer.php?u={{url-encode event.url}}"></a>

      Fig. Use of helpers

So, basically in the above code, we have used the helper “url-encode” and have passed the parameter “event.url” to it which we are getting from the model. Now we need to get this parameter in the url-encode.js file where we will encode it and return.

Accessing the params in helper:

import Ember from 'ember';

const { Helper } = Ember;

/**
 * Helper to URL encode a string
 * @param params
 * @returns {*}
 */
export function urlEncode(params) {
  if (!params || params.length === 0) {
    return '';
  }
  return encodeURIComponent(params[0]);
}

export default Helper.helper(urlEncode);

The above code shows how we can access the params in the url-encode.js. ‘params’ is an array passed which can be accessed in the function directly. Now we just need to perform the action on the params and return it to the template. Here we are using ‘encodeURIComponent’ method to encode the URL and then returning it.
This is how the helpers work. They are a better way to reduce redundancy and help code structure better.

Resources:

Ember JS Official guide

Blog on DockYard about Helpers by Lauren Tan

Source code:

https://github.com/fossasia/open-event-frontend/blob/development/app/helpers/url-encode.js

https://github.com/fossasia/open-event-frontend/blob/development/tests/integration/helpers/url-encode-test.js

Continue ReadingCustom Handlebar Helpers used in Open Event Frontend

Adding Settings and Contact Info Route to Open Event Frontend

In Open Event Frontend, while dealing with an issue, we had to create the ‘contact-info’ route as a subroute of the ‘settings’ route. We have given the user a facility to update his/her information thereby allowing them to change it whenever they want.

Thus to generate the route, we are using ember cli:

ember g route settings/contact-info

Thus, the above command will generate three files:

  • routes/settings/contact-info.js
  • templates/settings/contact-info.hbs
  • tests/unit/routes/settings/contact-info-test.js

1) contact-info.hbs

In this file, we have a form which we have made a component for easy use. Thus following is the content of the contact-info.hbs file:

{{settings/contact-info-section}}

Thus ultimately, we are having a component called ‘contact-info-section’ which contains our markup for the contact-info form.
To generate the component, we do:

ember g component settings/contact-info-section

This command will generate two files:
1. templates/components/contact-info-section.hbs
2. components/contact-info-section.js

Following is the markup in contact-info-section.hbs:

<form class="ui form" {{action 'submit' on='submit'}} novalidate>
  <div class="field">
    <label>{{t 'Email'}}</label>
    {{input type='email' name='email' value=email}}
  </div>
  <div class="field">
    <label>{{t 'Phone'}}</label>
    {{input type='text' name='phone' value=phone}}
  </div>
  <button class="ui teal button" type="submit">{{t 'Save'}}</button>
</form>

In the form, we are having two fields for inputs ‘Email’ and ‘Phone’ respectively. We are using Ember input helpers so as to achieve easy data binding. The name is used as an identifier for the validation.
We have one submit button at the bottom which saves the information that the user wants to update.

The contact-info-section.js file contains all the validation rules which validate the form when the user submits it. If a user enters any field empty, the form prompts the user with a message. Following is an example of the validation rules for the email field:

email: {
          identifier : 'email',
          rules      : [
            {
              type   : 'empty',
              prompt : this.l10n.t('Please enter your email ID')
            },
            {
              type   : 'email',
              prompt : this.l10n.t('Please enter a valid email ID')
            }
          ]
        }

Similar rules are there for the ‘phone’ field input.

2) contact-info.js
The contact-info.js renders our route. Thus it contains the ‘titletoken’ method which returns the ‘titletoken’ method which returns the page title.

Thus, after doing all the things above, we get the following as a result.

Resources:

Source code: https://github.com/fossasia/open-event-frontend

Continue ReadingAdding Settings and Contact Info Route to Open Event Frontend

Implementing Registration API in Open Event Front-end

In this post I will discuss how I implemented the registration feature in Open Event Front-end using the Open-Event-Orga API. The project uses Ember Data for consumption of the API in the ember application. The front end sends POST request to Open Event Orga Server which verifies and creates the user.

We use a custom serialize method for trimming the request payload of the user model by creating a custom user serializer. Lets see how we did it.

Implementing register API

The register API takes username & password in the payload for a POST request which are validated in the register-form component using the semantic-ui form validation. After validating the inputs from the user we bubble the save action to the controller form the component.

submit() {
  this.onValid(() => {
    this.set('errorMessage', null);
    this.set('isLoading', true);
    this.sendAction('submit');
  });
}

In controller we have `createUser()` action where we send a POST request to the server using the save() method, which returns a promise.

createUser() {
  var user = this.get('model');
  user.save()
    .then(() => {
      this.set('session.newUser', user.get('email'));
      this.set('isLoading', false);
      this.transitionToRoute('login');
    })
    .catch(reason => {
      this.set('isLoading', false);
      if (reason.hasOwnProperty('errors') && reason.errors[0].status === 409) {
        this.set('errorMessage', this.l10n.t('User already exists.'));
      } else {
        this.set('errorMessage', this.l10n.t('An unexpected error occurred.'));
      }
    });
}

The `user.save()` returns a promise, therefore we handle it using a then-catch clause. If the request is successful, it executes the `then` clause where we redirect to the login route. If the request fails we check if the status is 409 which translates to a duplicate entry i.e the user already exists in the server.

Serializing the user model using custom serializer

Ember lets us customise the payload using serializers for models. The serializers have serialize function where we can trim the payload of the model. In the user serializer we check if the request is for record creation using `options.includeId`. If the request is for record creation we trim the payload using the lodash `pick` method and pick only email & password for payload for POST request.

serialize(snapshot, options) {
  const json = this._super(...arguments);
  if (options && options.includeId) {
    json.data.attributes = pick(json.data.attributes, ['email', 'password']);
  }
  return json;
}

Thank you for reading the blog, you can check the source code for the example here.

Resources

Continue ReadingImplementing Registration API in Open Event Front-end

Maintaining Aspect Ratio of Images while Uploading in Open Event Frontend

In Open Event Frontend, we are using the image-upload at many places such as the cover photo of the event on the create event page, also at the system images (in the admin routes) where the user gets to change the image uploaded by him earlier, and also at the ‘profile’ route where the user can change his photo. But at different places, different dimensions of photos are needed since we are keeping standard in Open Event Frontend.

Therefore the image needs to be in a size with the correct ratio at the time of uploading. We are using the cropper component  for achieving this. The cropper is a modal which pops up after the image upload modal so that a user can crop the image according to the aspect ratio kept specific for that purpose. It looks as follows:

While dealing with an issue in Open Event Frontend, we had to have change in aspect ratio for ‘avatar’ images, unlike the other images. So, we had to modify our cropper modal so as to have different aspect ratios for different images when needed.

We solved the above problem as follows:

In our image-modal, we pass the aspect ratio as a parameter. So in our case, we wanted to set the aspect ratio 1:1 for the ‘avatar’ images only. Following is the code snippet of what we wanted:

{{widgets/forms/image-upload
needsCropper=true
label=(t 'Update Image')
id='user_image'
aspectRatio=(if (eq subTopic.name 'avatar') (array 1 1))
icon='photo'
hint=(t 'Select Image')
maxSizeInKb=10000
helpText=(t 'For Cover Photos : 300x150px (2:1 ratio) image.
For Avatar Photos : 150x150px (1:1 ratio) image.')}}

Thus, we passed the ‘aspectRatio’ as a parameter to the ‘image-upload’ modal. The image-upload further calls the cropper modal and passes ‘aspectRatio’.

{{#if needsCropper}}
{{modals/cropper-modal isOpen=cropperModalIsShown imgData=imgData onImageCrop=(action 'imageCropped') aspectRatio=aspectRatio}}
{{/if}}

Thus, we can use the passed param i.e ‘aspectRatio’ in our cropper to modify the logic for the aspect ratio. Following is what we did so as to obtain the aspect Ratio of 1:1 for ‘avatar’ images only. The default aspect ratio for all other images is 2:1.

onVisible() {
let viewPort = {};
let factor = 150;
const aspectRatio = this.getWithDefault('aspectRatio', [2, 1]);
viewPort.width = aspectRatio[0] * factor;
viewPort.height = aspectRatio[1] * factor;
viewPort.type = 'square';
this.$('.content').css('height', '300px');
this.$('img').croppie({
customClass : 'croppie',
viewport : viewPort,
boundary : {
height: 250
}
});
},

As shown above, we have kept a multiplying factor which is fixed. According to the aspect ratio specified, we calculate and set the width and height in the viewport object.

Thus, following is the thing (Aspect Ratio 1:1 ) we achieved for the ‘avatar’ images:


Resources
Official Ember JS guide: https://guides.emberjs.com/v1.10.0/templates/actions/

Blog on making our own modals: http://ember.guru/2014/master-your-modals-in-ember-js

Source code: https://github.com/sumedh123/open-event-frontend/tree/system-images

Continue ReadingMaintaining Aspect Ratio of Images while Uploading in Open Event Frontend

Implementing Tickets API on Open Event Frontend to Display Tickets

This blog article will illustrate how the tickets are displayed on the public event page in Open Event Frontend, using the tickets API. It will also illustrate the use of the add on, ember-data-has-query, and what role it will play in fetching data from various APIs. Our discussion primarily will involve the public/index route. The primary end point of Open Event API with which we are concerned with for fetching tickets for an event is

GET /v1/events/{event_identifier}/tickets

Since there are multiple  routes under public  including public/index, and they share some common event data, it is efficient to make the call for Event on the public route, rather than repeating it for each sub route, so the model for public route is:

model(params) {
return this.store.findRecord('event', params.event_id, { include: 'social-links' });
}

This modal takes care of fetching all the event data, but as we can see, the tickets are not included in the include parameter. The primary reason for this is the fact that the tickets data is not required on each of the public routes, rather it is required for the index route only. However the tickets have a has-many relationship to events, and it is not possible to make a call for them without calling in the entire event data again. This is where a really useful addon, ember-data-has-many-query comes in.

To quote the official documentation,

Ember Data‘s DS.Store supports querying top-level records using the query function.However, DS.hasMany and DS.belongsTo cannot be queried in the same way.This addon provides a way to query has-many and belongs-to relationships

So we can now proceed with the model for public/index route.

model() {
const eventDetails = this._super(...arguments);
return RSVP.hash({
  event   : eventDetails,
  tickets : eventDetails.query('tickets', {
    filter: [
      {
        and: [
          {
            name : 'sales-starts-at',
            op   : 'le',
            val  : moment().toISOString()
          },
          {
            name : 'sales-ends-at',
            op   : 'ge',
            val  : moment().toISOString()
          }
        ]
      }
    ]
  }),

We make use of this._super(…arguments) to use the event data fetched in the model of public route, eliminating the need for a separate API call for the same. Next, the ember-has-many-query add on allows us to query the tickets of the event, and we apply the filters restricting the tickets to only those, whose sale is live.
After the tickets are fetched they are passed onto the ticket list component to display them. We also need to take care of the cases, where there might be no tickets in case the event organiser is using an external ticket URL for ticketing, which can be easily handled via the is-ticketing-enabled property of events. And in case they are not enabled we don’t render the ticket-list component rather a button linked to the external ticket URL is rendered.  In case where ticketing is enabled the various properties which need to be computed such as the total price of tickets based on user input are handled by the ticket-list component itself.

{{#if model.event.isTicketingEnabled}}
  {{public/ticket-list tickets=model.tickets}}
{{else}}
<div class="ui grid">
  <div class="ui row">
      <a href="{{ticketUrl}}" class="ui right labeled blue icon button">
        <i class="ticket icon"></i>
        {{t 'Order tickets'}}
      </a>
  </div>
  <div class="ui row muted text">
      {{t 'You will be taken to '}} {{ticketUrl}} {{t ' to complete the purchase of tickets'}}
  </div>
</div>
{{/if}}

This is the most efficient way to fetch tickets, and also ensures that only the relevant data is passed to the concerned ticket-list component, without making any extra API calls, and it is made possible by the ember-data-has-many-query add on, with very minor changes required in the adapter and the event model. All that is required to do is make the adapter and the event model extend the RestAdapterMixin and ModelMixin provided by the add on, respectively.

Resources

Continue ReadingImplementing Tickets API on Open Event Frontend to Display Tickets

Creating Custom Validation Rules in Open Event Frontend

In the Open Event Frontend, users can create ‘Access codes’ for an event. Creation of access codes has a form located at the ‘tickets/access-codes/create’ which contains multiple form inputs such as ‘Number of Access tickets’, ‘status’, ‘Minimum tickets’, ‘Maximum tickets’, etc. To create an access code, a user has to fill the form. The form is validated at the time of submission. However, it should not happen that sometimes a user fills minimum number of tickets greater than maximum number of tickets. Semantic UI provides inbuilt validation for many inputs like the ‘text’, ‘email’, ‘password’, ‘number’ etc. But in some cases, it may happen that we need custom validation for some inputs before submitting the form.

         Number of tickets

             Min and max tickets

As shown in the above screenshot, the access code form has some inputs like ‘Min’, ‘Max’, ‘Number of access tickets’, etc. Here we need to ensure that the minimum number of tickets should not exceed the maximum number of tickets, also, the maximum number should not be greater than the total tickets, etc. To achieve this, we need to use the custom validation provided by Semantic UI.

To create a custom validation, we need to have a custom rule for it. To ensure the minimum value does not exceed the maximum value of the ticket, we first set up a rule for validation as follows:

min: {
identifier : 'min',
optional : true,
rules : [
{
type : 'number',
prompt : this.l10n.t('Please enter the proper number')
},
{
type : 'checkMaxMin',
prompt : this.l10n.t('Minimum value should not be greater than maximum')
}
]
},

In the above snippet, we introduced a new rule in the ‘min’ validation set of rules. The new rule called ‘checkMaxMin’ has to be defined so that it checks the necessary condition and returns the value desired.

$.fn.form.settings.rules.checkMaxMin = () => {
if (this.get('data.minQuantity') > this.get('data.maxQuantity')) {
return false;
}
return true;
};

 

Above code shows the rule which we defined in to check the required condition. It retrieves the data from the form by ‘this.get’ method and then checks whether the maximum tickets exceed the minimum. If they do, the function returns false, else it returns true. In this way, when a true value is returned, the form accepts the inputs else it rejects. The following screenshots illustrate the same:

In the same way, we can write custom validation for checking whether maximum tickets exceed the total number of tickets. Following is the code snippet and screenshot for the same.

max: {
identifier : 'max',
optional : true,
rules : [
{
type : 'number',
prompt : this.l10n.t('Please enter the proper number')
},
{
type : 'checkMaxMin',
prompt : this.l10n.t('Maximum value should not be less than minimum')
},
{
type : 'checkMaxTotal',
prompt : this.l10n.t('Maximum value should not be greater than number of tickets')
}
]
},

 

$.fn.form.settings.rules.checkMaxTotal = () => {
if (this.get('data.maxQuantity') > this.get('ticketsNumber')) {
return false;
}
return true;
};

Thus, in this way, we can use custom validation for some form inputs when we want to customise the inputs based on our requirements.

Resources:

Continue ReadingCreating Custom Validation Rules in Open Event Frontend

Using Semantic UI Modals in Open Event Frontend

Modals in semantic UI are used to display the content on the current view while temporarily blocking the interaction with the main view. In Open Event Frontend application, we’ve a ‘delete’ button which deletes the published event as soon as the button is pressed making all the data clean. Once the event is deleted by the user, it is not possible to restore it again. We encountered that this can create a whole lot of problem if the button is pressed unintentionally. So we thought of solving this by popping up a dialog box on button click with a warning and asking for user’s confirmation to delete the event. To implement the dialog box, we used semantic UI modals which helped in ensuring that the user correctly enters the name of the event in the given space to ensure that s/he wants to delete the event.

Since we want our modal to be customizable yet reusable so that it can be used anywhere in the project so we made it as the component called ‘event-delete-modal’. To do that we first need to start with the template.

The markup for the event-delete-modal looks like this:

<div class="content">
  <form class="ui form" autocomplete="off" {{action (optional formSubmit) on='submit' preventDefault=true}}>
    <div class="field">
      <div class="label">
        {{t 'Please enter the full name of the event to continue'}}
      </div>
      {{input type='text' name='confirm_name' value=confirmName required=true}}
    </div>
  </form>
</div>
<div class="actions">
  <button type="button" class="ui black button" {{action 'close'}}>
    {{t 'Cancel'}}
  </button>
  <button type="submit" class="ui red button" disabled={{isNameDifferent}} {{action deleteEvent}}>
    {{t 'Delete Event'}}
  </button>
</div>

The complete code for the template can be seen here.

The above code for the modal window is very similar to the codes which we write for creating the main window. We can see that the semantic UI collection “form” has also been used here for creating the form where the user can input the name of the event along with delete and cancel buttons. The delete button remains disabled until the time correct name of the event been written by the user to ensure that user really wants to delete the event. To cancel the modal we have used close callback method of semantic UI modal which itself closes it. Since the ‘isNameDifferent’ action is uniquely associated to this particular modal hence it’s been declared in the ‘event-delete-modal.js’ file.

The code for the  ‘isNameDifferent’ in ‘event-delete-modal.js’ file looks like this.

export default ModalBase.extend({
  isSmall         : true,
  confirmName     : '',
  isNameDifferent : computed('confirmName', function() {
    return this.get('confirmName').toLowerCase() !== this.get('eventName').toLowerCase();
  })
});

The complete code for the.js file can be seen here.

In the above piece of code, we have isSmall variable to ensure that our modal size is small so it can fit for all screen sizes and we have the implementation isNameDifferent() function. We can also notice that our modal is extending the ‘ModelBase’ class which has all the semantic UI modal settings and the callback methods to perform show, hide, close and open actions along with settings which will help modal to look the way we want it to be.  

The modal-base.js class looks like this.

  openObserver: observer('isOpen', function() {
   close() {
     this.set('isOpen', false);
   },
   actions: {
    close() {
      this.close();
    }
  },
  willInitSemantic(settings) {
    const defaultOptions = {
      detachable     : false,
      duration       : testing ? 0 : 200,
      dimmerSettings : {
        dimmerName : `${this.get('elementId')}-modal-dimmer`,
        variation  : 'inverted'
      },
      onHide: () => {
        this.set('isOpen', false);
        if (this.get('onHide')) {
          this.onHide();
        }
      },
      onVisible: () => {
        this.set('isOpen', true);
        this.$('[data-content]').popup({
          inline: true
        });
     }

The complete code for the .js file can be seen here.

In the above code, we can see that at the top we’ve an ‘openObserver’ function where we’re observing the behaviour of the modal and setting the variables according to the behavioural changes. Now, later we’re checking the status of those variables and performing the actions based on their value. For example, to close the modal we have a boolean variable ‘isOpen’ which is set to false now close() action will be called which closes the modal.  Similarly, in ‘willInitSemantic(settings)’ function we’re setting the modal’s setting like the effects, length, the details modal will display on popping out etc.
We’re here overriding the semantic UI moda settings like detachable, dimmerSettings, duration etc along with the callback methods like onHide(), onVisible() etc. to get the required results.

Finally, our event-delete-modal will look something like this.

Fig: Modal to delete the event

So to conclude this post, we can easily say that the modals are of great use. They can solve the purpose of displaying some alert or to input some values without interrupting the flow of the main page depending upon the requirements.

Additional Resources:

Blog post about Awesome Ember.js Form Components of Alex Speller: http://alexspeller.com/simple-forms-with-ember/

Continue ReadingUsing Semantic UI Modals in Open Event Frontend