diff --git a/css/app.css b/css/app.css
index ff4ea3953..da88ed4b1 100644
--- a/css/app.css
+++ b/css/app.css
@@ -665,6 +665,33 @@ div.combobox {
text-align: center;
}
+
+.checkselect label {
+ display: block;
+ padding: 5px;
+ width: 100%;
+ color: #999;
+}
+
+.checkselect label:hover {
+ cursor: pointer;
+}
+
+.checkselect .set {
+ background: #eee;
+ color: inherit;
+}
+
+.checkselect input[type="checkbox"] {
+ margin-right: 5px;
+ width: 20px;
+ vertical-align: middle;
+ opacity: 0.5;
+}
+.checkselect .set input[type="checkbox"] {
+ opacity: 1;
+}
+
/* Address input */
.preset-input .addr-housename {
diff --git a/index.html b/index.html
index 210494597..594a99885 100644
--- a/index.html
+++ b/index.html
@@ -21,6 +21,7 @@
+
diff --git a/js/id/ui/preset.js b/js/id/ui/preset.js
index 50205f1fe..51f7007ec 100644
--- a/js/id/ui/preset.js
+++ b/js/id/ui/preset.js
@@ -76,6 +76,14 @@ iD.ui.preset = function(context) {
.attr('id', 'input-' + d.key)
.attr('placeholder', 'http://example.com/');
break;
+ case 'check':
+ wrap = this.append('span').attr('class', 'input-wrap-position'),
+ i = wrap.append('input').attr('type', 'text');
+ var check = d3.checkselect().on('change', key);
+ wrap.call(check);
+ event.on('setTags.' + d.key, check.update);
+ break;
+
case 'select':
wrap = this.append('span').attr('class', 'input-wrap-position'),
i = wrap.append('input').attr('type', 'text');
diff --git a/js/lib/d3.checkselect.js b/js/lib/d3.checkselect.js
new file mode 100644
index 000000000..0177bb125
--- /dev/null
+++ b/js/lib/d3.checkselect.js
@@ -0,0 +1,46 @@
+d3.checkselect = function() {
+
+ var event = d3.dispatch('change'),
+ values = ['', 'yes', 'no'],
+ value = '',
+ input, box, text, label;
+
+ var check = function(selection) {
+
+ selection.classed('checkselect', 'true');
+
+ input = selection.select('input');
+ input.style('display', 'none');
+
+ label = selection.append('label');
+
+ box = label.append('input')
+ .attr('type', 'checkbox')
+ .datum(undefined);
+
+ text = label.append('span')
+ .attr('class', 'value');
+
+ box.on('click', function() {
+ input.property('value', values[(values.indexOf(value) + 1) % 3]);
+ update();
+ event.change();
+ d3.event.stopPropagation();
+ });
+
+ update();
+ };
+
+ function update() {
+ value = input.property('value');
+
+ box.property('indeterminate', !value);
+ box.property('checked', value === 'yes');
+ text.text(value || 'unknown');
+ label.classed('set', !!value);
+ }
+
+ check.update = update;
+
+ return d3.rebind(check, event, 'on');
+};
diff --git a/presets/forms.json b/presets/forms.json
index 83ed53a4a..48981a22c 100644
--- a/presets/forms.json
+++ b/presets/forms.json
@@ -12,9 +12,8 @@
},
"building_area": {
"key": "building",
- "type": "select",
- "default": { "area": "yes" },
- "options": ["yes", "no"]
+ "type": "check",
+ "default": { "area": "yes" }
},
"address": {
"type": "address",
@@ -44,8 +43,7 @@
},
"fee": {
"key": "fee",
- "type": "select",
- "options": ["yes", "no"]
+ "type": "check"
},
"access": {
"key": "access",
@@ -53,23 +51,19 @@
},
"atm": {
"key": "atm",
- "type": "select",
- "options": ["yes", "no"]
+ "type": "check"
},
"shelter": {
"key": "shelter",
- "type": "select",
- "options": ["yes", "no"]
+ "type": "check"
},
"emergency": {
"key": "emergency",
- "type": "select",
- "options": ["yes", "no"]
+ "type": "check"
},
"oneway": {
"key": "oneway",
- "type": "select",
- "options": ["yes", "no"]
+ "type": "check"
},
"access": {
"key": "access",