CSC/ECE 517 Spring 2020 - E2014. Refactor datetimepicker.js

From Expertiza_Wiki
Jump to navigation Jump to search

Abstract

Expertiza uses the jquery’s date-time picker widget for setting dates and times on various views. This is absolutely required so that all users select the date and/or time in a specified and fixed format. Instructors need to use it often while setting or modifying deadlines for various assignments in a course. Over the years, different developers used different version and formats of the date-time picker due to which there are inconsistencies across the expertiza project.

Problem Statement

The main problem with the date-time picker is that the widget and the date-time formats used across the expertiza project are not consistent. Moreover, the JQuery based date-time UI widget itself is on version 0.8 which is extremely old and no longer consistent with expertiza's looks and feel. The primary task of the refactor was to find, refactor and make the date-time picker consistent at all places while exploring the possibility of updating the date-time picker to a newer version or completely replacing it by another better widget which works in conjunction with modern javascript libraries.

Problem Solution

The first step in the approach was to explore the current functionality of existing date time picker. We explored the code base to understand the how 'datetimepicker.js' library was used and its respective compatibility. Simultaneously, we also studied other libraries and gems which could provide a consistent and easy alternative. Since the existing library was no longer being maintained (inactive since mid 2015) ([1]), and the new gem 'bootstrap-datetimepicker' provided a relatively recent and easier implementation. So we decided to pick the latter one and replace the older one.

Process

According to our solution, the existing library needed to be replaced by the new gem. The initial exploration phase helped us to extract the files where datetimepicker has been used in the codebase. The gem was included in the GemFile to make it available throughout the project. Further, necessary syntactical changes were made respective to the new gem. Another key point was to realise the use of a specific format at a specific place. For instance, a shorter format was used in pages to make efficient use of space. The following section includes specific files and the changes made in each of them.

Refactors

This section discusses the changes implemented as a part of this refactor

Installing the required gems

Following gems and its dependencies have been added to the GemFile for bundled installation:

This gem packages the bootstrap-datetime-picker for the Rails 3.1+ asset pipeline. It is based on bootstrap3 and requires momentjs as a dependency.

Moment.js is a lightweight javascript date library for parsing, manipulating, and formatting dates. This gems adds the required javascript files to the project which are used by the new Bootstrap3-datetimepicker gem.

Next, the CSS and javascript file provided by the gems need to be included the asset pipeline by including the following in application.js and application.scss file. The screenshots below depict the additions to the respective files:



Refactoring Date-Time Picker widget

The existing date-time picker widget was replaced by the new date-time picker in the following views:

1. Edit and create assignments - app/views/assignments/edit/_due_dates.html.erb
This contains fields to set the submission and review deadlines for different rounds. The existing JQuery call to the date time picker was replaced by the call to the new widget. Following changes were made to the file:
Before:

jQuery('#datetimepicker_' + element_id).datetimepicker({
            dateFormat: 'yy/mm/dd',
            timeFormat: 'HH:mm:ss z',
            controlType: 'select',
            timezoneList: [
                { value: -000, label: 'GMT'},
                { value: -300, label: 'Eastern'},
                { value: -360, label: 'Central' },
                { value: -420, label: 'Mountain' },
                { value: -480, label: 'Pacific' }
            ]
        });

After:

jQuery('#datetimepicker_' + element_id).datetimepicker({
            format: 'YYYY/MM/DD hh:mm z',
            sideBySide: true
        });


2. Topic sign up sheet - app/views/sign_up_sheet/_due_dates.html.erb
This page is used by the instructor to set up the topic sign up page for projects. The form includes a selection of start date and end date for signup. Following changes were made to the file:
Before:

$('.datetimepicker').datetimepicker({
    dateFormat: 'yy/mm/dd',
    timeFormat: 'HH:mm:ss'
});

After:

$('.datetimepicker').datetimepicker({
    format: 'YYYY/MM/DD HH:mm',
    sideBySide: true
});


3. New survey creation - app/views/survey_deployment/new.html.erb
The page contains the form to allow the creation of new surveys. The survey start and end dates can be set using the form. The old code used two separate inline onClick event to call the same DateTime picker. Both the calls were replaced by a single jquery call.

Before:

     <tr>
          <td><label for="start_date">Start Date:</label></td>
          <td class="form-inline">
               <input type="text" id="survey_deployment_start_date" name ="survey_deployment[start_date]" class="form-control width-250" onClick="$('#survey_deployment_start_date').datetimepicker()"/>
          </td>
     </tr>

     <tr>
          <td><label for="end_date">End Date:</label></td>
          <td class="form-inline">
               <input type="text" id="survey_deployment_end_date" name ="survey_deployment[end_date]" class="form-control width-250" 
onClick="$('#survey_deployment_end_date').datetimepicker()"/>
          </td>
     </tr>
</table>

After:

     <tr>
          <td><label for="start_date">Start Date:</label></td>
          <td class="form-inline">
               <input type="text" id="survey_deployment_start_date" name ="survey_deployment[start_date]" class="form-control width-250" />
          </td>
     </tr>

     <tr>
          <td><label for="end_date">End Date:</label></td>
          <td class="form-inline">
               <input type="text" id="survey_deployment_end_date" name ="survey_deployment[end_date]" class="form-control width-250" />
          </td>
     </tr>
