mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
Merge branch 'chips' of https://github.com/kepta/iD into kepta-chips
This commit is contained in:
@@ -232,6 +232,7 @@ dist/iD.js: \
|
||||
js/id/ui/preset/address.js \
|
||||
js/id/ui/preset/check.js \
|
||||
js/id/ui/preset/combo.js \
|
||||
js/id/ui/preset/multiselect.js \
|
||||
js/id/ui/preset/cycleway.js \
|
||||
js/id/ui/preset/input.js \
|
||||
js/id/ui/preset/localized.js \
|
||||
|
||||
+52
@@ -1193,6 +1193,58 @@ button.save.has-count .count::before {
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
/* preset form multiselect */
|
||||
|
||||
.form-field-multiselect {
|
||||
border: 1px solid #cfcfcf;
|
||||
border-top: 0px;
|
||||
padding: 5px 0 5px 10px;
|
||||
background: #fff;
|
||||
display: block;
|
||||
border-radius: 0 0 4px 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-field-multiselect:focus {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
.form-field-multiselect.active {
|
||||
border-bottom-left-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
.form-field-multiselect li {
|
||||
background-color: #eff2f7;
|
||||
border: 1px solid #ccd5e3;
|
||||
border-radius: 4px;
|
||||
line-height: 25px;
|
||||
display: inline-block;
|
||||
padding: 2px 5px;
|
||||
margin: 0 10px 5px 0;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.form-field-multiselect a {
|
||||
font-family: Arial, Helvetica, sans-serif !important;
|
||||
font-size: 16px !important;
|
||||
line-height: 25px;
|
||||
float: right;
|
||||
margin: 1px 0 0 5px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
color: #a6b4ce;
|
||||
}
|
||||
|
||||
.form-field-multiselect input {
|
||||
border: 0px;
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
.form-field-multiselect input:focus {
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
/* preset form cycleway */
|
||||
|
||||
.form-field-cycleway .preset-input-wrap li {
|
||||
|
||||
+3
-26
@@ -773,32 +773,9 @@ en:
|
||||
railway:
|
||||
# 'railway=*'
|
||||
label: Type
|
||||
recycling/cans:
|
||||
# 'recycling:cans=*'
|
||||
label: Accepts Cans
|
||||
recycling/clothes:
|
||||
# 'recycling:clothes=*'
|
||||
label: Accepts Clothes
|
||||
recycling/glass:
|
||||
# 'recycling:glass=*'
|
||||
label: Accepts Glass
|
||||
recycling/glass_bottles:
|
||||
# 'recycling:glass_bottles=*'
|
||||
label: Accepts Glass Bottles
|
||||
recycling/paper:
|
||||
# 'recycling:paper=*'
|
||||
label: Accepts Paper
|
||||
recycling/plastic:
|
||||
# 'recycling:plastic=*'
|
||||
label: Accepts Plastic
|
||||
recycling/type:
|
||||
# 'recycling_type=*'
|
||||
label: Recycling Type
|
||||
options:
|
||||
# recycling_type=centre
|
||||
centre: Recycling Center
|
||||
# recycling_type=container
|
||||
container: Container
|
||||
recycling/recycling_choices:
|
||||
# 'recycling=*'
|
||||
label: Accepts
|
||||
ref:
|
||||
# 'ref=*'
|
||||
label: Reference
|
||||
|
||||
@@ -653,7 +653,7 @@
|
||||
},
|
||||
"internet_access": {
|
||||
"key": "internet_access",
|
||||
"type": "combo",
|
||||
"type": "multiselect",
|
||||
"label": "Internet Access",
|
||||
"strings": {
|
||||
"options": {
|
||||
@@ -1020,46 +1020,10 @@
|
||||
"type": "typeCombo",
|
||||
"label": "Type"
|
||||
},
|
||||
"recycling/cans": {
|
||||
"key": "recycling:cans",
|
||||
"type": "check",
|
||||
"label": "Accepts Cans"
|
||||
},
|
||||
"recycling/clothes": {
|
||||
"key": "recycling:clothes",
|
||||
"type": "check",
|
||||
"label": "Accepts Clothes"
|
||||
},
|
||||
"recycling/glass": {
|
||||
"key": "recycling:glass",
|
||||
"type": "check",
|
||||
"label": "Accepts Glass"
|
||||
},
|
||||
"recycling/glass_bottles": {
|
||||
"key": "recycling:glass_bottles",
|
||||
"type": "check",
|
||||
"label": "Accepts Glass Bottles"
|
||||
},
|
||||
"recycling/paper": {
|
||||
"key": "recycling:paper",
|
||||
"type": "check",
|
||||
"label": "Accepts Paper"
|
||||
},
|
||||
"recycling/plastic": {
|
||||
"key": "recycling:plastic",
|
||||
"type": "check",
|
||||
"label": "Accepts Plastic"
|
||||
},
|
||||
"recycling/type": {
|
||||
"key": "recycling_type",
|
||||
"type": "combo",
|
||||
"label": "Recycling Type",
|
||||
"strings": {
|
||||
"options": {
|
||||
"container": "Container",
|
||||
"centre": "Recycling Center"
|
||||
}
|
||||
}
|
||||
"recycling/recycling_choices": {
|
||||
"key": "recycling",
|
||||
"type": "multiselect",
|
||||
"label": "Accepts"
|
||||
},
|
||||
"ref": {
|
||||
"key": "ref",
|
||||
@@ -1270,7 +1234,7 @@
|
||||
},
|
||||
"sport_ice": {
|
||||
"key": "sport",
|
||||
"type": "combo",
|
||||
"type": "multiselect",
|
||||
"label": "Sport",
|
||||
"options": [
|
||||
"skating",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"key": "internet_access",
|
||||
"type": "combo",
|
||||
"type": "multiselect",
|
||||
"label": "Internet Access",
|
||||
"strings": {
|
||||
"options": {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:cans",
|
||||
"type": "check",
|
||||
"label": "Accepts Cans"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:clothes",
|
||||
"type": "check",
|
||||
"label": "Accepts Clothes"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:glass",
|
||||
"type": "check",
|
||||
"label": "Accepts Glass"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:glass_bottles",
|
||||
"type": "check",
|
||||
"label": "Accepts Glass Bottles"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:paper",
|
||||
"type": "check",
|
||||
"label": "Accepts Paper"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"key": "recycling:plastic",
|
||||
"type": "check",
|
||||
"label": "Accepts Plastic"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"key": "recycling",
|
||||
"type": "multiselect",
|
||||
"label": "Accepts"
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"key": "recycling_type",
|
||||
"type": "combo",
|
||||
"label": "Recycling Type",
|
||||
"strings": {
|
||||
"options": {
|
||||
"container": "Container",
|
||||
"centre": "Recycling Center"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"key": "sport",
|
||||
"type": "combo",
|
||||
"type": "multiselect",
|
||||
"label": "Sport",
|
||||
"options": [
|
||||
"skating",
|
||||
|
||||
@@ -1581,13 +1581,7 @@
|
||||
"fields": [
|
||||
"operator",
|
||||
"address",
|
||||
"recycling/type",
|
||||
"recycling/cans",
|
||||
"recycling/glass_bottles",
|
||||
"recycling/paper",
|
||||
"recycling/glass",
|
||||
"recycling/plastic",
|
||||
"recycling/clothes"
|
||||
"recycling/recycling_choices"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
"fields": [
|
||||
"operator",
|
||||
"address",
|
||||
"recycling/type",
|
||||
"recycling/cans",
|
||||
"recycling/glass_bottles",
|
||||
"recycling/paper",
|
||||
"recycling/glass",
|
||||
"recycling/plastic",
|
||||
"recycling/clothes"
|
||||
"recycling/recycling_choices"
|
||||
],
|
||||
"geometry": [
|
||||
"point",
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"defaultcheck",
|
||||
"text",
|
||||
"maxspeed",
|
||||
"multiselect",
|
||||
"number",
|
||||
"tel",
|
||||
"email",
|
||||
|
||||
Vendored
+2
-24
@@ -1280,30 +1280,8 @@
|
||||
"railway": {
|
||||
"label": "Type"
|
||||
},
|
||||
"recycling/cans": {
|
||||
"label": "Accepts Cans"
|
||||
},
|
||||
"recycling/clothes": {
|
||||
"label": "Accepts Clothes"
|
||||
},
|
||||
"recycling/glass": {
|
||||
"label": "Accepts Glass"
|
||||
},
|
||||
"recycling/glass_bottles": {
|
||||
"label": "Accepts Glass Bottles"
|
||||
},
|
||||
"recycling/paper": {
|
||||
"label": "Accepts Paper"
|
||||
},
|
||||
"recycling/plastic": {
|
||||
"label": "Accepts Plastic"
|
||||
},
|
||||
"recycling/type": {
|
||||
"label": "Recycling Type",
|
||||
"options": {
|
||||
"container": "Container",
|
||||
"centre": "Recycling Center"
|
||||
}
|
||||
"recycling/recycling_choices": {
|
||||
"label": "Accepts"
|
||||
},
|
||||
"ref": {
|
||||
"label": "Reference"
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
<script src='js/id/ui/preset/access.js'></script>
|
||||
<script src='js/id/ui/preset/address.js'></script>
|
||||
<script src='js/id/ui/preset/check.js'></script>
|
||||
<script src='js/id/ui/preset/multiselect.js'></script>
|
||||
<script src='js/id/ui/preset/combo.js'></script>
|
||||
<script src='js/id/ui/preset/cycleway.js'></script>
|
||||
<script src='js/id/ui/preset/input.js'></script>
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
iD.ui.preset.multiselect = function(field, context) {
|
||||
var dispatch = d3.dispatch('init', 'change'),
|
||||
optstrings = field.strings && field.strings.options,
|
||||
optarray = field.options,
|
||||
strings = {},
|
||||
multiselectContainer,
|
||||
combobox,
|
||||
comboboxData,
|
||||
input,
|
||||
isInitialized;
|
||||
|
||||
field.key += ':';
|
||||
|
||||
function getOptStringKey(val) {
|
||||
if (optstrings) {
|
||||
var match = _.find(strings, function(o) {
|
||||
return o.value === val;
|
||||
});
|
||||
return match && match.key;
|
||||
}
|
||||
}
|
||||
|
||||
function getOptStringVal(key) {
|
||||
if (optstrings) {
|
||||
var match = _.find(strings, function(o) {
|
||||
return o.key === key;
|
||||
});
|
||||
return match && match.value;
|
||||
}
|
||||
}
|
||||
|
||||
function objectDifference(a, b) {
|
||||
var bObj = {};
|
||||
b.forEach(function(obj){
|
||||
bObj[obj.key] = obj;
|
||||
});
|
||||
// Return all elements in a, unless in b
|
||||
return a.filter(function(obj){
|
||||
return !(obj.key in bObj);
|
||||
});
|
||||
}
|
||||
|
||||
function multiselect(selection) {
|
||||
isInitialized = false;
|
||||
combobox = d3.combobox();
|
||||
|
||||
multiselectContainer = selection.selectAll('ul').data([0]);
|
||||
|
||||
multiselectContainer.enter()
|
||||
.append('ul')
|
||||
.on('click', function() {
|
||||
window.setTimeout(function(){input.node().focus();}, 100);
|
||||
})
|
||||
.attr('class', 'form-field-multiselect');
|
||||
|
||||
input = multiselectContainer.selectAll('input')
|
||||
.data([0]);
|
||||
|
||||
var enter = input.enter()
|
||||
.append('input')
|
||||
.attr('type', 'text')
|
||||
.attr('id', 'preset-input-' + field.id);
|
||||
|
||||
if (optstrings) { enter.attr('readonly', 'readonly'); }
|
||||
|
||||
input
|
||||
.call(function() {combobox(input, selection);})
|
||||
.on('change', change)
|
||||
.on('blur', change)
|
||||
.on('focus', function() {multiselectContainer.classed('active', true);})
|
||||
.each(function() {
|
||||
if (optstrings) {
|
||||
strings = Object.keys(optstrings).map(function(k) {
|
||||
return {
|
||||
key: k,
|
||||
value: field.t('options.' + k, { 'default': optstrings[k] })
|
||||
};
|
||||
});
|
||||
dispatch.init();
|
||||
isInitialized = true;
|
||||
} else if (optarray) {
|
||||
strings = optarray.map(function(k) {return {key: k, value: k};});
|
||||
dispatch.init();
|
||||
isInitialized = true;
|
||||
} else if (context.taginfo()) {
|
||||
context.taginfo().keys({query: field.key}, function(err, data) {
|
||||
if (!err) {
|
||||
strings = data.map(function(k) {
|
||||
var d = k.value.replace(field.key, '');
|
||||
return {
|
||||
key: d,
|
||||
value: d
|
||||
};
|
||||
});
|
||||
dispatch.init();
|
||||
isInitialized = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateStrings(tagsData) {
|
||||
comboboxData = objectDifference(strings, tagsData);
|
||||
combobox.data(comboboxData.map(comboValues));
|
||||
input.attr('placeholder', field.placeholder() ||
|
||||
( 'Type here'));
|
||||
}
|
||||
|
||||
|
||||
function update(data) {
|
||||
var chips = multiselectContainer.selectAll('.chips').data(data);
|
||||
|
||||
var chip = chips.enter()
|
||||
.insert('li', 'input')
|
||||
.attr('class', 'chips');
|
||||
|
||||
chip.append('span');
|
||||
chip.append('a');
|
||||
|
||||
chips.select('span').text(function(d) {return d.value;});
|
||||
|
||||
chips.select('a')
|
||||
.on('click', removeKey)
|
||||
.attr('class', 'remove')
|
||||
.text('×');
|
||||
|
||||
chips.exit().remove();
|
||||
}
|
||||
|
||||
function comboValues(d) {
|
||||
return {
|
||||
value: d.value,
|
||||
title: d.value
|
||||
};
|
||||
}
|
||||
|
||||
function change() {
|
||||
multiselectContainer.classed('active', false);
|
||||
var key = getOptStringKey(input.value()) || input.value();
|
||||
if (key && key !== '') {
|
||||
var t = {};
|
||||
t[field.key + key] = 'yes';
|
||||
input.value('');
|
||||
dispatch.change(t);
|
||||
}
|
||||
}
|
||||
|
||||
function removeKey(d) {
|
||||
d3.event.stopPropagation();
|
||||
var t = {};
|
||||
t[field.key + d.key] = undefined;
|
||||
dispatch.change(t);
|
||||
}
|
||||
|
||||
multiselect.tags = function(tags) {
|
||||
var tagsData = [];
|
||||
Object.keys(tags).forEach(function(d) {
|
||||
if (d.indexOf(field.key) > -1 && tags[d] === 'yes') {
|
||||
var datum = d.replace(field.key, '');
|
||||
|
||||
if (!optstrings) {
|
||||
return tagsData.push({
|
||||
key: datum,
|
||||
value: datum
|
||||
});
|
||||
}
|
||||
// discards any pair not found in optstrings
|
||||
if (optstrings && getOptStringVal(datum)) {
|
||||
return tagsData.push({
|
||||
key: datum,
|
||||
value: getOptStringVal(datum)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
update(tagsData);
|
||||
|
||||
if (isInitialized) {
|
||||
updateStrings(tagsData);
|
||||
} else {
|
||||
dispatch.on('init', function () {
|
||||
updateStrings(tagsData);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
multiselect.focus = function() {
|
||||
input.node().focus();
|
||||
};
|
||||
|
||||
return d3.rebind(multiselect, dispatch, 'on');
|
||||
};
|
||||
@@ -14,7 +14,7 @@ d3.combobox = function() {
|
||||
}));
|
||||
};
|
||||
|
||||
var combobox = function(input) {
|
||||
var combobox = function(input, customBoundingRect) {
|
||||
var idx = -1,
|
||||
container = d3.select(document.body)
|
||||
.selectAll('div.combobox')
|
||||
@@ -223,7 +223,7 @@ d3.combobox = function() {
|
||||
options.exit()
|
||||
.remove();
|
||||
|
||||
var rect = input.node().getBoundingClientRect();
|
||||
var rect = customBoundingRect ? customBoundingRect.node().getBoundingClientRect() : input.node().getBoundingClientRect();
|
||||
|
||||
container.style({
|
||||
'left': rect.left + 'px',
|
||||
|
||||
Reference in New Issue
Block a user