Files
iD/modules/ui/fields/roadheight.js

227 lines
7.7 KiB
JavaScript

import { dispatch as d3_dispatch } from 'd3-dispatch';
import { select as d3_select } from 'd3-selection';
import * as countryCoder from '@rapideditor/country-coder';
import { uiCombobox } from '../combobox';
import { t, localizer } from '../../core/localizer';
import { utilGetSetValue, utilNoAuto, utilRebind, utilTotalExtent } from '../../util';
import { likelyRawNumberFormat } from './input';
export function uiFieldRoadheight(field, context) {
var dispatch = d3_dispatch('change');
var primaryUnitInput = d3_select(null);
var primaryInput = d3_select(null);
var secondaryInput = d3_select(null);
var secondaryUnitInput = d3_select(null);
var _entityIDs = [];
var _tags;
var _isImperial;
var formatFloat = localizer.floatFormatter(localizer.languageCode());
var parseLocaleFloat = localizer.floatParser(localizer.languageCode());
var primaryUnits = [
{
value: 'm',
title: t('inspector.roadheight.meter'),
},
{
value: 'ft',
title: t('inspector.roadheight.foot'),
},
];
var unitCombo = uiCombobox(context, 'roadheight-unit')
.data(primaryUnits);
function roadheight(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);
primaryInput = wrap.selectAll('input.roadheight-number')
.data([0]);
primaryInput = primaryInput.enter()
.append('input')
.attr('type', 'text')
.attr('class', 'roadheight-number')
.attr('id', field.domId)
.call(utilNoAuto)
.merge(primaryInput);
primaryInput
.on('change', change)
.on('blur', change);
var loc = combinedEntityExtent().center();
_isImperial = countryCoder.roadHeightUnit(loc) === 'ft';
primaryUnitInput = wrap.selectAll('input.roadheight-unit')
.data([0]);
primaryUnitInput = primaryUnitInput.enter()
.append('input')
.attr('type', 'text')
.attr('class', 'roadheight-unit')
.call(unitCombo)
.merge(primaryUnitInput);
primaryUnitInput
.on('blur', changeUnits)
.on('change', changeUnits);
secondaryInput = wrap.selectAll('input.roadheight-secondary-number')
.data([0]);
secondaryInput = secondaryInput.enter()
.append('input')
.attr('type', 'text')
.attr('class', 'roadheight-secondary-number')
.call(utilNoAuto)
.merge(secondaryInput);
secondaryInput
.on('change', change)
.on('blur', change);
secondaryUnitInput = wrap.selectAll('input.roadheight-secondary-unit')
.data([0]);
secondaryUnitInput = secondaryUnitInput.enter()
.append('input')
.attr('type', 'text')
.call(utilNoAuto)
.classed('disabled', true)
.classed('roadheight-secondary-unit', true)
.attr('readonly', 'readonly')
.merge(secondaryUnitInput);
function changeUnits() {
var primaryUnit = utilGetSetValue(primaryUnitInput);
if (primaryUnit === 'm') {
_isImperial = false;
} else if (primaryUnit === 'ft') {
_isImperial = true;
}
utilGetSetValue(primaryUnitInput, _isImperial ? 'ft' : 'm');
setUnitSuggestions();
change();
}
}
function setUnitSuggestions() {
utilGetSetValue(primaryUnitInput, _isImperial ? 'ft' : 'm');
}
function change() {
var tag = {};
var primaryValue = utilGetSetValue(primaryInput).trim();
var secondaryValue = utilGetSetValue(secondaryInput).trim();
// don't override multiple values with blank string
if (!primaryValue && !secondaryValue && Array.isArray(_tags[field.key])) return;
if (!primaryValue && !secondaryValue) {
tag[field.key] = undefined;
} else {
var rawPrimaryValue = likelyRawNumberFormat.test(primaryValue)
? parseFloat(primaryValue)
: parseLocaleFloat(primaryValue);
if (isNaN(rawPrimaryValue)) rawPrimaryValue = primaryValue;
var rawSecondaryValue = likelyRawNumberFormat.test(secondaryValue)
? parseFloat(secondaryValue)
: parseLocaleFloat(secondaryValue);
if (isNaN(rawSecondaryValue)) rawSecondaryValue = secondaryValue;
if (isNaN(rawPrimaryValue) || isNaN(rawSecondaryValue) || !_isImperial) {
tag[field.key] = context.cleanTagValue(rawPrimaryValue);
} else {
if (rawPrimaryValue !== '') {
rawPrimaryValue = rawPrimaryValue + '\'';
}
if (rawSecondaryValue !== '') {
rawSecondaryValue = rawSecondaryValue + '"';
}
tag[field.key] = context.cleanTagValue(rawPrimaryValue + rawSecondaryValue);
}
}
dispatch.call('change', this, tag);
}
roadheight.tags = function(tags) {
_tags = tags;
var primaryValue = tags[field.key];
var secondaryValue;
var isMixed = Array.isArray(primaryValue);
if (!isMixed) {
if (primaryValue && (primaryValue.indexOf('\'') >= 0 || primaryValue.indexOf('"') >= 0)) {
secondaryValue = primaryValue.match(/(-?[\d.]+)"/);
if (secondaryValue !== null) {
secondaryValue = formatFloat(parseFloat(secondaryValue[1]));
}
primaryValue = primaryValue.match(/(-?[\d.]+)'/);
if (primaryValue !== null) {
primaryValue = formatFloat(parseFloat(primaryValue[1]));
}
_isImperial = true;
} else if (primaryValue) {
var rawValue = primaryValue;
primaryValue = parseFloat(rawValue);
if (isNaN(primaryValue)) {
primaryValue = rawValue;
} else {
primaryValue = formatFloat(primaryValue);
}
_isImperial = false;
}
}
setUnitSuggestions();
// If feet are specified but inches are omitted, assume zero inches.
var inchesPlaceholder = formatFloat(0);
utilGetSetValue(primaryInput, typeof primaryValue === 'string' ? primaryValue : '')
.attr('title', isMixed ? primaryValue.filter(Boolean).join('\n') : null)
.attr('placeholder', isMixed ? t('inspector.multiple_values') : t('inspector.unknown'))
.classed('mixed', isMixed);
utilGetSetValue(secondaryInput, typeof secondaryValue === 'string' ? secondaryValue : '')
.attr('placeholder', isMixed ? t('inspector.multiple_values') : (_isImperial ? inchesPlaceholder : null))
.classed('mixed', isMixed)
.classed('disabled', !_isImperial)
.attr('readonly', _isImperial ? null : 'readonly');
secondaryUnitInput.attr('value', _isImperial ? t('inspector.roadheight.inch') : null);
};
roadheight.focus = function() {
primaryInput.node().focus();
};
roadheight.entityIDs = function(val) {
_entityIDs = val;
};
function combinedEntityExtent() {
return _entityIDs && _entityIDs.length && utilTotalExtent(_entityIDs, context.graph());
}
return utilRebind(roadheight, dispatch, 'on');
}