modules/ui/fields/roadspeed.js (110 lines of code) (raw):
import { dispatch as d3_dispatch } from 'd3-dispatch';
import { select as d3_select } from 'd3-selection';
import * as countryCoder from '@ideditor/country-coder';
import { uiCombobox } from '../combobox';
import { t } from '../../core/localizer';
import { utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent } from '../../util';
export function uiFieldRoadspeed(field, context) {
var dispatch = d3_dispatch('change');
var unitInput = d3_select(null);
var input = d3_select(null);
var _entityIDs = [];
var _tags;
var _isImperial;
var speedCombo = uiCombobox(context, 'roadspeed');
var unitCombo = uiCombobox(context, 'roadspeed-unit')
.data(['km/h', 'mph'].map(comboValues));
var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120];
var imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
function roadspeed(selection) {
var wrap = selection.selectAll('.form-field-input-wrap')
.data([0]);
wrap = wrap.enter()
.append('div')
.attr('class', 'form-field-input-wrap form-field-input-' + field.type)
.merge(wrap);
input = wrap.selectAll('input.roadspeed-number')
.data([0]);
input = input.enter()
.append('input')
.attr('type', 'text')
.attr('class', 'roadspeed-number')
.attr('id', field.domId)
.call(utilNoAuto)
.call(speedCombo)
.merge(input);
input
.on('change', change)
.on('blur', change);
var loc = combinedEntityExtent().center();
_isImperial = countryCoder.roadSpeedUnit(loc) === 'mph';
unitInput = wrap.selectAll('input.roadspeed-unit')
.data([0]);
unitInput = unitInput.enter()
.append('input')
.attr('type', 'text')
.attr('class', 'roadspeed-unit')
.call(unitCombo)
.merge(unitInput);
unitInput
.on('blur', changeUnits)
.on('change', changeUnits);
function changeUnits() {
_isImperial = utilGetSetValue(unitInput) === 'mph';
utilGetSetValue(unitInput, _isImperial ? 'mph' : 'km/h');
setUnitSuggestions();
change();
}
}
function setUnitSuggestions() {
speedCombo.data((_isImperial ? imperialValues : metricValues).map(comboValues));
utilGetSetValue(unitInput, _isImperial ? 'mph' : 'km/h');
}
function comboValues(d) {
return {
value: d.toString(),
title: d.toString()
};
}
function change() {
var tag = {};
var value = utilGetSetValue(input).trim();
// don't override multiple values with blank string
if (!value && Array.isArray(_tags[field.key])) return;
if (!value) {
tag[field.key] = undefined;
} else if (isNaN(value) || !_isImperial) {
tag[field.key] = context.cleanTagValue(value);
} else {
tag[field.key] = context.cleanTagValue(value + ' mph');
}
dispatch.call('change', this, tag);
}
roadspeed.tags = function(tags) {
_tags = tags;
var value = tags[field.key];
var isMixed = Array.isArray(value);
if (!isMixed) {
if (value && value.indexOf('mph') >= 0) {
value = parseInt(value, 10).toString();
_isImperial = true;
} else if (value) {
_isImperial = false;
}
}
setUnitSuggestions();
utilGetSetValue(input, typeof value === 'string' ? value : '')
.attr('title', isMixed ? value.filter(Boolean).join('\n') : null)
.attr('placeholder', isMixed ? t('inspector.multiple_values') : field.placeholder())
.classed('mixed', isMixed);
};
roadspeed.focus = function() {
input.node().focus();
};
roadspeed.entityIDs = function(val) {
_entityIDs = val;
};
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}
return utilRebind(roadspeed, dispatch, 'on');
}