<commit_before>/**
 * Logs Screen
 *
 * Shows all logs
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
'use strict';

const API = require('../api');
const App = require('../app');
const Constants = require('../constants');
const Log = require('../logs/log');
const page = require('page');
const Utils = require('../utils');

class LogsScreen {
  constructor() {
    this.logs = {};
    this.logDescr = null;
    this.start = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    this.end = new Date(Date.now());
    this.refreshThings = this.refreshThings.bind(this);
    this.onWindowResize = this.onWindowResize.bind(this);
    this.toggleCreateLog = this.toggleCreateLog.bind(this);
    this.onCreateLogDeviceSelect = this.onCreateLogDeviceSelect.bind(this);
    this.onCreateLog = this.onCreateLog.bind(this);
    this.hideRemoveDialog = this.hideRemoveDialog.bind(this);
    this.onRemoveConfirm = this.onRemoveConfirm.bind(this);
    window.addEventListener('resize', this.onWindowResize);
  }

  init() {
    this.view = document.getElementById('logs-view');
    this.createLogScreen = document.getElementById('create-log-screen');
    this.createLogHint = document.querySelector('.create-log-hint');
    this.createLogDevice = document.querySelector('.create-log-device');
    this.createLogDevice.addEventListener('change',
                                          this.onCreateLogDeviceSelect);
    this.createLogProperty = document.querySelector('.create-log-property');
    this.createLogSaveButton =
      document.getElementById('create-log-save-button');
    this.createLogSaveButton.addEventListener('click', this.onCreateLog);

    this.createLogButton = document.querySelector('.create-log-button');
    this.createLogButton.addEventListener('click', this.toggleCreateLog);
    this.createLogRetention =
      document.querySelector('.create-log-retention-duration');
    this.logsContainer = this.view.querySelector('.logs');
    this.logsHeader = document.querySelector('.logs-header');
    this.logRemoveDialog = document.getElementById('log-remove-dialog');
    this.logRemoveButton = document.getElementById('log-remove-button');
    this.logRemoveButton.addEventListener('click', this.onRemoveConfirm);
    this.logRemoveName = document.getElementById('log-remove-name');
    this.logRemoveBackButton =
      document.getElementById('log-remove-back-button');
    this.logRemoveBackButton.addEventListener('click', this.hideRemoveDialog);
    this.onWindowResize();
  }

  show(logDescr) {
    this.logDescr = logDescr;
    this.reload();

    App.gatewayModel.unsubscribe(Constants.REFRESH_THINGS, this.refreshThings);
    App.gatewayModel.subscribe(
      Constants.REFRESH_THINGS,
      this.refreshThings,
      true);
  }

  reload() {
    const soloView = !!this.logDescr;

    if (soloView) {
      const menu = [
        // {
        //   listener: this.handleEdit.bind(this),
        //   name: 'Edit',
        //   icon: '/optimized-images/edit-plain.svg',
        // },
        {
          listener: this.handleRemove.bind(this),
          name: 'Remove',
          icon: '/optimized-images/remove.svg',
        },
      ];
      App.buildOverflowMenu(menu);
      App.showOverflowButton();
      this.createLogButton.classList.add('hidden');
    } else {
      App.hideOverflowButton();
      this.createLogButton.classList.remove('hidden');
    }

    fetch(`/logs/.schema`, {headers: API.headers()}).then((res) => {
      return res.json();
    }).then((schema) => {
      this.logsContainer.innerHTML = '';
      for (const id in this.logs) {
        const log = this.logs[id];
        if (log.elt.parentNode) {
          log.elt.parentNode.removeChild(log.elt);
        }
        delete this.logs[id];
      }

      for (const logInfo of schema) {
        let included = true;
        if (soloView) {
          included = logInfo.thing === this.logDescr.thing &&
            logInfo.property === this.logDescr.property;
        }

        if (!included) {
          continue;
        }

        const log = new Log(logInfo.thing, logInfo.property, this.start,
                            this.end, soloView);

        this.logs[logInfo.id] = log;
        this.logsContainer.appendChild(log.elt);
        log.load();
      }
      if (!schema || schema.length === 0) {
        this.createLogHint.classList.remove('hidden');
      } else {
        this.createLogHint.classList.add('hidden');
      }
      this.streamAll();
    }).catch((e) => {
      App.showMessage('Server error: unable to retrieve logs', 5000);
      console.error('Unable to fetch schema', e);
    });
  }

  streamAll() {
    if (this.messageSocket) {
      return;
    }
    const timeBounds = `start=${this.start.getTime()}&end=${this.end.getTime()}`;
    const query = `jwt=${API.jwt}&${timeBounds}`;
    let subPath = '';
    if (this.thing) {
      subPath = `things/${this.thing}/properties/${this.property}`;
    }

    const path = `${App.ORIGIN.replace(/^http/, 'ws')}/logs/${subPath}?${query}`;
    this.messageSocket = new WebSocket(path);

    const onMessage = (msg) => {
      const messages = JSON.parse(msg.data);
      for (const message of messages) {
        if (this.logs.hasOwnProperty(message.id)) {
          this.logs[message.id].addRawPoint(message);
        }
      }
    };

    const cleanup = () => {
      this.messageSocket.removeEventListener('message', onMessage);
      this.messageSocket.removeEventListener('close', cleanup);
      this.messageSocket.removeEventListener('error', cleanup);
      this.messageSocket.close();
      this.messageSocket = null;

      for (const id in this.logs) {
        this.logs[id].redraw();
      }
    };

    this.messageSocket.addEventListener('message', onMessage);
    this.messageSocket.addEventListener('close', cleanup);
    this.messageSocket.addEventListener('error', cleanup);
  }

  refreshThings(things) {
    this.createLogDevice.innerHTML = '';
    this.things = things;
    things.forEach((description, thingId) => {
      const opt = document.createElement('option');
      opt.innerText = description.name;
      opt.value = thingId;
      this.createLogDevice.appendChild(opt);
    });
    this.onCreateLogDeviceSelect();
  }

  onCreateLogDeviceSelect() {
    const thing = this.things.get(this.createLogDevice.value);
    if (!thing) {
      return;
    }

    this.createLogProperty.innerHTML = '';
    for (const propId in thing.properties) {
      const opt = document.createElement('option');
      opt.innerText = thing.properties[propId].title ||
        Utils.capitalize(propId);
      opt.value = propId;
      this.createLogProperty.appendChild(opt);
    }
  }

  toggleCreateLog() {
    this.createLogScreen.classList.toggle('hidden');
  }

  onCreateLog() {
    const dayToMs = 24 * 60 * 60 * 1000;

    fetch('/logs', {
      method: 'POST',
      headers: Object.assign(API.headers(),
                             {'Content-Type': 'application/json'}),
      body: JSON.stringify({
        descr: {
          type: 'property',
          thing: this.createLogDevice.value,
          property: this.createLogProperty.value,
        },
        maxAge: this.createLogRetention.value * dayToMs,
      }),
    }).then((res) => {
      if (res.ok) {
        this.toggleCreateLog();
        this.createLogHint.classList.add('hidden');
        this.reload();
      } else {
        App.showMessage('Server error: unable to create log', 5000);
      }
    });
  }

  onWindowResize() {
  }

  handleEdit() {
  }

  handleRemove() {
    this.logRemoveName.textContent = this.logsHeader.textContent;

    this.logRemoveDialog.classList.remove('hidden');
  }

  hideRemoveDialog() {
    this.logRemoveDialog.classList.add('hidden');
  }

  onRemoveConfirm() {
    this.hideRemoveDialog();
    if (!this.logDescr) {
      console.warn('Ignoring attempt to remove log from logs view');
      return;
    }
    const thing = this.logDescr.thing;
    const property = this.logDescr.property;
    const path = `/logs/things/${thing}/properties/${property}`;
    fetch(path, {
      method: 'DELETE',
      headers: API.headers(),
    }).then((res) => {
      if (!res.ok) {
        App.showMessage('Server error: unable to remove log', 5000);
      } else {
        page('/logs');
      }
    });
  }
}

module.exports = new LogsScreen();
<commit_msg>Properly reset logs title<commit_after>/**
 * Logs Screen
 *
 * Shows all logs
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
'use strict';

const API = require('../api');
const App = require('../app');
const Constants = require('../constants');
const Log = require('../logs/log');
const page = require('page');
const Utils = require('../utils');

class LogsScreen {
  constructor() {
    this.logs = {};
    this.logDescr = null;
    this.start = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    this.end = new Date(Date.now());
    this.refreshThings = this.refreshThings.bind(this);
    this.onWindowResize = this.onWindowResize.bind(this);
    this.toggleCreateLog = this.toggleCreateLog.bind(this);
    this.onCreateLogDeviceSelect = this.onCreateLogDeviceSelect.bind(this);
    this.onCreateLog = this.onCreateLog.bind(this);
    this.hideRemoveDialog = this.hideRemoveDialog.bind(this);
    this.onRemoveConfirm = this.onRemoveConfirm.bind(this);
    window.addEventListener('resize', this.onWindowResize);
  }

  init() {
    this.view = document.getElementById('logs-view');
    this.createLogScreen = document.getElementById('create-log-screen');
    this.createLogHint = document.querySelector('.create-log-hint');
    this.createLogDevice = document.querySelector('.create-log-device');
    this.createLogDevice.addEventListener('change',
                                          this.onCreateLogDeviceSelect);
    this.createLogProperty = document.querySelector('.create-log-property');
    this.createLogSaveButton =
      document.getElementById('create-log-save-button');
    this.createLogSaveButton.addEventListener('click', this.onCreateLog);

    this.createLogButton = document.querySelector('.create-log-button');
    this.createLogButton.addEventListener('click', this.toggleCreateLog);
    this.createLogRetention =
      document.querySelector('.create-log-retention-duration');
    this.logsContainer = this.view.querySelector('.logs');
    this.logsHeader = document.querySelector('.logs-header');
    this.logRemoveDialog = document.getElementById('log-remove-dialog');
    this.logRemoveButton = document.getElementById('log-remove-button');
    this.logRemoveButton.addEventListener('click', this.onRemoveConfirm);
    this.logRemoveName = document.getElementById('log-remove-name');
    this.logRemoveBackButton =
      document.getElementById('log-remove-back-button');
    this.logRemoveBackButton.addEventListener('click', this.hideRemoveDialog);
    this.onWindowResize();
  }

  show(logDescr) {
    this.logDescr = logDescr;
    this.reload();

    App.gatewayModel.unsubscribe(Constants.REFRESH_THINGS, this.refreshThings);
    App.gatewayModel.subscribe(
      Constants.REFRESH_THINGS,
      this.refreshThings,
      true);
  }

  reload() {
    const soloView = !!this.logDescr;

    if (soloView) {
      const menu = [
        // {
        //   listener: this.handleEdit.bind(this),
        //   name: 'Edit',
        //   icon: '/optimized-images/edit-plain.svg',
        // },
        {
          listener: this.handleRemove.bind(this),
          name: 'Remove',
          icon: '/optimized-images/remove.svg',
        },
      ];
      App.buildOverflowMenu(menu);
      App.showOverflowButton();
      this.createLogButton.classList.add('hidden');
    } else {
      App.hideOverflowButton();
      this.createLogButton.classList.remove('hidden');
      this.logsHeader.textContent = 'Logs';
    }

    fetch(`/logs/.schema`, {headers: API.headers()}).then((res) => {
      return res.json();
    }).then((schema) => {
      this.logsContainer.innerHTML = '';
      for (const id in this.logs) {
        const log = this.logs[id];
        if (log.elt.parentNode) {
          log.elt.parentNode.removeChild(log.elt);
        }
        delete this.logs[id];
      }

      for (const logInfo of schema) {
        let included = true;
        if (soloView) {
          included = logInfo.thing === this.logDescr.thing &&
            logInfo.property === this.logDescr.property;
        }

        if (!included) {
          continue;
        }

        const log = new Log(logInfo.thing, logInfo.property, this.start,
                            this.end, soloView);

        this.logs[logInfo.id] = log;
        this.logsContainer.appendChild(log.elt);
        log.load();
      }
      if (!schema || schema.length === 0) {
        this.createLogHint.classList.remove('hidden');
      } else {
        this.createLogHint.classList.add('hidden');
      }
      this.streamAll();
    }).catch((e) => {
      App.showMessage('Server error: unable to retrieve logs', 5000);
      console.error('Unable to fetch schema', e);
    });
  }

  streamAll() {
    if (this.messageSocket) {
      return;
    }
    const timeBounds = `start=${this.start.getTime()}&end=${this.end.getTime()}`;
    const query = `jwt=${API.jwt}&${timeBounds}`;
    let subPath = '';
    if (this.thing) {
      subPath = `things/${this.thing}/properties/${this.property}`;
    }

    const path = `${App.ORIGIN.replace(/^http/, 'ws')}/logs/${subPath}?${query}`;
    this.messageSocket = new WebSocket(path);

    const onMessage = (msg) => {
      const messages = JSON.parse(msg.data);
      for (const message of messages) {
        if (this.logs.hasOwnProperty(message.id)) {
          this.logs[message.id].addRawPoint(message);
        }
      }
    };

    const cleanup = () => {
      this.messageSocket.removeEventListener('message', onMessage);
      this.messageSocket.removeEventListener('close', cleanup);
      this.messageSocket.removeEventListener('error', cleanup);
      this.messageSocket.close();
      this.messageSocket = null;

      for (const id in this.logs) {
        this.logs[id].redraw();
      }
    };

    this.messageSocket.addEventListener('message', onMessage);
    this.messageSocket.addEventListener('close', cleanup);
    this.messageSocket.addEventListener('error', cleanup);
  }

  refreshThings(things) {
    this.createLogDevice.innerHTML = '';
    this.things = things;
    things.forEach((description, thingId) => {
      const opt = document.createElement('option');
      opt.innerText = description.name;
      opt.value = thingId;
      this.createLogDevice.appendChild(opt);
    });
    this.onCreateLogDeviceSelect();
  }

  onCreateLogDeviceSelect() {
    const thing = this.things.get(this.createLogDevice.value);
    if (!thing) {
      return;
    }

    this.createLogProperty.innerHTML = '';
    for (const propId in thing.properties) {
      const opt = document.createElement('option');
      opt.innerText = thing.properties[propId].title ||
        Utils.capitalize(propId);
      opt.value = propId;
      this.createLogProperty.appendChild(opt);
    }
  }

  toggleCreateLog() {
    this.createLogScreen.classList.toggle('hidden');
  }

  onCreateLog() {
    const dayToMs = 24 * 60 * 60 * 1000;

    fetch('/logs', {
      method: 'POST',
      headers: Object.assign(API.headers(),
                             {'Content-Type': 'application/json'}),
      body: JSON.stringify({
        descr: {
          type: 'property',
          thing: this.createLogDevice.value,
          property: this.createLogProperty.value,
        },
        maxAge: this.createLogRetention.value * dayToMs,
      }),
    }).then((res) => {
      if (res.ok) {
        this.toggleCreateLog();
        this.createLogHint.classList.add('hidden');
        this.reload();
      } else {
        App.showMessage('Server error: unable to create log', 5000);
      }
    });
  }

  onWindowResize() {
  }

  handleEdit() {
  }

  handleRemove() {
    this.logRemoveName.textContent = this.logsHeader.textContent;

    this.logRemoveDialog.classList.remove('hidden');
  }

  hideRemoveDialog() {
    this.logRemoveDialog.classList.add('hidden');
  }

  onRemoveConfirm() {
    this.hideRemoveDialog();
    if (!this.logDescr) {
      console.warn('Ignoring attempt to remove log from logs view');
      return;
    }
    const thing = this.logDescr.thing;
    const property = this.logDescr.property;
    const path = `/logs/things/${thing}/properties/${property}`;
    fetch(path, {
      method: 'DELETE',
      headers: API.headers(),
    }).then((res) => {
      if (!res.ok) {
        App.showMessage('Server error: unable to remove log', 5000);
      } else {
        page('/logs');
      }
    });
  }
}

module.exports = new LogsScreen();
<|endoftext|>


<commit_before>(function(){

    xtag.register('widget-Filter', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var spawnCondition, filterTitle, currentFilter,
                    controlWrap = document.createElement('form'),
                    controlRows = [],
                    encodedFilter = document.createElement('input'),
                    applyFilter = document.createElement('input'),
                    filterNameLabel = document.createElement('label'),
                    filterName = document.createElement('input'),
                    saveFilter = document.createElement('button'),
                    chooseFilterLabel = document.createElement('label'),
                    chooseFilter = document.createElement('select'),
                    loadFilter = document.createElement('button'),
                    deleteFilter = document.createElement('button'),
                    loadTarget = document.createElement('input'),
                    deleteTarget = document.createElement('input'),
                    saveLoadFilter = document.createElement('button');

                this.filterConditions = [];
                this.nRows = [];
                this.detectors = ['DANTE', 'DESCANT', 'GRIFFIN', 'PACES', 'SCEPTAR', 'ZDS'];
                this.detectorCodes = ['DA', 'DS', 'GR', 'PA', 'SE', 'ZD'],
                this.filterOptions = ['Singles', 'Coincidences', 'Prescale'];
                this.filterCodes = ['S', 'C', 'P'];

                filterTitle = document.createElement('h1');
                filterTitle.innerHTML = 'Filter Control';
                this.appendChild(filterTitle);
                currentFilter = document.createElement('h3');
                currentFilter.setAttribute('id', 'currentFilter');
                this.appendChild(currentFilter);

                this.conditionWrap = document.createElement('form');
                this.conditionWrap.setAttribute('id', 'conditionWrap');
                this.conditionWrap.onchange = function(){
                    this.dumpFilterName();
                }.bind(this);
                this.appendChild(this.conditionWrap);

                this.spawnFilterCondition();

                spawnCondition = document.createElement('button');
                spawnCondition.innerHTML = 'OR new condition';
                spawnCondition.setAttribute('class', 'stdin');
                spawnCondition.setAttribute('id', 'spawnCondition')
                spawnCondition.onclick = this.spawnFilterCondition.bind(this);
                this.appendChild(spawnCondition);

                controlWrap.setAttribute('class', 'filterControl summary');
                controlWrap.setAttribute('id', 'filterDefinitionForm');
                controlWrap.setAttribute('method', 'POST');
                controlWrap.setAttribute('action', 'registerFilter');
                this.appendChild(controlWrap);

                controlRows[0] = document.createElement('span')
                controlWrap.appendChild(controlRows[0]);

                encodedFilter.setAttribute('type', 'text');
                encodedFilter.setAttribute('id', 'encodedFilter');
                encodedFilter.setAttribute('style', 'display:none');
                encodedFilter.setAttribute('name', 'filterString');
                controlRows[0].appendChild(encodedFilter);

                applyFilter.setAttribute('type', 'checkbox');
                applyFilter.setAttribute('id', 'applyFilter');
                applyFilter.setAttribute('style', 'display:none');
                applyFilter.setAttribute('name', 'applyFilter');
                controlRows[0].appendChild(applyFilter);

                filterNameLabel.innerHTML = 'Filter Name:';
                filterName.setAttribute('class', 'stdin');
                filterName.setAttribute('type', 'text');
                filterName.setAttribute('id', 'filterName');
                filterName.setAttribute('name', 'filterName');
                filterName.setAttribute('pattern', '^[\\S]*$');
                filterName.setAttribute('required', true);
                controlRows[0].appendChild(filterNameLabel);
                controlRows[0].appendChild(filterName);

                saveFilter.setAttribute('class', 'stdin');
                saveFilter.innerHTML = 'Save Filter Definition';
                saveFilter.onclick = this.registerNewFilter.bind(this);
                controlRows[0].appendChild(saveFilter);

                saveLoadFilter.setAttribute('class', 'stdin');
                saveLoadFilter.innerHTML = 'Save & Apply Filter Definition';
                saveLoadFilter.onclick = function(){
                    this.registerNewFilter();
                    document.getElementById('applyFilter').checked = true;
                }.bind(this);
                controlRows[0].appendChild(saveLoadFilter);

                controlRows[1] = document.createElement('span');
                controlWrap.appendChild(controlRows[1]);

                chooseFilterLabel.innerHTML = 'Load / Delete Filter:'
                controlRows[1].appendChild(chooseFilterLabel);
                chooseFilter.setAttribute('class', 'stdin');
                chooseFilter.setAttribute('id', 'filterList');
                controlRows[1].appendChild(chooseFilter);

                loadTarget.setAttribute('type', 'text');
                loadTarget.setAttribute('name', 'loadTarget');
                loadTarget.setAttribute('id', 'loadTarget');
                loadTarget.setAttribute('value', 'null');
                loadTarget.setAttribute('style', 'display:none');
                controlRows[1].appendChild(loadTarget);
                loadFilter.setAttribute('class', 'stdin');
                loadFilter.innerHTML = 'Load'
                loadFilter.onclick = function(){
                    document.getElementById('loadTarget').value = selected('filterList')
                }
                controlRows[1].appendChild(loadFilter);

                deleteTarget.setAttribute('type', 'text');
                deleteTarget.setAttribute('name', 'deleteTarget');
                deleteTarget.setAttribute('id', 'deleteTarget');
                deleteTarget.setAttribute('value', 'null');
                deleteTarget.setAttribute('style', 'display:none');
                controlRows[1].appendChild(deleteTarget);
                deleteFilter.setAttribute('class', 'stdin');
                deleteFilter.innerHTML = 'Delete'
                deleteFilter.onclick = function(){
                    document.getElementById('deleteTarget').value = selected('filterList')
                }
                controlRows[1].appendChild(deleteFilter);

                XHR('http://'+this.MIDAS+'/?cmd=jcopy&odb=/Filter&encoding=json-nokeys', this.registerFilterODB.bind(this));
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'spawnFilterCondition' : function(){
                var newCondition = document.createElement('div'),
                    leftTab = document.createElement('div'),
                    filterContent = document.createElement('div'),
                    conditionTable = document.createElement('table'),
                    addNewRow = document.createElement('button'),
                    deleteCondition = document.createElement('button'),
                    index = this.filterConditions.length;

                newCondition.setAttribute('id', 'filterCondition' + index);
                newCondition.setAttribute('class', 'filterCondition');
                this.conditionWrap.appendChild(newCondition);

                leftTab.setAttribute('id', 'leftTab' + index);
                leftTab.setAttribute('class', 'leftTab');
                leftTab.innerHTML = 'OR';
                newCondition.appendChild(leftTab);

                filterContent.setAttribute('id', 'filterContent' + index);
                filterContent.setAttribute('class', 'filterContent');
                newCondition.appendChild(filterContent)

                conditionTable.setAttribute('id', 'filterTable'+index);
                conditionTable.setAttribute('class', 'filterTable');
                filterContent.appendChild(conditionTable);

                addNewRow.setAttribute('id', 'addNewRow' + index);
                addNewRow.setAttribute('class', 'stdin lightButton');
                addNewRow.innerHTML = 'AND new condition';
                addNewRow.onclick = this.addNewRow.bind(this, index);
                filterContent.appendChild(addNewRow);

                deleteCondition.setAttribute('id', 'deleteCondition' + index);
                deleteCondition.setAttribute('class', 'stdin lightButton');
                deleteCondition.innerHTML = 'Delete This Block';
                deleteCondition.onclick = this.deleteOrBlock.bind(this, index);
                filterContent.appendChild(deleteCondition);

                this.nRows[index] = 0;
                addNewRow.onclick();

                this.filterConditions.push(newCondition);
            },

            'addNewRow' : function(index){
                var row, cell,
                    detectorSelect, detectorOption,
                    filterSelect, filterOption,
                    optionConfigWrap, optionConfigLabel, optionConfigInput,
                    deleteRow,
                    i,
                    rowIndex = this.nRows[index]

                row = document.createElement('tr');
                row.setAttribute('id', 'filterRow' + index + rowIndex);
                document.getElementById('filterTable' + index).appendChild(row);

                cell = document.createElement('td');
                cell.innerHTML = 'AND';
                row.appendChild(cell);

                cell = document.createElement('td');
                row.appendChild(cell);
                detectorSelect = document.createElement('select');
                detectorSelect.setAttribute('id', 'detectorSelect'+index+rowIndex);
                detectorSelect.setAttribute('class', 'stdin');
                for(i=0; i<this.detectors.length; i++){
                    detectorOption = document.createElement('option');
                    detectorOption.value = this.detectorCodes[i];
                    detectorOption.innerHTML = this.detectors[i];
                    detectorSelect.appendChild(detectorOption);
                }
                cell.appendChild(detectorSelect);

                cell = document.createElement('td');
                row.appendChild(cell);
                filterSelect = document.createElement('select');
                filterSelect.setAttribute('id', 'filterType'+index+rowIndex)
                filterSelect.setAttribute('class', 'stdin');
                filterSelect.onchange = function(idCode){
                    var filterType = selected('filterType'+idCode);

                    this.manageInputCell(filterType, idCode);

                }.bind(this, ''+index+rowIndex);
                for(i=0; i<this.filterOptions.length; i++){
                    filterOption = document.createElement('option');
                    filterOption.value = this.filterCodes[i];
                    filterOption.innerHTML = this.filterOptions[i];
                    filterSelect.appendChild(filterOption);
                }
                cell.appendChild(filterSelect);

                cell = document.createElement('td');
                row.appendChild(cell);
                optionConfigWrap = document.createElement('div');
                optionConfigWrap.setAttribute('id', 'optionConfigWrap'+index+rowIndex);
                optionConfigWrap.setAttribute('class', 'optionConfigWrap hiddenConfig');
                cell.appendChild(optionConfigWrap);
                optionConfigLabel = document.createElement('label');
                optionConfigLabel.setAttribute('id', 'optionConfigLabel'+index+rowIndex);
                optionConfigWrap.appendChild(optionConfigLabel);
                optionConfigInput = document.createElement('input');
                optionConfigInput.setAttribute('id', 'optionConfigInput'+index+rowIndex);
                optionConfigInput.setAttribute('class', 'stdin');
                optionConfigInput.setAttribute('type', 'number');
                optionConfigInput.setAttribute('step', 1);
                optionConfigInput.setAttribute('min', 0);
                optionConfigWrap.appendChild(optionConfigInput);

                cell = document.createElement('td');
                row.appendChild(cell);
                deleteRow = document.createElement('button');
                deleteRow.innerHTML = 'Remove';
                deleteRow.setAttribute('class', 'stdin');
                deleteRow.onclick = this.deleteRow.bind(this, index, ''+index+rowIndex);
                cell.appendChild(deleteRow);

                this.nRows[index]++;

                return false;

            },

            'manageInputCell' : function(filterType, idCode){

                if(filterType == 'S'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap hiddenConfig');
                } else if(filterType == 'C'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap');
                    document.getElementById('optionConfigLabel'+idCode).innerHTML = 'Multiplicity: ';
                    document.getElementById('optionConfigInput'+idCode).setAttribute('value', 2);
                } else if(filterType == 'P'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap');
                    document.getElementById('optionConfigLabel'+idCode).innerHTML = 'Factor: ';
                    document.getElementById('optionConfigInput'+idCode).setAttribute('value', 10);
                }
            },

            'deleteOrBlock' : function(index){
                var block = document.getElementById('filterCondition' + index);
                this.conditionWrap.removeChild(block);

                return false;
            },

            'deleteRow' : function(index, idCode){
                var row = document.getElementById('filterRow'+idCode);
                document.getElementById('filterTable'+index).removeChild(row);
                this.dumpFilterName();
                return false;
            },

            'registerNewFilter' : function(){
                var filterConditions = this.querySelectorAll('div.filterCondition'),
                    tableRows,
                    selects,
                    detector, filter, scale, condition,
                    encoded = [],
                    i,j;

                for(i=0; i<filterConditions.length; i++){
                    tableRows = filterConditions[i].querySelectorAll('tr');
                    if(!tableRows || tableRows.length == 0) continue;
                    encoded[i] = [];

                    for(j=0; j<tableRows.length; j++){
                        selects = tableRows[j].querySelectorAll('select');

                        detector = selected(selects[0].id);
                        filter = selected(selects[1].id);
                        scale = parseInt(tableRows[j].querySelectorAll('input')[0].value, 10);
                        if(!scale) scale = 1;

                        condition = detector + '-' + filter + '-' + scale;

                        encoded[i][j] = condition;

                    }
                }

                document.getElementById('encodedFilter').value = JSON.stringify(encoded);
            },

            'registerFilterODB' : function(responseText){
                var data = JSON.parse(responseText),
                    currentName = data.Current,
                    currentFilter = data.Filters[currentName],
                    filterSelect = document.getElementById('filterList'),
                    filterOptions, key;

                this.filterRecord = data;
                this.presets = [];

                this.loadFilter(currentFilter);
                document.getElementById('filterName').value = currentName;
                document.getElementById('currentFilter').innerHTML = 'Current Active Filter: ' + currentName;

                for(key in data.Filters){
                    filterOptions = document.createElement('option');
                    filterOptions.innerHTML = key;
                    filterOptions.value = key;
                    filterSelect.appendChild(filterOptions);
                    this.presets.push(key);
                }

                filterSelect.value = currentName;
            },

            'loadFilter' : function(currentFilter){
                var orCells = this.querySelectorAll('div.filterCondition'),
                    cellDelete,
                    createOr = document.getElementById('spawnCondition'),
                    currentOr,
                    i, key;

                for(i=0; i<orCells.length; i++){
                    cellDelete = orCells[i].querySelectorAll('button.lightButton')[1]; //TODO fragile - don't ever change that class or loading breaks!
                    cellDelete.onclick();
                }

                for(key in currentFilter){
                    if(key.indexOf('last_written') != -1 ) continue;

                    createOr.onclick();

                    currentOr = this.querySelectorAll('div.filterCondition');
                    currentOr = currentOr[currentOr.length - 1];
                    if(currentFilter[key] instanceof Array){
                        for(i=0; i<currentFilter[key].length; i++){
                            currentOr.querySelectorAll('select')[i*2].value = currentFilter[key][i].slice(0,2);
                            currentOr.querySelectorAll('select')[i*2+1].value = currentFilter[key][i].slice(3,4);
                            currentOr.querySelectorAll('select')[i*2+1].onchange();
                            currentOr.querySelectorAll('input')[i].value = parseInt(currentFilter[key][i].slice(5),10);

                            if(i<currentFilter[key].length-1)
                                currentOr.querySelectorAll('button.lightButton')[0].onclick();
                        }
                    } else {
                        currentOr.querySelectorAll('select')[0].value = currentFilter[key].slice(0,2);
                        currentOr.querySelectorAll('select')[1].value = currentFilter[key].slice(3,4);
                        currentOr.querySelectorAll('select')[1].onchange();
                        currentOr.querySelectorAll('input')[0].value = parseInt(currentFilter[key].slice(5),10);
                    }

                }
            },

            'dumpFilterName' : function(){
                if(this.presets.indexOf(document.getElementById('filterName').value) != -1)
                    document.getElementById('filterName').value = '';
            }
        }
    });

})();<commit_msg>remove filter name on edit<commit_after>(function(){

    xtag.register('widget-Filter', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var spawnCondition, filterTitle, currentFilter,
                    controlWrap = document.createElement('form'),
                    controlRows = [],
                    encodedFilter = document.createElement('input'),
                    applyFilter = document.createElement('input'),
                    filterNameLabel = document.createElement('label'),
                    filterName = document.createElement('input'),
                    saveFilter = document.createElement('button'),
                    chooseFilterLabel = document.createElement('label'),
                    chooseFilter = document.createElement('select'),
                    loadFilter = document.createElement('button'),
                    deleteFilter = document.createElement('button'),
                    loadTarget = document.createElement('input'),
                    deleteTarget = document.createElement('input'),
                    saveLoadFilter = document.createElement('button');

                this.filterConditions = [];
                this.nRows = [];
                this.detectors = ['DANTE', 'DESCANT', 'GRIFFIN', 'PACES', 'SCEPTAR', 'ZDS'];
                this.detectorCodes = ['DA', 'DS', 'GR', 'PA', 'SE', 'ZD'],
                this.filterOptions = ['Singles', 'Coincidences', 'Prescale'];
                this.filterCodes = ['S', 'C', 'P'];

                filterTitle = document.createElement('h1');
                filterTitle.innerHTML = 'Filter Control';
                this.appendChild(filterTitle);
                currentFilter = document.createElement('h3');
                currentFilter.setAttribute('id', 'currentFilter');
                this.appendChild(currentFilter);

                this.conditionWrap = document.createElement('form');
                this.conditionWrap.setAttribute('id', 'conditionWrap');
                this.conditionWrap.onchange = function(){
                    this.dumpFilterName();
                }.bind(this);
                this.appendChild(this.conditionWrap);

                this.spawnFilterCondition();

                spawnCondition = document.createElement('button');
                spawnCondition.innerHTML = 'OR new condition';
                spawnCondition.setAttribute('class', 'stdin');
                spawnCondition.setAttribute('id', 'spawnCondition')
                spawnCondition.onclick = this.spawnFilterCondition.bind(this);
                this.appendChild(spawnCondition);

                controlWrap.setAttribute('class', 'filterControl summary');
                controlWrap.setAttribute('id', 'filterDefinitionForm');
                controlWrap.setAttribute('method', 'POST');
                controlWrap.setAttribute('action', 'registerFilter');
                this.appendChild(controlWrap);

                controlRows[0] = document.createElement('span')
                controlWrap.appendChild(controlRows[0]);

                encodedFilter.setAttribute('type', 'text');
                encodedFilter.setAttribute('id', 'encodedFilter');
                encodedFilter.setAttribute('style', 'display:none');
                encodedFilter.setAttribute('name', 'filterString');
                controlRows[0].appendChild(encodedFilter);

                applyFilter.setAttribute('type', 'checkbox');
                applyFilter.setAttribute('id', 'applyFilter');
                applyFilter.setAttribute('style', 'display:none');
                applyFilter.setAttribute('name', 'applyFilter');
                controlRows[0].appendChild(applyFilter);

                filterNameLabel.innerHTML = 'Filter Name:';
                filterName.setAttribute('class', 'stdin');
                filterName.setAttribute('type', 'text');
                filterName.setAttribute('id', 'filterName');
                filterName.setAttribute('name', 'filterName');
                filterName.setAttribute('pattern', '^[\\S]*$');
                filterName.setAttribute('required', true);
                controlRows[0].appendChild(filterNameLabel);
                controlRows[0].appendChild(filterName);

                saveFilter.setAttribute('class', 'stdin');
                saveFilter.innerHTML = 'Save Filter Definition';
                saveFilter.onclick = this.registerNewFilter.bind(this);
                controlRows[0].appendChild(saveFilter);

                saveLoadFilter.setAttribute('class', 'stdin');
                saveLoadFilter.innerHTML = 'Save & Apply Filter Definition';
                saveLoadFilter.onclick = function(){
                    this.registerNewFilter();
                    document.getElementById('applyFilter').checked = true;
                }.bind(this);
                controlRows[0].appendChild(saveLoadFilter);

                controlRows[1] = document.createElement('span');
                controlWrap.appendChild(controlRows[1]);

                chooseFilterLabel.innerHTML = 'Load / Delete Filter:'
                controlRows[1].appendChild(chooseFilterLabel);
                chooseFilter.setAttribute('class', 'stdin');
                chooseFilter.setAttribute('id', 'filterList');
                controlRows[1].appendChild(chooseFilter);

                loadTarget.setAttribute('type', 'text');
                loadTarget.setAttribute('name', 'loadTarget');
                loadTarget.setAttribute('id', 'loadTarget');
                loadTarget.setAttribute('value', 'null');
                loadTarget.setAttribute('style', 'display:none');
                controlRows[1].appendChild(loadTarget);
                loadFilter.setAttribute('class', 'stdin');
                loadFilter.innerHTML = 'Load'
                loadFilter.onclick = function(){
                    document.getElementById('loadTarget').value = selected('filterList')
                }
                controlRows[1].appendChild(loadFilter);

                deleteTarget.setAttribute('type', 'text');
                deleteTarget.setAttribute('name', 'deleteTarget');
                deleteTarget.setAttribute('id', 'deleteTarget');
                deleteTarget.setAttribute('value', 'null');
                deleteTarget.setAttribute('style', 'display:none');
                controlRows[1].appendChild(deleteTarget);
                deleteFilter.setAttribute('class', 'stdin');
                deleteFilter.innerHTML = 'Delete'
                deleteFilter.onclick = function(){
                    document.getElementById('deleteTarget').value = selected('filterList')
                }
                controlRows[1].appendChild(deleteFilter);

                XHR('http://'+this.MIDAS+'/?cmd=jcopy&odb=/Filter&encoding=json-nokeys', this.registerFilterODB.bind(this));
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'spawnFilterCondition' : function(){
                var newCondition = document.createElement('div'),
                    leftTab = document.createElement('div'),
                    filterContent = document.createElement('div'),
                    conditionTable = document.createElement('table'),
                    addNewRow = document.createElement('button'),
                    deleteCondition = document.createElement('button'),
                    index = this.filterConditions.length;

                newCondition.setAttribute('id', 'filterCondition' + index);
                newCondition.setAttribute('class', 'filterCondition');
                this.conditionWrap.appendChild(newCondition);

                leftTab.setAttribute('id', 'leftTab' + index);
                leftTab.setAttribute('class', 'leftTab');
                leftTab.innerHTML = 'OR';
                newCondition.appendChild(leftTab);

                filterContent.setAttribute('id', 'filterContent' + index);
                filterContent.setAttribute('class', 'filterContent');
                newCondition.appendChild(filterContent)

                conditionTable.setAttribute('id', 'filterTable'+index);
                conditionTable.setAttribute('class', 'filterTable');
                filterContent.appendChild(conditionTable);

                addNewRow.setAttribute('id', 'addNewRow' + index);
                addNewRow.setAttribute('class', 'stdin lightButton');
                addNewRow.innerHTML = 'AND new condition';
                addNewRow.onclick = this.addNewRow.bind(this, index);
                filterContent.appendChild(addNewRow);

                deleteCondition.setAttribute('id', 'deleteCondition' + index);
                deleteCondition.setAttribute('class', 'stdin lightButton');
                deleteCondition.innerHTML = 'Delete This Block';
                deleteCondition.onclick = this.deleteOrBlock.bind(this, index);
                filterContent.appendChild(deleteCondition);

                this.nRows[index] = 0;
                addNewRow.onclick();

                this.filterConditions.push(newCondition);

                this.dumpFilterName();
            },

            'addNewRow' : function(index){
                var row, cell,
                    detectorSelect, detectorOption,
                    filterSelect, filterOption,
                    optionConfigWrap, optionConfigLabel, optionConfigInput,
                    deleteRow,
                    i,
                    rowIndex = this.nRows[index]

                row = document.createElement('tr');
                row.setAttribute('id', 'filterRow' + index + rowIndex);
                document.getElementById('filterTable' + index).appendChild(row);

                cell = document.createElement('td');
                cell.innerHTML = 'AND';
                row.appendChild(cell);

                cell = document.createElement('td');
                row.appendChild(cell);
                detectorSelect = document.createElement('select');
                detectorSelect.setAttribute('id', 'detectorSelect'+index+rowIndex);
                detectorSelect.setAttribute('class', 'stdin');
                for(i=0; i<this.detectors.length; i++){
                    detectorOption = document.createElement('option');
                    detectorOption.value = this.detectorCodes[i];
                    detectorOption.innerHTML = this.detectors[i];
                    detectorSelect.appendChild(detectorOption);
                }
                cell.appendChild(detectorSelect);

                cell = document.createElement('td');
                row.appendChild(cell);
                filterSelect = document.createElement('select');
                filterSelect.setAttribute('id', 'filterType'+index+rowIndex)
                filterSelect.setAttribute('class', 'stdin');
                filterSelect.onchange = function(idCode){
                    var filterType = selected('filterType'+idCode);

                    this.manageInputCell(filterType, idCode);

                }.bind(this, ''+index+rowIndex);
                for(i=0; i<this.filterOptions.length; i++){
                    filterOption = document.createElement('option');
                    filterOption.value = this.filterCodes[i];
                    filterOption.innerHTML = this.filterOptions[i];
                    filterSelect.appendChild(filterOption);
                }
                cell.appendChild(filterSelect);

                cell = document.createElement('td');
                row.appendChild(cell);
                optionConfigWrap = document.createElement('div');
                optionConfigWrap.setAttribute('id', 'optionConfigWrap'+index+rowIndex);
                optionConfigWrap.setAttribute('class', 'optionConfigWrap hiddenConfig');
                cell.appendChild(optionConfigWrap);
                optionConfigLabel = document.createElement('label');
                optionConfigLabel.setAttribute('id', 'optionConfigLabel'+index+rowIndex);
                optionConfigWrap.appendChild(optionConfigLabel);
                optionConfigInput = document.createElement('input');
                optionConfigInput.setAttribute('id', 'optionConfigInput'+index+rowIndex);
                optionConfigInput.setAttribute('class', 'stdin');
                optionConfigInput.setAttribute('type', 'number');
                optionConfigInput.setAttribute('step', 1);
                optionConfigInput.setAttribute('min', 0);
                optionConfigWrap.appendChild(optionConfigInput);

                cell = document.createElement('td');
                row.appendChild(cell);
                deleteRow = document.createElement('button');
                deleteRow.innerHTML = 'Remove';
                deleteRow.setAttribute('class', 'stdin');
                deleteRow.onclick = this.deleteRow.bind(this, index, ''+index+rowIndex);
                cell.appendChild(deleteRow);

                this.nRows[index]++;

                this.dumpFilterName();

                return false;

            },

            'manageInputCell' : function(filterType, idCode){

                if(filterType == 'S'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap hiddenConfig');
                } else if(filterType == 'C'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap');
                    document.getElementById('optionConfigLabel'+idCode).innerHTML = 'Multiplicity: ';
                    document.getElementById('optionConfigInput'+idCode).setAttribute('value', 2);
                } else if(filterType == 'P'){
                    document.getElementById('optionConfigWrap'+idCode).setAttribute('class', 'optionConfigWrap');
                    document.getElementById('optionConfigLabel'+idCode).innerHTML = 'Factor: ';
                    document.getElementById('optionConfigInput'+idCode).setAttribute('value', 10);
                }
            },

            'deleteOrBlock' : function(index){
                var block = document.getElementById('filterCondition' + index);
                this.conditionWrap.removeChild(block);
                this.dumpFilterName();

                return false;
            },

            'deleteRow' : function(index, idCode){
                var row = document.getElementById('filterRow'+idCode);
                document.getElementById('filterTable'+index).removeChild(row);
                this.dumpFilterName();
                return false;
            },

            'registerNewFilter' : function(){
                var filterConditions = this.querySelectorAll('div.filterCondition'),
                    tableRows,
                    selects,
                    detector, filter, scale, condition,
                    encoded = [],
                    i,j;

                for(i=0; i<filterConditions.length; i++){
                    tableRows = filterConditions[i].querySelectorAll('tr');
                    if(!tableRows || tableRows.length == 0) continue;
                    encoded[i] = [];

                    for(j=0; j<tableRows.length; j++){
                        selects = tableRows[j].querySelectorAll('select');

                        detector = selected(selects[0].id);
                        filter = selected(selects[1].id);
                        scale = parseInt(tableRows[j].querySelectorAll('input')[0].value, 10);
                        if(!scale) scale = 1;

                        condition = detector + '-' + filter + '-' + scale;

                        encoded[i][j] = condition;

                    }
                }

                document.getElementById('encodedFilter').value = JSON.stringify(encoded);
            },

            'registerFilterODB' : function(responseText){
                var data = JSON.parse(responseText),
                    currentName = data.Current,
                    currentFilter = data.Filters[currentName],
                    filterSelect = document.getElementById('filterList'),
                    filterOptions, key;

                this.filterRecord = data;
                this.presets = [];

                this.loadFilter(currentFilter);
                document.getElementById('filterName').value = currentName;
                document.getElementById('currentFilter').innerHTML = 'Current Active Filter: ' + currentName;

                for(key in data.Filters){
                    filterOptions = document.createElement('option');
                    filterOptions.innerHTML = key;
                    filterOptions.value = key;
                    filterSelect.appendChild(filterOptions);
                    this.presets.push(key);
                }

                filterSelect.value = currentName;
            },

            'loadFilter' : function(currentFilter){
                var orCells = this.querySelectorAll('div.filterCondition'),
                    cellDelete,
                    createOr = document.getElementById('spawnCondition'),
                    currentOr,
                    i, key;

                for(i=0; i<orCells.length; i++){
                    cellDelete = orCells[i].querySelectorAll('button.lightButton')[1]; //TODO fragile - don't ever change that class or loading breaks!
                    cellDelete.onclick();
                }

                for(key in currentFilter){
                    if(key.indexOf('last_written') != -1 ) continue;

                    createOr.onclick();

                    currentOr = this.querySelectorAll('div.filterCondition');
                    currentOr = currentOr[currentOr.length - 1];
                    if(currentFilter[key] instanceof Array){
                        for(i=0; i<currentFilter[key].length; i++){
                            currentOr.querySelectorAll('select')[i*2].value = currentFilter[key][i].slice(0,2);
                            currentOr.querySelectorAll('select')[i*2+1].value = currentFilter[key][i].slice(3,4);
                            currentOr.querySelectorAll('select')[i*2+1].onchange();
                            currentOr.querySelectorAll('input')[i].value = parseInt(currentFilter[key][i].slice(5),10);

                            if(i<currentFilter[key].length-1)
                                currentOr.querySelectorAll('button.lightButton')[0].onclick();
                        }
                    } else {
                        currentOr.querySelectorAll('select')[0].value = currentFilter[key].slice(0,2);
                        currentOr.querySelectorAll('select')[1].value = currentFilter[key].slice(3,4);
                        currentOr.querySelectorAll('select')[1].onchange();
                        currentOr.querySelectorAll('input')[0].value = parseInt(currentFilter[key].slice(5),10);
                    }

                }
            },

            'dumpFilterName' : function(){
                if(this.presets.indexOf(document.getElementById('filterName').value) != -1)
                    document.getElementById('filterName').value = '';
            }
        }
    });

})();<|endoftext|>


<commit_before>response.content='';
response.headers['Content-Type']='application/json';
var json = response.content.asJSON;

json.country = 'us';
json.postalcode = '95123'
json.elevation = 'Very High';<commit_msg>updated to use javascript object model<commit_after>context.proxyResponse.content='';
context.proxyResponse.headers['Content-Type']='application/json';
var json = context.proxyResponse.content.asJSON;

json.country = 'us';
json.postalcode = '95123'
json.elevation = 'Very High';<|endoftext|>


<commit_before>import React from 'react';
import { View, Text, StyleSheet, Image, TouchableWithoutFeedback } from 'react-native';
import TimeDisplayer from '../components/TimeDisplayer'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 12,
    flexDirection: 'row',
    alignItems: 'flex-end',
    borderColor: '#E3E3E3',
    borderBottomWidth: 1
  },
  text: {
    fontSize: 16,
  },
  middle: {
    flex: 1,
  },
  lastRan: {
    fontSize: 12,
  }
});

const QueryRow = (props) => (
  <TouchableWithoutFeedback
      onPress={props.onPress}>
    <View style={styles.container}>
      <Text style={styles.text}>
        {props.label}
      </Text>
      <View style={styles.middle} />
      <TimeDisplayer style={styles.lastRan} time={props.lastRan}/>
    </View>
  </TouchableWithoutFeedback>
);

export default QueryRow;
<commit_msg>More consistent query row footer<commit_after>import React from 'react';
import { View, Text, StyleSheet, Image, TouchableWithoutFeedback } from 'react-native';
import TimeDisplayer from '../components/TimeDisplayer'

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 12,
    flexDirection: 'column',
    borderColor: '#E3E3E3',
    borderBottomWidth: 1
  },
  text: {
    fontSize: 16,
  },
  middle: {
    flex: 1,
  },
  lastRan: {
    fontSize: 10,
  },
  footer: {
    flexDirection: 'row',
    justifyContent: 'space-between'
  },
});

const QueryRow = (props) => (
  <TouchableWithoutFeedback
      onPress={props.onPress}>
    <View style={styles.container}>
      <Text style={styles.text}>
        {props.label}
      </Text>
      <View style={styles.footer}>
        <View style={styles.middle}/>
        <TimeDisplayer style={styles.lastRan} time={props.lastRan}/>
      </View>
    </View>
  </TouchableWithoutFeedback>
);

export default QueryRow;
<|endoftext|>


<commit_before>#pragma strict

 private var pos : Vector2;
 private var tr : Transform;

 var speed = 4.0;
 var moveUp : KeyCode;
 var moveDown : KeyCode;
 var moveRight : KeyCode;
 var moveLeft : KeyCode;

 var posx = 0;
 var posy = 0;

 function Start() {
     pos = transform.position;
     tr = transform;
 }

 function Update() {

     if (Input.GetKey(moveRight) && tr.position == pos) {
     	if(posx <9)
     	{
     	 posx++;
         pos += Vector2.right;
        }
     }
     else if (Input.GetKeyDown(moveLeft) && tr.position == pos) {
     	if(posx>0)
     	{
     	 posx--;
         pos -= Vector2.right;
        }
     }
     else if (Input.GetKeyDown(moveUp) && tr.position == pos) {
         pos += Vector2.up;
     }
     else if (Input.GetKeyDown(moveDown) && tr.position == pos) {
         pos -= Vector2.up;
     }

     transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * speed);
 }   <commit_msg>Teleport character over reaching an edge on vertical axis<commit_after>#pragma strict

 private var pos : Vector2;
 private var tr : Transform;

 var speed = 4.0;
 var moveUp : KeyCode;
 var moveDown : KeyCode;
 var moveRight : KeyCode;
 var moveLeft : KeyCode;

 var posx = 0;
 var posy = -1;

 var timer = 0.0;

 var player : GameObject;
 var spawnPos : Vector2;

 function Start() {
     pos = transform.position;
     tr = transform;
 }

 function Update() {

 		timer += Time.deltaTime;
 	if(posy == -1)
     {
        pos += Vector2.up;
        posy = 0;
     }
 if(posy == 3)
     {
        pos -= Vector2.up;
        posy = 2;
     }
     if (Input.GetKey(moveRight) && tr.position == pos) {
     	if(posx <9)
     	{
     	 posx++;
         pos += Vector2.right;
        }
     }
     else if (Input.GetKeyDown(moveLeft) && tr.position == pos) {
     	if(posx>0)
     	{
     	 posx--;
         pos -= Vector2.right;
        }
     }
     else if (Input.GetKeyDown(moveUp) && tr.position == pos) {

         pos += Vector2.up;
         posy++;
          Debug.Log(posy);
     }
     else if (Input.GetKeyDown(moveDown) && tr.position == pos) {

         pos -= Vector2.up;
         posy--;
          Debug.Log(posy);
     }

     transform.position = Vector3.MoveTowards(transform.position, pos, Time.deltaTime * speed);

     if(posy == 3 && Input.GetKeyDown(moveUp)){
         posy= -1;
        spawnPos = Vector2(pos.x,-2.003905);
     	var temp_spawn_player = Instantiate(gameObject, spawnPos, Quaternion.identity);
     	Destroy(gameObject,0.1);
     }
     if(posy == -1 && Input.GetKeyDown(moveDown)){
        posy= 3;
        spawnPos = Vector2(pos.x,1.996095);
     	var temp_spawn_player2 = Instantiate(gameObject, spawnPos, Quaternion.identity);
     	Destroy(gameObject,0.1);
     }

 }   <|endoftext|>


<commit_before>define(
  'ephox.alloy.behaviour.Positioning',

  [
    'ephox.alloy.behaviour.Behaviour',
    'ephox.alloy.dom.DomModification',
    'ephox.alloy.positioning.AnchorSchema',
    'ephox.boulder.api.FieldPresence',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.peanut.Fun',
    'ephox.repartee.api.Anchor',
    'ephox.repartee.api.Origins',
    'ephox.repartee.api.SimpleLayout',
    'ephox.sugar.api.Css',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.Location',
    'ephox.sugar.api.Remove',
    'global!window'
  ],

  function (Behaviour, DomModification, AnchorSchema, FieldPresence, FieldSchema, ValueSchema, Fun, Anchor, Origins, SimpleLayout, Css, Insert, Location, Remove, window) {
    var schema = FieldSchema.field(
      'positioning',
      'positioning',
      FieldPresence.asOption(),
      ValueSchema.objOf([
        FieldSchema.defaulted('useFixed', false),
        FieldSchema.option('bounds')
      ])
    );

    var getFixedOrigin = function () {
      return Origins.fixed(0, 0, window.innerWidth, window.innerHeight);
    };

    var getRelativeOrigin = function (component) {
      // This container is the origin.
      var position = Location.absolute(component.element());
      return Origins.relative(position.left(), position.top());
    };

    var getLayout = function (direction, layout) {
      return direction.isRtl() ? [ layout.southwest, layout.southeast, layout.northwest, layout.northeast ] : [ layout.southeast, layout.southwest, layout.northeast, layout.northwest ];
    };

    var placeFixed = function (origin, anchoring, posInfo, placee) {
      console.log('anchoring', anchoring);

      var anchor = Anchor.box(anchoring.anchorBox());

      SimpleLayout.fixed(anchor, placee.element(), anchoring.bubble(), anchoring.layouts(), anchoring.overrides());
    };

    var placeRelative = function (origin, anchoring, posInfo, placee) {

    };

    var place = function (origin, anchoring, posInfo, placee) {
      var f = posInfo.useFixed() ? placeFixed : placeRelative;
      f(origin, anchoring, posInfo, placee);

      /*
      var optBounds = posInfo.bounds();
      var bounds = Origins.viewport(origin, optBounds);

      var bubble = placement.bubble();
      var anchorBox = placement.anchorBox();

      // TODO: Add RTL support.
      var direction = { isRtl: function () { return false; }};

      var preference = getLayout(direction, placement.layouts());

      var options = {
        bounds: bounds,
        origin: origin,
        preference:  preference,
        maxHeightFunction: placement.maxHeightFunction()
      };

      var decision = Callouts.layout(anchorBox, popup, bubble, options);
      Callouts.position(popup, direction, decision, origin);

      Callouts.setClasses(popup, decision);
      Callouts.setHeight(anchorBox, popup, decision, options, bubble);
      */
    };

    var position = function (component, posInfo, anchor, placee) {
      var anchorage = ValueSchema.asStructOrDie('positioning anchor.info', AnchorSchema, anchor);
      var origin = posInfo.useFixed() ? getFixedOrigin() : getRelativeOrigin(component);

      // We set it to be fixed, so that it doesn't interfere with the layout of anything
      // when calculating anchors
      Css.set(placee.element(), 'position', 'fixed');
      // INVESTIGATE: Will hiding the popup cause issues for focus?
      Css.set(placee.element(), 'visibility', 'hidden');

      var placer = anchorage.placement();
      placer(component, posInfo, anchorage, origin).each(function (anchoring) {
        place(origin, anchoring, posInfo, placee);
      });
      Css.remove(placee.element(), 'visibility');
    };

    var addContainer = function (component, posInfo, sandbox) {
      Insert.append(component.element(), sandbox.element());
    };

    var removeContainer = function (component, posInfo, sandbox) {
      Remove.remove(sandbox.element());
    };

    var exhibit = function (info) {
      return info.positioning().fold(function () {
        return DomModification.nu({});
      }, function (posInfo) {
        return DomModification.nu({
          classes: [ ],
          styles: posInfo.useFixed() ? { } : { position: 'relative' }
        });
      });
    };

    var apis = function (info) {
      return {
        position: Behaviour.tryActionOpt('positioning', info, 'position', position),
        addContainer: Behaviour.tryActionOpt('positioning', info, 'addContainer', addContainer),
        removeContainer: Behaviour.tryActionOpt('positioning', info, 'removeContainer', removeContainer)
      };
    };

    return Behaviour.contract({
      name: Fun.constant('positioning'),
      schema: Fun.constant(schema),
      exhibit: exhibit,
      handlers: Fun.constant({ }),
      apis: apis
    });
  }
);<commit_msg>VAN-44: closer to relative and fixed working again<commit_after>define(
  'ephox.alloy.behaviour.Positioning',

  [
    'ephox.alloy.behaviour.Behaviour',
    'ephox.alloy.dom.DomModification',
    'ephox.alloy.positioning.AnchorSchema',
    'ephox.boulder.api.FieldPresence',
    'ephox.boulder.api.FieldSchema',
    'ephox.boulder.api.ValueSchema',
    'ephox.peanut.Fun',
    'ephox.perhaps.Option',
    'ephox.repartee.api.Anchor',
    'ephox.repartee.api.Boxes',
    'ephox.repartee.api.Origins',
    'ephox.repartee.api.SimpleLayout',
    'ephox.sugar.api.Css',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.Location',
    'ephox.sugar.api.Remove',
    'global!window'
  ],

  function (Behaviour, DomModification, AnchorSchema, FieldPresence, FieldSchema, ValueSchema, Fun, Option, Anchor, Boxes, Origins, SimpleLayout, Css, Insert, Location, Remove, window) {
    var schema = FieldSchema.field(
      'positioning',
      'positioning',
      FieldPresence.asOption(),
      ValueSchema.objOf([
        FieldSchema.defaulted('useFixed', false),
        FieldSchema.option('bounds')
      ])
    );

    var getFixedOrigin = function () {
      return Origins.fixed(0, 0, window.innerWidth, window.innerHeight);
    };

    var getRelativeOrigin = function (component) {
      // This container is the origin.
      var position = Location.absolute(component.element());
      return Origins.relative(position.left(), position.top());
    };

    var getLayout = function (direction, layout) {
      return direction.isRtl() ? [ layout.southwest, layout.southeast, layout.northwest, layout.northeast ] : [ layout.southeast, layout.southwest, layout.northeast, layout.northwest ];
    };

    var placeFixed = function (_component, origin, anchoring, posInfo, placee) {
      console.log('anchoring', anchoring);

      var anchor = Anchor.box(anchoring.anchorBox());

      // TODO: Overrides for expanding panel
      SimpleLayout.fixed(anchor, placee.element(), anchoring.bubble(), anchoring.layouts(), anchoring.overrides());
    };

    var placeRelative = function (component, origin, anchoring, posInfo, placee) {
      var bounds = posInfo.bounds().getOr(Boxes.view());

      SimpleLayout.relative(
        anchoring.anchorBox(),
        placee.element(),
        anchoring.bubble(),
        {
          bounds: bounds,
          origin: origin,
          preference: anchoring.layouts(),
          maxHeightFunction: function () { }
        }
      );
    };

    var place = function (component, origin, anchoring, posInfo, placee) {
      var f = posInfo.useFixed() ? placeFixed : placeRelative;
      f(component, origin, anchoring, posInfo, placee);

      /*
      var optBounds = posInfo.bounds();
      var bounds = Origins.viewport(origin, optBounds);

      var bubble = placement.bubble();
      var anchorBox = placement.anchorBox();

      // TODO: Add RTL support.
      var direction = { isRtl: function () { return false; }};

      var preference = getLayout(direction, placement.layouts());

      var options = {
        bounds: bounds,
        origin: origin,
        preference:  preference,
        maxHeightFunction: placement.maxHeightFunction()
      };

      var decision = Callouts.layout(anchorBox, popup, bubble, options);
      Callouts.position(popup, direction, decision, origin);

      Callouts.setClasses(popup, decision);
      Callouts.setHeight(anchorBox, popup, decision, options, bubble);
      */
    };

    var position = function (component, posInfo, anchor, placee) {
      var anchorage = ValueSchema.asStructOrDie('positioning anchor.info', AnchorSchema, anchor);
      var origin = posInfo.useFixed() ? getFixedOrigin() : getRelativeOrigin(component);

      // We set it to be fixed, so that it doesn't interfere with the layout of anything
      // when calculating anchors
      Css.set(placee.element(), 'position', 'fixed');
      // INVESTIGATE: Will hiding the popup cause issues for focus?
      Css.set(placee.element(), 'visibility', 'hidden');

      var placer = anchorage.placement();
      placer(component, posInfo, anchorage, origin).each(function (anchoring) {
        place(component, origin, anchoring, posInfo, placee);
      });
      Css.remove(placee.element(), 'visibility');
    };

    var addContainer = function (component, posInfo, sandbox) {
      Insert.append(component.element(), sandbox.element());
    };

    var removeContainer = function (component, posInfo, sandbox) {
      Remove.remove(sandbox.element());
    };

    var exhibit = function (info) {
      return info.positioning().fold(function () {
        return DomModification.nu({});
      }, function (posInfo) {
        return DomModification.nu({
          classes: [ ],
          styles: posInfo.useFixed() ? { } : { position: 'relative' }
        });
      });
    };

    var apis = function (info) {
      return {
        position: Behaviour.tryActionOpt('positioning', info, 'position', position),
        addContainer: Behaviour.tryActionOpt('positioning', info, 'addContainer', addContainer),
        removeContainer: Behaviour.tryActionOpt('positioning', info, 'removeContainer', removeContainer)
      };
    };

    return Behaviour.contract({
      name: Fun.constant('positioning'),
      schema: Fun.constant(schema),
      exhibit: exhibit,
      handlers: Fun.constant({ }),
      apis: apis
    });
  }
);<|endoftext|>


