diff --git a/css/app.css b/css/app.css
index eff5c8db8..3ee648b9d 100644
--- a/css/app.css
+++ b/css/app.css
@@ -948,6 +948,10 @@ a:hover .icon.out-link { background-position: -500px -14px;}
font-weight: bold;
}
+.form-field-access .preset-input-wrap {
+ padding: 5px;
+}
+
/* adding additional preset fields */
.more-buttons {
diff --git a/data/locales.js b/data/locales.js
index 0d76a697e..561b9dbb3 100644
--- a/data/locales.js
+++ b/data/locales.js
@@ -321,7 +321,40 @@ locale.en = {
"presets": {
"fields": {
"access": {
- "label": "Access"
+ "label": "Access",
+ "types": {
+ "access": "General",
+ "foot": "Foot",
+ "motor_vehicle": "Motor Vehicles",
+ "bicycle": "Bicycles",
+ "horse": "Horses"
+ },
+ "options": {
+ "yes": {
+ "title": "Allowed",
+ "description": "Access permitted by law; a right of way"
+ },
+ "no": {
+ "title": "Prohibited",
+ "description": "Access not permitted to the general public"
+ },
+ "permissive": {
+ "title": "Permissive",
+ "description": "Access permitted until such time as the owner revokes the permission"
+ },
+ "private": {
+ "title": "Private",
+ "description": "Access permitted only with permission of the owner on an individual basis"
+ },
+ "designated": {
+ "title": "Designated",
+ "description": "Access permitted according to signs or specific local laws"
+ },
+ "destination": {
+ "title": "Destination",
+ "description": "Access permitted only to reach a destination"
+ }
+ }
},
"address": {
"label": "Address",
diff --git a/data/presets.yaml b/data/presets.yaml
index e8bc48c76..940b9fd12 100644
--- a/data/presets.yaml
+++ b/data/presets.yaml
@@ -3,6 +3,31 @@ en:
fields:
access:
label: Access
+ types:
+ access: General
+ foot: Foot
+ motor_vehicle: Motor Vehicles
+ bicycle: Bicycles
+ horse: Horses
+ options:
+ yes:
+ title: Allowed
+ description: Access permitted by law; a right of way
+ no:
+ title: Prohibited
+ description: Access not permitted to the general public
+ permissive:
+ title: Permissive
+ description: Access permitted until such time as the owner revokes the permission
+ private:
+ title: Private
+ description: Access permitted only with permission of the owner on an individual basis
+ designated:
+ title: Designated
+ description: Access permitted according to signs or specific local laws
+ destination:
+ title: Destination
+ description: Access permitted only to reach a destination
address:
label: Address
placeholders:
diff --git a/data/presets/fields.json b/data/presets/fields.json
index 542fc131c..7fb6e77a5 100644
--- a/data/presets/fields.json
+++ b/data/presets/fields.json
@@ -1,8 +1,49 @@
{
"access": {
- "key": "access",
- "type": "combo",
- "label": "Access"
+ "keys": [
+ "access",
+ "foot",
+ "motor_vehicle",
+ "bicycle",
+ "horse"
+ ],
+ "type": "access",
+ "label": "Access",
+ "strings": {
+ "types": {
+ "access": "General",
+ "foot": "Foot",
+ "motor_vehicle": "Motor Vehicles",
+ "bicycle": "Bicycles",
+ "horse": "Horses"
+ },
+ "options": {
+ "yes": {
+ "title": "Allowed",
+ "description": "Access permitted by law; a right of way"
+ },
+ "no": {
+ "title": "Prohibited",
+ "description": "Access not permitted to the general public"
+ },
+ "permissive": {
+ "title": "Permissive",
+ "description": "Access permitted until such time as the owner revokes the permission"
+ },
+ "private": {
+ "title": "Private",
+ "description": "Access permitted only with permission of the owner on an individual basis"
+ },
+ "designated": {
+ "title": "Designated",
+ "description": "Access permitted according to signs or specific local laws"
+ },
+ "destination": {
+ "title": "Destination",
+ "description": "Access permitted only to reach a destination"
+ }
+ }
+ }
},
"address": {
"type": "address",
diff --git a/data/presets/fields/access.json b/data/presets/fields/access.json
index 0243f6cbb..a58a7f9ff 100644
--- a/data/presets/fields/access.json
+++ b/data/presets/fields/access.json
@@ -1,5 +1,40 @@
{
- "key": "access",
- "type": "combo",
- "label": "Access"
+ "keys": ["access", "foot", "motor_vehicle", "bicycle", "horse"],
+ "type": "access",
+ "label": "Access",
+ "strings": {
+ "types": {
+ "access": "General",
+ "foot": "Foot",
+ "motor_vehicle": "Motor Vehicles",
+ "bicycle": "Bicycles",
+ "horse": "Horses"
+ },
+ "options": {
+ "yes": {
+ "title": "Allowed",
+ "description": "Access permitted by law; a right of way"
+ },
+ "no": {
+ "title": "Prohibited",
+ "description": "Access not permitted to the general public"
+ },
+ "permissive": {
+ "title": "Permissive",
+ "description": "Access permitted until such time as the owner revokes the permission"
+ },
+ "private": {
+ "title": "Private",
+ "description": "Access permitted only with permission of the owner on an individual basis"
+ },
+ "designated": {
+ "title": "Designated",
+ "description": "Access permitted according to signs or specific local laws"
+ },
+ "destination": {
+ "title": "Destination",
+ "description": "Access permitted only to reach a destination"
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/data/presets/schema/field.json b/data/presets/schema/field.json
index 8c43995fe..78a68da54 100644
--- a/data/presets/schema/field.json
+++ b/data/presets/schema/field.json
@@ -18,6 +18,7 @@
"description": "Type of field",
"type": "string",
"enum": [
+ "access",
"address",
"check",
"combo",
diff --git a/index.html b/index.html
index e8148cd36..c8dbaf254 100644
--- a/index.html
+++ b/index.html
@@ -95,6 +95,7 @@
+
diff --git a/js/id/ui/preset/access.js b/js/id/ui/preset/access.js
new file mode 100644
index 000000000..55ceedcbe
--- /dev/null
+++ b/js/id/ui/preset/access.js
@@ -0,0 +1,76 @@
+iD.ui.preset.access = function(field, context) {
+ var event = d3.dispatch('change', 'close'),
+ entity,
+ items;
+
+ function access(selection) {
+ var wrap = selection.append('div')
+ .attr('class', 'cf preset-input-wrap');
+
+ items = wrap.append('ul').selectAll('li')
+ .data(field.keys);
+
+ var enter = items.enter()
+ .append('li')
+ .attr('class', function(d) { return 'cf preset-access-' + d; });
+
+ enter.append('label')
+ .attr('class', 'col3 preset-label-access')
+ .attr('for', function(d) { return 'preset-input-access-' + d; })
+ .text(function(d) { return field.t('types.' + d); });
+
+ enter.append('div')
+ .attr('class', 'col9 preset-input-access-wrap')
+ .append('input')
+ .attr('type', 'text')
+ .attr('class', 'preset-input-access')
+ .attr('id', function(d) { return 'preset-input-access-' + d; })
+ .on('change', change)
+ .on('blur', change)
+ .each(function(d) {
+ d3.select(this)
+ .call(d3.combobox()
+ .data(access.options(d)));
+ });
+ }
+
+ function change(d) {
+ var tag = {};
+ tag[d] = d3.select(this).property('value');
+ event.change(tag);
+ }
+
+ access.options = function(type) {
+ var options = ['no', 'permissive', 'private', 'designated', 'destination'];
+
+ if (type != 'access') {
+ options.unshift('yes');
+ }
+
+ return options.map(function(option) {
+ return {
+ title: field.t('options.' + option + '.description'),
+ value: option
+ }
+ });
+ };
+
+ access.entity = function(_) {
+ if (!arguments.length) return entity;
+ entity = _;
+ return access;
+ };
+
+ access.tags = function(tags) {
+ items.selectAll('.preset-input-access')
+ .property('value', function(d) { return tags[d] || ''; });
+ return access;
+ };
+
+ access.focus = function() {
+ items.selectAll('.preset-input-access')
+ .node().focus();
+ };
+
+ return d3.rebind(access, event, 'on');
+};
diff --git a/test/index.html b/test/index.html
index aae9c6458..a68e1baf7 100644
--- a/test/index.html
+++ b/test/index.html
@@ -93,6 +93,7 @@
+
@@ -230,6 +231,8 @@
+
+
diff --git a/test/spec/ui/preset/access.js b/test/spec/ui/preset/access.js
new file mode 100644
index 000000000..ecfc30754
--- /dev/null
+++ b/test/spec/ui/preset/access.js
@@ -0,0 +1,23 @@
+describe('iD.ui.preset.access', function() {
+ var selection, field;
+
+ beforeEach(function() {
+ selection = d3.select(document.createElement('div'));
+ field = iD().presets().field('access');
+ });
+
+ it('creates inputs for a variety of modes of access', function() {
+ var access = iD.ui.preset.access(field, {});
+ selection.call(access);
+ expect(selection.selectAll('.preset-access-access')[0].length).to.equal(1);
+ expect(selection.selectAll('.preset-access-foot')[0].length).to.equal(1);
+ expect(selection.selectAll('.preset-access-motor_vehicle')[0].length).to.equal(1);
+ expect(selection.selectAll('.preset-access-bicycle')[0].length).to.equal(1);
+ expect(selection.selectAll('.preset-access-horse')[0].length).to.equal(1);
+ });
+
+ it('does not include a "yes" option for general access (#934)', function() {
+ var access = iD.ui.preset.access(field, {});
+ expect(_.pluck(access.options('access'), 'value')).not.to.include('yes');
+ });
+});