Allow to use an unicode char as marker icon symbol
One can also use a property to have a dynamic value (eg. to display numbers:, 1, 2, 3, 4…). fix #527
This commit is contained in:
parent
705d0cbb73
commit
af6c7fba26
8 changed files with 110 additions and 17 deletions
|
@ -71,6 +71,7 @@ COMMIT;
|
||||||
- fixed ClusterMarker text color on Chrome (#547)
|
- fixed ClusterMarker text color on Chrome (#547)
|
||||||
- allow to clone also markers
|
- allow to clone also markers
|
||||||
- only list https ready tilerlayers when page is in https (#567)
|
- only list https ready tilerlayers when page is in https (#567)
|
||||||
|
- allow to use an unicode character as Marker symbol (#527)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -553,7 +553,29 @@ i.info {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
input.blur {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
}
|
||||||
|
.blur + .button:before {
|
||||||
|
content: '✔';
|
||||||
|
}
|
||||||
|
.blur + .button {
|
||||||
|
width: 40px;
|
||||||
|
height: 18px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 18px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
input[type=hidden].blur + .button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* *********** */
|
/* *********** */
|
||||||
/* Panel */
|
/* Panel */
|
||||||
|
|
|
@ -410,7 +410,7 @@ L.U.Help = L.Class.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
formatURL: L._('Supported variables that will be dynamically replaced') + ': {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}...',
|
formatURL: L._('Supported variables that will be dynamically replaced') + ': {bbox}, {lat}, {lng}, {zoom}, {east}, {north}..., {left}, {top}...',
|
||||||
formatIconURL: L._('You can use feature properties as variables: ex.: with "http://myserver.org/images/{name}.png", the {name} variable will be replaced by the "name" value of each markers.'),
|
formatIconSymbol: L._('Symbol can be either a unicode caracter or an URL. You can use feature properties as variables: ex.: with "http://myserver.org/images/{name}.png", the {name} variable will be replaced by the "name" value of each marker.'),
|
||||||
colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
|
colorValue: L._('Must be a valid CSS value (eg.: DarkBlue or #123456)'),
|
||||||
smoothFactor: L._('How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'),
|
smoothFactor: L._('How much to simplify the polyline on each zoom level (more = better performance and smoother look, less = more accurate)'),
|
||||||
dashArray: L._('A comma separated list of numbers that defines the stroke dash pattern. Ex.: "5, 10, 15".'),
|
dashArray: L._('A comma separated list of numbers that defines the stroke dash pattern. Ex.: "5, 10, 15".'),
|
||||||
|
|
|
@ -52,10 +52,10 @@ L.FormBuilder.Element.include({
|
||||||
this.label = L.DomUtil.create('label', '', this.getLabelParent());
|
this.label = L.DomUtil.create('label', '', this.getLabelParent());
|
||||||
this.label.innerHTML = this.label.title = this.options.label;
|
this.label.innerHTML = this.label.title = this.options.label;
|
||||||
if (this.options.helpEntries) this.builder.map.help.button(this.label, this.options.helpEntries);
|
if (this.options.helpEntries) this.builder.map.help.button(this.label, this.options.helpEntries);
|
||||||
else if (this.options.helpText) {
|
else if (this.options.helpTooltip) {
|
||||||
var info = L.DomUtil.create('i', 'info', this.label);
|
var info = L.DomUtil.create('i', 'info', this.label);
|
||||||
L.DomEvent.on(info, 'mouseover', function () {
|
L.DomEvent.on(info, 'mouseover', function () {
|
||||||
this.builder.map.ui.tooltip({anchor: info, content: this.options.helpText, position: 'top'});
|
this.builder.map.ui.tooltip({anchor: info, content: this.options.helpTooltip, position: 'top'});
|
||||||
}, this);
|
}, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,28 +355,51 @@ L.FormBuilder.NullableBoolean = L.FormBuilder.Select.extend({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
L.FormBuilder.IconUrl = L.FormBuilder.Input.extend({
|
|
||||||
|
L.FormBuilder.BlurInput.include({
|
||||||
|
|
||||||
|
build: function () {
|
||||||
|
this.options.className = 'blur';
|
||||||
|
L.FormBuilder.Input.prototype.build.call(this);
|
||||||
|
var button = L.DomUtil.create('span', 'button blur-button');
|
||||||
|
L.DomUtil.after(this.input, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
|
|
||||||
type: function () {
|
type: function () {
|
||||||
return 'hidden';
|
return 'hidden';
|
||||||
},
|
},
|
||||||
|
|
||||||
build: function () {
|
build: function () {
|
||||||
L.FormBuilder.Input.prototype.build.call(this);
|
this.options.helpText = this.builder.map.help.formatIconSymbol;
|
||||||
|
L.FormBuilder.BlurInput.prototype.build.call(this);
|
||||||
this.parentContainer = L.DomUtil.create('div', 'umap-form-iconfield', this.parentNode);
|
this.parentContainer = L.DomUtil.create('div', 'umap-form-iconfield', this.parentNode);
|
||||||
this.buttonsContainer = L.DomUtil.create('div', '', this.parentContainer);
|
this.buttonsContainer = L.DomUtil.create('div', '', this.parentContainer);
|
||||||
this.pictogramsContainer = L.DomUtil.create('div', 'umap-pictogram-list', this.parentContainer);
|
this.pictogramsContainer = L.DomUtil.create('div', 'umap-pictogram-list', this.parentContainer);
|
||||||
this.input.type = 'hidden';
|
this.input.type = 'hidden';
|
||||||
this.input.placeholder = L._('Url');
|
this.input.placeholder = L._('Symbol or url');
|
||||||
this.udpatePreview();
|
this.udpatePreview();
|
||||||
this.on('define', this.fetchIconList);
|
this.on('define', this.fetchIconList);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isUrl: function () {
|
||||||
|
return (this.value().indexOf('/') !== -1);
|
||||||
|
},
|
||||||
|
|
||||||
udpatePreview: function () {
|
udpatePreview: function () {
|
||||||
if (this.value() && this.value().indexOf('{') === -1) { // Do not try to render URL with variables
|
if (this.value()&& this.value().indexOf('{') === -1) { // Do not try to render URL with variables
|
||||||
|
if (this.isUrl()) {
|
||||||
var img = L.DomUtil.create('img', '', L.DomUtil.create('div', 'umap-icon-choice', this.buttonsContainer));
|
var img = L.DomUtil.create('img', '', L.DomUtil.create('div', 'umap-icon-choice', this.buttonsContainer));
|
||||||
img.src = this.value();
|
img.src = this.value();
|
||||||
L.DomEvent.on(img, 'click', this.fetchIconList, this);
|
L.DomEvent.on(img, 'click', this.fetchIconList, this);
|
||||||
|
} else {
|
||||||
|
var el = L.DomUtil.create('span', '', L.DomUtil.create('div', 'umap-icon-choice', this.buttonsContainer));
|
||||||
|
el.textContent = this.value();
|
||||||
|
L.DomEvent.on(el, 'click', this.fetchIconList, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.button = L.DomUtil.create('a', '', this.buttonsContainer);
|
this.button = L.DomUtil.create('a', '', this.buttonsContainer);
|
||||||
this.button.innerHTML = this.value() ? L._('Change symbol') : L._('Add symbol');
|
this.button.innerHTML = this.value() ? L._('Change symbol') : L._('Add symbol');
|
||||||
|
@ -432,15 +455,15 @@ L.FormBuilder.IconUrl = L.FormBuilder.Input.extend({
|
||||||
this.udpatePreview();
|
this.udpatePreview();
|
||||||
}, this);
|
}, this);
|
||||||
var customButton = L.DomUtil.create('a', '', this.pictogramsContainer);
|
var customButton = L.DomUtil.create('a', '', this.pictogramsContainer);
|
||||||
customButton.innerHTML = L._('Set URL');
|
customButton.innerHTML = L._('Set symbol');
|
||||||
customButton.href = '#';
|
customButton.href = '#';
|
||||||
customButton.style.display = 'block';
|
customButton.style.display = 'block';
|
||||||
customButton.style.clear = 'both';
|
customButton.style.clear = 'both';
|
||||||
this.builder.map.help.button(customButton, 'formatIconURL');
|
this.builder.map.help.button(customButton, 'formatIconSymbol');
|
||||||
L.DomEvent
|
L.DomEvent
|
||||||
.on(customButton, 'click', L.DomEvent.stop)
|
.on(customButton, 'click', L.DomEvent.stop)
|
||||||
.on(customButton, 'click', function (e) {
|
.on(customButton, 'click', function (e) {
|
||||||
this.input.type = 'url';
|
this.input.type = 'text';
|
||||||
this.pictogramsContainer.innerHTML = '';
|
this.pictogramsContainer.innerHTML = '';
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
@ -699,7 +722,7 @@ L.U.FormBuilder = L.FormBuilder.extend({
|
||||||
smoothFactor: {handler: 'Range', min: 0, max: 10, step: 0.5, label: L._('Simplify'), helpEntries: 'smoothFactor', inheritable: true},
|
smoothFactor: {handler: 'Range', min: 0, max: 10, step: 0.5, label: L._('Simplify'), helpEntries: 'smoothFactor', inheritable: true},
|
||||||
dashArray: {label: L._('dash array'), helpEntries: 'dashArray', inheritable: true},
|
dashArray: {label: L._('dash array'), helpEntries: 'dashArray', inheritable: true},
|
||||||
iconClass: {handler: 'IconClassSwitcher', label: L._('Icon shape'), inheritable: true},
|
iconClass: {handler: 'IconClassSwitcher', label: L._('Icon shape'), inheritable: true},
|
||||||
iconUrl: {handler: 'IconUrl', label: L._('Icon symbol'), inheritable: true},
|
iconUrl: {handler: 'IconUrl', label: L._('Icon symbol'), inheritable: true, helpText: L.U.Help.formatIconSymbol},
|
||||||
popupTemplate: {handler: 'PopupTemplate', label: L._('Popup style'), inheritable: true},
|
popupTemplate: {handler: 'PopupTemplate', label: L._('Popup style'), inheritable: true},
|
||||||
popupContentTemplate: {label: L._('Popup content template'), handler: 'Textarea', helpEntries: ['dynamicProperties', 'textFormatting'], placeholder: '# {name}', inheritable: true},
|
popupContentTemplate: {label: L._('Popup content template'), handler: 'Textarea', helpEntries: ['dynamicProperties', 'textFormatting'], placeholder: '# {name}', inheritable: true},
|
||||||
datalayer: {handler: 'DataLayerSwitcher', label: L._('Choose the layer of the feature')},
|
datalayer: {handler: 'DataLayerSwitcher', label: L._('Choose the layer of the feature')},
|
||||||
|
|
|
@ -59,9 +59,17 @@ L.U.Icon.Default = L.U.Icon.extend({
|
||||||
this.elements.main = L.DomUtil.create('div');
|
this.elements.main = L.DomUtil.create('div');
|
||||||
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
||||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
||||||
this.elements.img = L.DomUtil.create('img', null, this.elements.container);
|
|
||||||
var src = this._getIconUrl('icon');
|
var src = this._getIconUrl('icon');
|
||||||
if (src) this.elements.img.src = src;
|
if (src) {
|
||||||
|
// An url.
|
||||||
|
if (src.indexOf('http') === 0 || src.indexOf('/') === 0) {
|
||||||
|
this.elements.img = L.DomUtil.create('img', null, this.elements.container);
|
||||||
|
this.elements.img.src = src;
|
||||||
|
} else {
|
||||||
|
this.elements.span = L.DomUtil.create('span', null, this.elements.container)
|
||||||
|
this.elements.span.textContent = src;
|
||||||
|
}
|
||||||
|
}
|
||||||
this._setColor();
|
this._setColor();
|
||||||
this._setIconStyles(this.elements.main, 'icon');
|
this._setIconStyles(this.elements.main, 'icon');
|
||||||
return this.elements.main;
|
return this.elements.main;
|
||||||
|
|
|
@ -1030,6 +1030,12 @@ a.add-datalayer:hover,
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
max-width: 24px !important;
|
max-width: 24px !important;
|
||||||
}
|
}
|
||||||
|
.umap-div-icon .icon_container span,
|
||||||
|
.umap-drop-icon .icon_container span {
|
||||||
|
vertical-align: middle;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
.umap-circle-icon {
|
.umap-circle-icon {
|
||||||
border: 1px solid white;
|
border: 1px solid white;
|
||||||
border-radius: 10px 10px 10px 10px;
|
border-radius: 10px 10px 10px 10px;
|
||||||
|
|
|
@ -31,6 +31,38 @@ describe('L.U.Marker', function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#iconSymbolChange()', function () {
|
||||||
|
|
||||||
|
it('should change icon symbol', function () {
|
||||||
|
enableEdit();
|
||||||
|
happen.click(qs('div.umap-drop-icon'));
|
||||||
|
happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit'));
|
||||||
|
changeInputValue(qs('form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]'), '1');
|
||||||
|
assert.equal(qs('div.umap-drop-icon span').textContent, '1');
|
||||||
|
changeInputValue(qs('form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]'), '{name}');
|
||||||
|
assert.equal(qs('div.umap-drop-icon span').textContent, 'test');
|
||||||
|
clickCancel();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#iconClassChange()', function () {
|
||||||
|
|
||||||
|
it('should change icon class', function () {
|
||||||
|
enableEdit();
|
||||||
|
happen.click(qs('div.umap-drop-icon'));
|
||||||
|
happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit'));
|
||||||
|
changeSelectValue(qs('form#umap-feature-shape-properties .umap-field-iconClass select[name=iconClass]'), 'Circle');
|
||||||
|
assert.notOk(qs('div.umap-drop-icon'));
|
||||||
|
assert.ok(qs('div.umap-circle-icon'));
|
||||||
|
happen.click(qs('form#umap-feature-shape-properties .umap-field-iconClass .undefine'));
|
||||||
|
assert.notOk(qs('div.umap-circle-icon'));
|
||||||
|
assert.ok(qs('div.umap-drop-icon'));
|
||||||
|
clickCancel();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#clone', function () {
|
describe('#clone', function () {
|
||||||
|
|
||||||
it('should clone marker', function () {
|
it('should clone marker', function () {
|
||||||
|
|
|
@ -44,6 +44,7 @@ var clickCancel = function () {
|
||||||
var changeInputValue = function (input, value) {
|
var changeInputValue = function (input, value) {
|
||||||
input.value = value;
|
input.value = value;
|
||||||
happen.once(input, {type: 'input'});
|
happen.once(input, {type: 'input'});
|
||||||
|
happen.once(input, {type: 'blur'});
|
||||||
};
|
};
|
||||||
var changeSelectValue = function (path_or_select, value) {
|
var changeSelectValue = function (path_or_select, value) {
|
||||||
if (typeof path_or_select === 'string') path_or_select = qs(path_or_select);
|
if (typeof path_or_select === 'string') path_or_select = qs(path_or_select);
|
||||||
|
|
Loading…
Reference in a new issue