<commit_before>/*
 * django-selectable UI widget
 * Source: https://bitbucket.org/mlavin/django-selectable
 * Docs: http://django-selectable.readthedocs.org/
 *
 * Depends:
 *   - jQuery 1.4.4+
 *   - jQuery UI 1.8 widget factory
 *
 * Copyright 2010-2012, Mark Lavin
 * BSD License
 *
*/
(function($) {

	$.widget("ui.djselectable", {

        options: {
            removeIcon: "ui-icon-close",
            comboboxIcon: "ui-icon-triangle-1-s",
            prepareQuery: null,
            highlightMatch: true,
            formatLabel: null
        },

        _initDeck: function() {
            /* Create list display for currently selected items for multi-select */
            var self = this;
            var data = $(this.element).data();
            var style = data.selectablePosition || data['selectable-position'] || 'bottom';
            this.deck = $('
').addClass('ui-widget selectable-deck selectable-deck-' + style);
            if (style === 'bottom' || style === 'bottom-inline') {
                $(this.element).after(this.deck);
            } else {
                $(this.element).before(this.deck);
            }
            $(self.hiddenMultipleSelector).each(function(i, input) {
                self._addDeckItem(input);
            });
        },

        _addDeckItem: function(input) {
            /* Add new deck list item from a given hidden input */
            var self = this;
            $('
')
            .text($(input).attr('title'))
            .addClass('selectable-deck-item')
            .appendTo(this.deck)
            .append(
                $('
')
                .addClass('selectable-deck-remove')
                .append(
                    $('')
                    .attr('href', '#')
                    .button({
                        icons: {
                            primary: self.options.removeIcon
                        },
                        text: false
                    })
                    .click(function() {
                        $(input).remove();
                        $(this).closest('li').remove();
                        return false;
                    })
                )
            );
        },

        select: function(item, event) {
            /* Trigger selection of a given item.
            Item should contain two properties: id and value
            Event is the original select event if there is one.
            Event should not be passed if trigger manually.
            */
            var self = this,
            input = this.element;
            $(input).removeClass('ui-state-error');
            if (item) {
                if (self.allowMultiple) {
                    $(input).val("");
                    $(input).data("autocomplete").term = "";
                    if ($(self.hiddenMultipleSelector + '[value=' + item.id + ']').length === 0) {
                        var newInput = $('<input />', {
                            'type': 'hidden',
                            'name': self.hiddenName,
                            'value': item.id,
                            'title': item.value,
                            'data-selectable-type': 'hidden-multiple'
                        });
                        $(input).after(newInput);
                        self._addDeckItem(newInput);
                        return false;
                    }
                } else {
                    $(input).val(item.value);
                    var ui = {item: item};
                    if (typeof(event) == 'undefined' || event.type != "autocompleteselect") {
                        $(input).trigger('autocompleteselect', [ui ]);
                    }
                }
            }
        },

        _create: function() {
            /* Initialize a new selectable widget */
            var self = this,
            input = this.element,
            data = $(input).data();
            self.allowNew = data.selectableAllowNew || data['selectable-allow-new'];
            self.allowMultiple = data.selectableMultiple || data['selectable-multiple'];
            self.textName = $(input).attr('name');
            self.hiddenName = self.textName.replace('_0', '_1');
            self.hiddenSelector = ':input[data-selectable-type=hidden][name=' + self.hiddenName + ']';
            self.hiddenMultipleSelector = ':input[data-selectable-type=hidden-multiple][name=' + self.hiddenName + ']';
            if (self.allowMultiple) {
                self.allowNew = false;
                $(input).val("");
                this._initDeck();
            }

            function dataSource(request, response) {
                /* Custom data source to uses the lookup url with pagination
                Adds hook for adjusting query parameters.
                Includes timestamp to prevent browser caching the lookup. */
                var url = data.selectableUrl || data['selectable-url'];
                var now = new Date().getTime();
                var query = {term: request.term, timestamp: now};
                if (self.options.prepareQuery) {
                    self.options.prepareQuery(query);
                }
                var page = $(input).data("page");
                if (page) {
                    query.page = page;
                }
				$.getJSON(url, query, response);
            }
            // Create base auto-complete lookup
            $(input).autocomplete({
                source: dataSource,
                change: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if ($(input).val() && !ui.item) {
                        if (!self.allowNew) {
                            $(input).addClass('ui-state-error');
                        }
                    }
                    if (self.allowMultiple && !$(input).hasClass('ui-state-error')) {
                        $(input).val("");
                        $(input).data("autocomplete").term = "";
                    }
                },
                select: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if (ui.item && ui.item.page) {
                        // Set current page value
                        $(input).data("page", ui.tem.page);
                        $('.selectable-paginator', self.menu).remove();
                        // Search for next page of results
                        $(input).autocomplete("search");
                        return false;
                    }
                    self.select(ui.item, event);
                }
            }).addClass("ui-widget ui-widget-content ui-corner-all");
            // Override the default auto-complete render.
            $(input).data("autocomplete")._renderItem = function(ul, item) {
                /* Adds hook for additional formatting, allows HTML in the label,
                highlights term matches and handles pagination. */
                var label = item.label;
                if (self.options.formatLabel) {
                    label = self.options.formatLabel(label, item);
                }
                if (self.options.highlightMatch) {
                    var re = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" +
                    $.ui.autocomplete.escapeRegex(this.term) +
                    ")(?![^<>]*>)(?![^&;]+;)", "gi");
                    label = label.replace(re, "$1");
                }
                var li =  $("

")
                    .data("item.autocomplete", item)
                    .append($("").append(label))
                    .appendTo(ul);
                if (item.page) {
                    li.addClass('selectable-paginator');
                }
                return li;
            };
            // Override the default auto-complete suggest.
            $(input).data("autocomplete")._suggest = function(items) {
                /* Needed for handling pagination links */
                var page = $(input).data('page');
                var ul = this.menu.element;
                if (!page) {
                    ul.empty();
                }
                $(input).data('page', null);
                ul.zIndex(this.element.zIndex() + 1);
                this._renderMenu(ul, items);
                this.menu.deactivate();
                this.menu.refresh();
                // size and position menu
                ul.show();
                this._resizeMenu();
                ul.position($.extend({of: this.element}, this.options.position));
                if (this.options.autoFocus) {
                    this.menu.next(new $.Event("mouseover"));
                }
            };
            // Additional work for combobox widgets
            var selectableType = data.selectableType || data['selectable-type'];
            if (selectableType === 'combobox') {
                // Change auto-complete options
                $(input).autocomplete("option", {
                    delay: 0,
                    minLength: 0
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-left ui-combo-input");
                // Add show all items button
                $("<button> </button>").attr("tabIndex", -1).attr("title", "Show All Items")
                .insertAfter($(input))
                .button({
                    icons: {
                        primary: self.options.comboboxIcon
                    },
                    text: false
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-right ui-button-icon ui-combo-button")
                .click(function() {
                    // close if already visible
                    if ($(input).autocomplete("widget").is(":visible")) {
                        $(input).autocomplete("close");
                        return false;
                    }
                    // pass empty string as value to search for, displaying all results
                    $(input).autocomplete("search", "");
                    $(input).focus();
                    return false;
                });
            }
        }
	});
})(jQuery);

function bindSelectables(context) {
    /* Bind all selectable widgets in a given context.
    Automatically called on document.ready.
    Additional calls can be made for dynamically added widgets.
    */
    $(":input[data-selectable-type=text]", context).djselectable();
    $(":input[data-selectable-type=combobox]", context).djselectable();
    $(":input[data-selectable-type=hidden]", context).each(function(i, elem) {
        var hiddenName = $(elem).attr('name');
        var textName = hiddenName.replace('_1', '_0');
        $(":input[name=" + textName + "][data-selectable-url]").bind(
            "autocompletechange autocompleteselect",
            function(event, ui) {
                if (ui.item && ui.item.id) {
                    $(elem).val(ui.item.id);
                } else {
                    $(elem).val("");
                }
            }
        );
    });
}

/* Monkey-patch Django's dynamic formset, if defined */
if (typeof(django) !== "undefined" && typeof(django.jQuery) !== "undefined") {
    if (django.jQuery.fn.formset) {
        var oldformset = django.jQuery.fn.formset;
        django.jQuery.fn.formset = function(opts) {
            var options = $.extend({}, opts);
            var addedevent = function(row) {
                bindSelectables($(row));
            };
            var added = null;
            if (options.added) {
                // Wrap previous added function and include call to bindSelectables
                var oldadded = options.added;
                added = function(row) { oldadded(row); addedevent(row); };
            }
            options.added = added || addedevent;
            return oldformset.call(this, options);
        };
    }
}

/* Monkey-patch Django's dismissAddAnotherPopup(), if defined */
if (typeof(dismissAddAnotherPopup) !== "undefined" && typeof(windowname_to_id) !== "undefined" && typeof(html_unescape) !== "undefined") {
    var django_dismissAddAnotherPopup = dismissAddAnotherPopup;
    dismissAddAnotherPopup = function(win, newId, newRepr) {
        /* See if the popup came from a selectable field.
           If not, pass control to Django's code.
           If so, handle it. */
        var fieldName = windowname_to_id(win.name); /* e.g. "id_fieldname" */
        var field = $('#' + fieldName);
        var multiField = $('#' + fieldName + '_0');
        /* Check for bound selectable */
        var singleWidget = field.data('djselectable');
        var multiWidget = multiField.data('djselectable');
        if (singleWidget || multiWidget) {
            // newId and newRepr are expected to have previously been escaped by
            // django.utils.html.escape.
            var item =  {
                id: html_unescape(newId),
                value: html_unescape(newRepr)
            };
            if (singleWidget) {
                field.djselectable('select', item);
            }
            if (multiWidget) {
                multiField.djselectable('select', item);
            }
            win.close();
        } else {
            /* Not ours, pass on to original function. */
            return django_dismissAddAnotherPopup(win, newId, newRepr);
        }
    };
}

$(document).ready(function() {
    // Bind existing widgets on document ready
    if (typeof(djselectableAutoLoad) === "undefined" || djselectableAutoLoad) {
        bindSelectables('body');
    }
});
<commit_msg>Fixed type preventing "show more results" link in dropdown to work<commit_after>/*
 * django-selectable UI widget
 * Source: https://bitbucket.org/mlavin/django-selectable
 * Docs: http://django-selectable.readthedocs.org/
 *
 * Depends:
 *   - jQuery 1.4.4+
 *   - jQuery UI 1.8 widget factory
 *
 * Copyright 2010-2012, Mark Lavin
 * BSD License
 *
*/
(function($) {

	$.widget("ui.djselectable", {

        options: {
            removeIcon: "ui-icon-close",
            comboboxIcon: "ui-icon-triangle-1-s",
            prepareQuery: null,
            highlightMatch: true,
            formatLabel: null
        },

        _initDeck: function() {
            /* Create list display for currently selected items for multi-select */
            var self = this;
            var data = $(this.element).data();
            var style = data.selectablePosition || data['selectable-position'] || 'bottom';
            this.deck = $('
').addClass('ui-widget selectable-deck selectable-deck-' + style);
            if (style === 'bottom' || style === 'bottom-inline') {
                $(this.element).after(this.deck);
            } else {
                $(this.element).before(this.deck);
            }
            $(self.hiddenMultipleSelector).each(function(i, input) {
                self._addDeckItem(input);
            });
        },

        _addDeckItem: function(input) {
            /* Add new deck list item from a given hidden input */
            var self = this;
            $('
')
            .text($(input).attr('title'))
            .addClass('selectable-deck-item')
            .appendTo(this.deck)
            .append(
                $('
')
                .addClass('selectable-deck-remove')
                .append(
                    $('')
                    .attr('href', '#')
                    .button({
                        icons: {
                            primary: self.options.removeIcon
                        },
                        text: false
                    })
                    .click(function() {
                        $(input).remove();
                        $(this).closest('li').remove();
                        return false;
                    })
                )
            );
        },

        select: function(item, event) {
            /* Trigger selection of a given item.
            Item should contain two properties: id and value
            Event is the original select event if there is one.
            Event should not be passed if trigger manually.
            */
            var self = this,
            input = this.element;
            $(input).removeClass('ui-state-error');
            if (item) {
                if (self.allowMultiple) {
                    $(input).val("");
                    $(input).data("autocomplete").term = "";
                    if ($(self.hiddenMultipleSelector + '[value=' + item.id + ']').length === 0) {
                        var newInput = $('<input />', {
                            'type': 'hidden',
                            'name': self.hiddenName,
                            'value': item.id,
                            'title': item.value,
                            'data-selectable-type': 'hidden-multiple'
                        });
                        $(input).after(newInput);
                        self._addDeckItem(newInput);
                        return false;
                    }
                } else {
                    $(input).val(item.value);
                    var ui = {item: item};
                    if (typeof(event) == 'undefined' || event.type != "autocompleteselect") {
                        $(input).trigger('autocompleteselect', [ui ]);
                    }
                }
            }
        },

        _create: function() {
            /* Initialize a new selectable widget */
            var self = this,
            input = this.element,
            data = $(input).data();
            self.allowNew = data.selectableAllowNew || data['selectable-allow-new'];
            self.allowMultiple = data.selectableMultiple || data['selectable-multiple'];
            self.textName = $(input).attr('name');
            self.hiddenName = self.textName.replace('_0', '_1');
            self.hiddenSelector = ':input[data-selectable-type=hidden][name=' + self.hiddenName + ']';
            self.hiddenMultipleSelector = ':input[data-selectable-type=hidden-multiple][name=' + self.hiddenName + ']';
            if (self.allowMultiple) {
                self.allowNew = false;
                $(input).val("");
                this._initDeck();
            }

            function dataSource(request, response) {
                /* Custom data source to uses the lookup url with pagination
                Adds hook for adjusting query parameters.
                Includes timestamp to prevent browser caching the lookup. */
                var url = data.selectableUrl || data['selectable-url'];
                var now = new Date().getTime();
                var query = {term: request.term, timestamp: now};
                if (self.options.prepareQuery) {
                    self.options.prepareQuery(query);
                }
                var page = $(input).data("page");
                if (page) {
                    query.page = page;
                }
				$.getJSON(url, query, response);
            }
            // Create base auto-complete lookup
            $(input).autocomplete({
                source: dataSource,
                change: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if ($(input).val() && !ui.item) {
                        if (!self.allowNew) {
                            $(input).addClass('ui-state-error');
                        }
                    }
                    if (self.allowMultiple && !$(input).hasClass('ui-state-error')) {
                        $(input).val("");
                        $(input).data("autocomplete").term = "";
                    }
                },
                select: function(event, ui) {
                    $(input).removeClass('ui-state-error');
                    if (ui.item && ui.item.page) {
                        // Set current page value
                        $(input).data("page", ui.item.page);
                        $('.selectable-paginator', self.menu).remove();
                        // Search for next page of results
                        $(input).autocomplete("search");
                        return false;
                    }
                    self.select(ui.item, event);
                }
            }).addClass("ui-widget ui-widget-content ui-corner-all");
            // Override the default auto-complete render.
            $(input).data("autocomplete")._renderItem = function(ul, item) {
                /* Adds hook for additional formatting, allows HTML in the label,
                highlights term matches and handles pagination. */
                var label = item.label;
                if (self.options.formatLabel) {
                    label = self.options.formatLabel(label, item);
                }
                if (self.options.highlightMatch) {
                    var re = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" +
                    $.ui.autocomplete.escapeRegex(this.term) +
                    ")(?![^<>]*>)(?![^&;]+;)", "gi");
                    label = label.replace(re, "$1");
                }
                var li =  $("

")
                    .data("item.autocomplete", item)
                    .append($("").append(label))
                    .appendTo(ul);
                if (item.page) {
                    li.addClass('selectable-paginator');
                }
                return li;
            };
            // Override the default auto-complete suggest.
            $(input).data("autocomplete")._suggest = function(items) {
                /* Needed for handling pagination links */
                var page = $(input).data('page');
                var ul = this.menu.element;
                if (!page) {
                    ul.empty();
                }
                $(input).data('page', null);
                ul.zIndex(this.element.zIndex() + 1);
                this._renderMenu(ul, items);
                this.menu.deactivate();
                this.menu.refresh();
                // size and position menu
                ul.show();
                this._resizeMenu();
                ul.position($.extend({of: this.element}, this.options.position));
                if (this.options.autoFocus) {
                    this.menu.next(new $.Event("mouseover"));
                }
            };
            // Additional work for combobox widgets
            var selectableType = data.selectableType || data['selectable-type'];
            if (selectableType === 'combobox') {
                // Change auto-complete options
                $(input).autocomplete("option", {
                    delay: 0,
                    minLength: 0
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-left ui-combo-input");
                // Add show all items button
                $("<button> </button>").attr("tabIndex", -1).attr("title", "Show All Items")
                .insertAfter($(input))
                .button({
                    icons: {
                        primary: self.options.comboboxIcon
                    },
                    text: false
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-right ui-button-icon ui-combo-button")
                .click(function() {
                    // close if already visible
                    if ($(input).autocomplete("widget").is(":visible")) {
                        $(input).autocomplete("close");
                        return false;
                    }
                    // pass empty string as value to search for, displaying all results
                    $(input).autocomplete("search", "");
                    $(input).focus();
                    return false;
                });
            }
        }
	});
})(jQuery);

function bindSelectables(context) {
    /* Bind all selectable widgets in a given context.
    Automatically called on document.ready.
    Additional calls can be made for dynamically added widgets.
    */
    $(":input[data-selectable-type=text]", context).djselectable();
    $(":input[data-selectable-type=combobox]", context).djselectable();
    $(":input[data-selectable-type=hidden]", context).each(function(i, elem) {
        var hiddenName = $(elem).attr('name');
        var textName = hiddenName.replace('_1', '_0');
        $(":input[name=" + textName + "][data-selectable-url]").bind(
            "autocompletechange autocompleteselect",
            function(event, ui) {
                if (ui.item && ui.item.id) {
                    $(elem).val(ui.item.id);
                } else {
                    $(elem).val("");
                }
            }
        );
    });
}

/* Monkey-patch Django's dynamic formset, if defined */
if (typeof(django) !== "undefined" && typeof(django.jQuery) !== "undefined") {
    if (django.jQuery.fn.formset) {
        var oldformset = django.jQuery.fn.formset;
        django.jQuery.fn.formset = function(opts) {
            var options = $.extend({}, opts);
            var addedevent = function(row) {
                bindSelectables($(row));
            };
            var added = null;
            if (options.added) {
                // Wrap previous added function and include call to bindSelectables
                var oldadded = options.added;
                added = function(row) { oldadded(row); addedevent(row); };
            }
            options.added = added || addedevent;
            return oldformset.call(this, options);
        };
    }
}

/* Monkey-patch Django's dismissAddAnotherPopup(), if defined */
if (typeof(dismissAddAnotherPopup) !== "undefined" && typeof(windowname_to_id) !== "undefined" && typeof(html_unescape) !== "undefined") {
    var django_dismissAddAnotherPopup = dismissAddAnotherPopup;
    dismissAddAnotherPopup = function(win, newId, newRepr) {
        /* See if the popup came from a selectable field.
           If not, pass control to Django's code.
           If so, handle it. */
        var fieldName = windowname_to_id(win.name); /* e.g. "id_fieldname" */
        var field = $('#' + fieldName);
        var multiField = $('#' + fieldName + '_0');
        /* Check for bound selectable */
        var singleWidget = field.data('djselectable');
        var multiWidget = multiField.data('djselectable');
        if (singleWidget || multiWidget) {
            // newId and newRepr are expected to have previously been escaped by
            // django.utils.html.escape.
            var item =  {
                id: html_unescape(newId),
                value: html_unescape(newRepr)
            };
            if (singleWidget) {
                field.djselectable('select', item);
            }
            if (multiWidget) {
                multiField.djselectable('select', item);
            }
            win.close();
        } else {
            /* Not ours, pass on to original function. */
            return django_dismissAddAnotherPopup(win, newId, newRepr);
        }
    };
}

$(document).ready(function() {
    // Bind existing widgets on document ready
    if (typeof(djselectableAutoLoad) === "undefined" || djselectableAutoLoad) {
        bindSelectables('body');
    }
});
<|endoftext|>