jibeinc/juice

View on GitHub
src/LocationTextInput/index.js

Summary

Maintainability
A
35 mins
Test Coverage
require('./styles.css');
const inputTmpl = require('./input.tmpl');
const TextInput = require('../TextInput');
const CurrentLocation = require('../CurrentLocation');
const Utils = require('../Utils.js');

/**
 * This TextInput Implementation provides additional UI behaviors to the icon element
 * over the default TextInput class.
 * - If the icon is clicked while the value is empty, the browser's GeoLocation API
 * will default the value with the user's current location
 *
 * @author Naveed Nadjmabadi
 */
class LocationTextInput extends TextInput {
  /**
   * Creates a new LocationTextInput
   * @param {string} el - the selector for the element to attach to
   * @param {object} opts - The options for the component
   * @param {string} opts.currentLocationText - The text to display for "use my current location"
   */
  constructor(el, opts = {}) {
    super(el, opts);

    Object.assign(this, {
      currentLocationText: opts.currentLocationText,
      showLoaderOnCurrentLocation: opts.showLoaderOnCurrentLocation
    });
  }

  /**
   * Gets the current value, and is it has a displayName, finds that
   * @returns {string} The current value
   */
  get() {
    if (Utils.isPlainObject(this.value) && this.value.displayName) {
      return this.value.displayName;
    }

    return super.get();
  }

  /**
   * Sets the value of the LocationTextInput
   * @param {string|object} v - the value to set
   */
  set(v) {

    // If the textInput contains location data
    if (typeof v === 'object') {
      this.value = v;

      if (this.$input) {
        this.$input.val(v.isLocation ? this.currentLocationText : v.displayName);
      }

      this.publish(this.get());
      this.showHideIcon();
    }
    else {
      super.set(v);
    }
  }

  /**
   * Renders the html for the LocationTextInput and its CurrentLocation icon
   */
  renderDom() {
    // the base input
    this.$el.html(inputTmpl(this));
    this.$input = this.$el.find('input');

    this.$icon = this.$el.find('.ui-text-input-icon');

    // adding the CurrentLocation sub-component
    this.locationIcon = new CurrentLocation('.ui-location-icon', {
      showLoaderOnCurrentLocation: this.showLoaderOnCurrentLocation
    });

    this.$locationIcon = this.$el.find('.ui-location-icon');

    this.locationIcon.subscribe((event) => {
      if (event.isLocation) {
        this.set(event);
      }
    });

    this.locationIcon.render();
  }

  /**
   * Shows or hides the icon
   */
  showHideIcon() {
    if (this.$icon) {
      if (this.get()) {
        this.$icon.css('display', 'block')
        this.$locationIcon.css('display', 'none')
      }
      else {
        this.$icon.css('display', 'none')
        this.$locationIcon.css('display', 'block');
      }
    }
  }
}

module.exports = LocationTextInput;