ministryofjustice/Claim-for-Crown-Court-Defence

View on GitHub
app/webpack/javascripts/modules/Modules.OffenceSearchInput.js

Summary

Maintainability
A
0 mins
Test Coverage
/**
 * OffenceSearchInput
 * A controller to handel search input,
 * state and provide results data
 */

moj.Modules.OffenceSearchInput = {
  // component selector
  el: '.mod-search-input',

  // search input selector
  input: '.fx-input',

  // hidden input to store model value
  model: '.fx-model',

  // clear button selector
  clear: '.fx-clear-search',

  // fee_scheme selector
  feeScheme: '.fx-fee-scheme',

  // delay in miliseconds
  debounce: 500,

  // min input length to trigger search
  minLength: 3,

  // publisher names
  publishers: {
    // API results recieved
    results: '/offence/search/results/'
  },

  // subscriber names
  subscribers: {
    // trigger the API call
    run: '/offence/search/run/',

    // apply filters to the API call
    filter: '/offence/search/filter/'
  },

  init: function () {
    this.$el = $(this.el)
    if (this.$el.length > 0) {
      this.$input = $(this.input)
      this.$model = $(this.model)
      this.$clear = $(this.clear)
      this.$feeScheme = $(this.feeScheme)
      this.bindEvents()
    }
  },

  bindEvents: function () {
    this.clearSearch()
    this.bindSubscribers()
    this.trackUserInput()
  },

  // binding subscribers and callbacks
  bindSubscribers: function () {
    const self = this

    $.subscribe(this.subscribers.run, function () {
      self.runQuery()
    })

    $.subscribe(this.subscribers.filter, function (e, options) {
      self.runQuery(options)
    })
  },

  runQuery: function (options) {
    const self = this

    // dataOptions for the api request
    // defaults, search input and filters
    const dataOptions = {
      // default value
      fee_scheme: this.$feeScheme.val(),

      // Search query text
      search_offence: this.$input.val(),

      // filters are applied
      ...options
    }

    this.query(dataOptions).then(function (data) {
      // showing the clear search button
      self.$clear.removeClass('hidden')

      // publish the response data
      $.publish(self.publishers.results, data)
    })
  },

  query: function (options) {
    const _options = options
    const def = $.Deferred()
    $.ajax({
      type: 'GET',
      url: '/offences',
      data: _options,
      dataType: 'json',
      success: function (results) {
        options.results = results || []
        def.resolve(_options)
      },
      error: function (req, status, err) {
        def.reject(status, err)
      }
    })

    return def.promise()
  },

  // Tracking the user inout and calling the API
  // when required. Uses $.debounce to limit calls

  trackUserInput: function () {
    const self = this
    this.$input.on('keyup', moj.Modules.Debounce.init(function (e) {
      if (self.$input.val().length >= 3) {
        self.runQuery()
      }
    }, 290))
  },

  // clearSearch procedure
  clearSearch: function () {
    const self = this
    self.$clear.on('click', function (e) {
      e.preventDefault()
      self.$clear.addClass('hidden')
      self.$el.find('.fx-input').val('')
      self.$el.find('.fx-model').val('')
      $.publish('/offence/search/clear/')
    })
  }
}