</table>
  <script type="text/javascript">
      jQuery('#survey_deployment_start_date, #survey_deployment_end_date').datetimepicker({
          format: 'YYYY/MM/DD HH:mm',
          sideBySide: true
      });
  </script>


4. Version logs - app/views/sign_up_sheet/_due_dates.html.erb
The version logs file which is only accessible to the admins uses the date tie picker to filter the search results using the start and the end date. Following changes were made to the file:

Before:

jQuery('.datetimeklass').datetimepicker({
            dateFormat: 'yy/mm/dd',
            timeFormat: 'HH:mm:ss z',
            controlType: 'select',
            timezoneList: [
                { value: -000, label: 'GMT'},
                { value: -300, label: 'Eastern'},
                { value: -360, label: 'Central' },
                { value: -420, label: 'Mountain' },
                { value: -480, label: 'Pacific' }
            ]
        });

After:

jQuery('.datetimeklass').datetimepicker({
        format: 'YYYY/MM/DD HH:mm z',
        sideBySide: true
    });

Output

The old jquery based date-time picker was replaced by a new modern bootstrap based date-time picker as shown in the pictures below. The new bootstrap date-time picker widget also has different styles which can be implemented by changing the code as per the documentation here.

Old Date-Time Picker


New Date-Time Picker

Testing

Test Plan

This refactor was mainly concerned with the date-time picker widget UI. Thus most of the testing was done manually as automated testing cannot be used to test the widget. After refactoring each of the pages using the date-time widget, rigorous testing was done to check if the date-time picker selected the right date in appropriate formats. Automated testing was performed to test the models and controllers which relied on the date-time picker for its correct functioning. Code climate was used to maintain the code quality and Travis CI build checks were properly monitored for each commit.

Manual Testing

The new date-time picker widget was manually tested for correctness using the following manual steps:
1. Create and edit assignments
Login into instructor account -> Select Manage Assignments -> Click on the plus sign to the right -> Fill in the relevant details -> In the 'due dates' enter the submission and review deadline using the new date time picker widget -> Save -> Check if assignment with proper deadline is being created.

2. New survey creation
Login into instructor account -> Select Manage assignments -> From the list of assignments select an assignment and select the 'assign survey' action-> Fill in the relevant details -> Enter the survey start and end date using the new date time picker widget -> Save -> Check if the survey is created with proper deadline.

3. Version logs
Login to the Admin/Super admin account -> Open the version logs page -> Select the proper date range to filter the results -> Click 'search' -> Check if results are getting filtered according to the dates selected.

RSpec Testing

To the test the datetimepicker.js functionality, Rspec testing on an untested controller using this gem was performed. In versions controller, search functionality uses the new datetimepicker.js gem. This controller is being given access to only admins and super-admins.

The tests check if the datetimepicker.js is correctly used and on the button click the relevant data is returned from database. Also the datetimepicker feature with start date and end date detection should work for both admins and super-admins.






Travis CI Build Testing

Travis-CI Build Test of the beta branch after a refactored function is merged in the beta branch.

Files changed

1. GemFile. (https://github.com/expertiza/expertiza/pull/1694/files#diff-8b7db4d5cc4b8f6dc8feb7030baa2478)
2. GemFile.lock (https://github.com/expertiza/expertiza/pull/1694/files#diff-e79a60dc6b85309ae70a6ea8261eaf95)
3. application.js (https://github.com/expertiza/expertiza/pull/1694/files#diff-a9c3bd311eab80c9ebe6a69830f9ad02)
4. application.scss (https://github.com/expertiza/expertiza/pull/1694/files#diff-f859e2848b07324f808ce1a5ccd9fcba)
5. assignments/edit/_due_dates.html.erb (https://github.com/expertiza/expertiza/pull/1694/files#diff-540fd2bd6c34b48213716b1dd713733a)
6. sign_up_sheet/_due_dates.html.erb (https://github.com/expertiza/expertiza/pull/1694/files#diff-7a2dff6c7ee5e0f3f4af03fc13a51a7a)
7. survey_deployments (https://github.com/expertiza/expertiza/pull/1694/files#diff-d44102ee049545f5ad9a297b7a922e34)
8. _row_header.html.erb (https://github.com/expertiza/expertiza/pull/1694/files#diff-0defadd3dbc65f90ba975eb0ec963ca0)
9. search.html.erb (https://github.com/expertiza/expertiza/pull/1694/files#diff-325adffe6f7b1a0ac7400e12a5d99f3d)
10. factories.rb (https://github.com/expertiza/expertiza/pull/1694/files#diff-3a17ddf9d828caa60f11423f20fb88a9)
11. versions_search_spec.rb (https://github.com/expertiza/expertiza/pull/1694/files#diff-72f04cc00e26505c570aaecbbe103314)
12. list.html.erb (https://github.com/expertiza/expertiza/pull/1694/files#diff-0256edc752068f64fd59dc0c260659db)

Useful Links

Github Repo: https://github.com/SujalAhrodia/expertiza/tree/beta
Pull Request: https://github.com/expertiza/expertiza/pull/1694

Team Information

Project Mentor:
Pratik Abhyankar

Project Members:
Akanksha Bhattacharyya
Sahil Papalkar
Sujal