From 3dee85226f1fa6a29a03d598c8c11be1c5dba4ca Mon Sep 17 00:00:00 2001
From: John Martin
Date: Tue, 15 Oct 2013 15:10:09 +0100
Subject: [PATCH] [#1262] First working version of the JS module for image
uploading
---
.../base/javascript/modules/image-upload.js | 147 ++++++++++++++++++
ckan/public/base/javascript/resource.config | 1 +
ckan/public/base/less/forms.less | 34 ++++
ckan/templates/group/snippets/group_form.html | 10 +-
ckan/templates/macros/form.html | 27 ++++
.../snippets/organization_form.html | 9 +-
6 files changed, 211 insertions(+), 17 deletions(-)
create mode 100644 ckan/public/base/javascript/modules/image-upload.js
diff --git a/ckan/public/base/javascript/modules/image-upload.js b/ckan/public/base/javascript/modules/image-upload.js
new file mode 100644
index 00000000000..69ca8f93c05
--- /dev/null
+++ b/ckan/public/base/javascript/modules/image-upload.js
@@ -0,0 +1,147 @@
+/* Image Upload
+ *
+ *
+ * Options
+ * - id: what's the id of the context?
+ */
+this.ckan.module('image-upload', function($, _) {
+ return {
+ /* options object can be extended using data-module-* attributes */
+ options: {
+ is_url: true,
+ has_image: false,
+ i18n: {
+ upload: _('From computer'),
+ url: _('From web'),
+ remove: _('Remove'),
+ label: _('Upload image'),
+ label_url: _('Image URL'),
+ remove_tooltip: _('Reset this')
+ },
+ template: [
+ ''
+ ].join("\n")
+ },
+
+ state: {
+ attached: 1,
+ blank: 2,
+ web: 3
+ },
+
+ /* Initialises the module setting up elements and event listeners.
+ *
+ * Returns nothing.
+ */
+ initialize: function () {
+ $.proxyAll(this, /_on/);
+ var options = this.options;
+
+ // firstly setup the fields
+ this.input = $('input[name="image_upload"]', this.el);
+ this.field_url = $('input[name="image_url"]', this.el).parents('.control-group');
+ this.field_image = this.input.parents('.control-group');
+
+ var checkbox = $('input[name="clear_upload"]', this.el);
+ if (checkbox.length > 0) {
+ options.has_image = true;
+ checkbox.parents('.control-group').remove();
+ }
+
+ this.field_clear = $('')
+ .appendTo(this.el);
+
+ this.button_url = $(' '+this.i18n('url')+'')
+ .on('click', this._onFromWeb)
+ .insertAfter(this.input);
+
+ this.button_upload = $(''+this.i18n('upload')+'')
+ .insertAfter(this.input);
+
+ this.button_remove = $('')
+ .text(this.i18n('remove'))
+ .on('click', this._onRemove)
+ .insertAfter(this.button_upload);
+
+ $('')
+ .prop('title', this.i18n('remove_tooltip'))
+ .on('click', this._onRemove)
+ .insertBefore($('input', this.field_url));
+
+ $('label[for="field-image-upload"]').text(this.i18n('label'));
+
+ this.input
+ .on('mouseover', this._onInputMouseOver)
+ .on('mouseout', this._onInputMouseOut)
+ .on('change', this._onInputChange)
+ .css('width', this.button_upload.outerWidth())
+ .hide();
+
+ this.fields = $('')
+ .add(this.button_remove)
+ .add(this.button_upload)
+ .add(this.button_url)
+ .add(this.input)
+ .add(this.field_url)
+ .add(this.field_image);
+
+ if (options.is_url) {
+ this.changeState(this.state.web);
+ } else if (options.has_image) {
+ this.changeState(this.state.attached);
+ } else {
+ this.changeState(this.state.blank);
+ }
+
+ },
+
+ changeState: function(state) {
+ this.fields.hide();
+ if (state == this.state.blank) {
+ this.button_upload
+ .add(this.field_image)
+ .add(this.button_url)
+ .add(this.input)
+ .show();
+ } else if (state == this.state.attached) {
+ this.button_remove
+ .add(this.field_image)
+ .show();
+ } else if (state == this.state.web) {
+ this.field_url
+ .show();
+ }
+ },
+
+ _onFromWeb: function() {
+ this.changeState(this.state.web);
+ $('input', this.field_url).focus();
+ if (this.options.has_image) {
+ this.field_clear.val('true');
+ }
+ },
+
+ _onRemove: function() {
+ this.changeState(this.state.blank);
+ $('input', this.field_url).val('');
+ if (this.options.has_image) {
+ this.field_clear.val('true');
+ }
+ },
+
+ _onInputChange: function() {
+ this.file_name = this.input.val();
+ this.field_clear.val('');
+ this.changeState(this.state.attached);
+ },
+
+ _onInputMouseOver: function() {
+ this.button_upload.addClass('hover');
+ },
+
+ _onInputMouseOut: function() {
+ this.button_upload.removeClass('hover');
+ }
+
+ }
+});
diff --git a/ckan/public/base/javascript/resource.config b/ckan/public/base/javascript/resource.config
index b1a7302d9e8..564da811a6e 100644
--- a/ckan/public/base/javascript/resource.config
+++ b/ckan/public/base/javascript/resource.config
@@ -38,6 +38,7 @@ ckan =
modules/table-toggle-more.js
modules/dataset-visibility.js
modules/media-grid.js
+ modules/image-upload.js
main =
apply_html_class
diff --git a/ckan/public/base/less/forms.less b/ckan/public/base/less/forms.less
index 289439c291a..2bfc1a2d492 100644
--- a/ckan/public/base/less/forms.less
+++ b/ckan/public/base/less/forms.less
@@ -670,3 +670,37 @@ textarea {
.box-shadow(none);
}
}
+
+.js .image-upload {
+ #field-image-upload {
+ cursor: pointer;
+ position: absolute;
+ z-index: 1;
+ .opacity(0);
+ }
+ .controls {
+ position: relative;
+ }
+ .btn {
+ position: relative;
+ top: 0;
+ margin-right: 10px;
+ &.hover {
+ color: @grayDark;
+ text-decoration: none;
+ background-position: 0 -15px;
+ .transition(background-position .1s linear);
+ }
+ }
+ .btn-remove-url {
+ position: absolute;
+ margin-right: 0;
+ top: 4px;
+ right: 5px;
+ padding: 0 4px;
+ .border-radius(100px);
+ .icon-remove {
+ margin-right: 0;
+ }
+ }
+}
diff --git a/ckan/templates/group/snippets/group_form.html b/ckan/templates/group/snippets/group_form.html
index 322f9ebff8a..cd19912d66b 100644
--- a/ckan/templates/group/snippets/group_form.html
+++ b/ckan/templates/group/snippets/group_form.html
@@ -19,15 +19,7 @@
{{ form.markdown('description', label=_('Description'), id='field-description', placeholder=_('A little information about my group...'), value=data.description, error=errors.description) }}
- {{ form.input('image_url', label=_('Image URL'), id='field-image-url', placeholder=_('http://example.com/my-image.jpg'), value=data.image_url, error=errors.image_url, classes=['control-full']) }}
-
-
- {% if h.uploads_enabled() %}
- {{ form.input('image_upload', label=_('Image Upload'), id='field-image-upload', type='file', placeholder='', value=data.image_url, error='', classes=['control-full']) }}
- {% if data.image_url and not data.image_url.startswith('http') %}
- {{ form.checkbox('clear_upload', label=_('Clear Upload'), id='field-clear-upload', value='true', error='', classes=['control-full']) }}
- {% endif %}
- {% endif %}
+ {{ form.image_upload(data, errors, image_url=c.group_dict.image_display_url, is_upload_enabled=h.uploads_enabled()) }}
{% endblock %}
diff --git a/ckan/templates/macros/form.html b/ckan/templates/macros/form.html
index 497dea6bf02..7dc044ccca2 100644
--- a/ckan/templates/macros/form.html
+++ b/ckan/templates/macros/form.html
@@ -395,3 +395,30 @@
{% endmacro %}
+{#
+Builds a file upload for input
+
+Example
+ {% import 'macros/form.html' as form %}
+ {{ form.image_upload(data, errors, is_upload_enabled=true) }}
+
+#}
+{% macro image_upload(data, errors, image_url=false, is_upload_enabled=false, placeholder=false) %}
+ {% set placeholder = placeholder if placeholder else _('http://example.com/my-image.jpg') %}
+ {% set has_uploaded_data = data.image_url and not data.image_url.startswith('http') %}
+ {% set is_url = data.image_url and data.image_url.startswith('http') %}
+
+ {% if is_upload_enabled %}{% endif %}
+
+ {{ input('image_url', label=_('Image URL'), id='field-image-url', placeholder=placeholder, value=data.image_url, error=errors.image_url, classes=['control-full']) }}
+
+ {% if is_upload_enabled %}
+ {{ input('image_upload', label=_('Image Upload'), id='field-image-upload', type='file', placeholder='', value='', error='', classes=['control-full']) }}
+ {% if has_uploaded_data %}
+ {{ checkbox('clear_upload', label=_('Clear Upload'), id='field-clear-upload', value='true', error='', classes=['control-full']) }}
+ {% endif %}
+ {% endif %}
+
+ {% if is_upload_enabled %}
{% endif %}
+
+{% endmacro %}
diff --git a/ckan/templates/organization/snippets/organization_form.html b/ckan/templates/organization/snippets/organization_form.html
index 0a2134e89f7..0b97b958d38 100644
--- a/ckan/templates/organization/snippets/organization_form.html
+++ b/ckan/templates/organization/snippets/organization_form.html
@@ -19,14 +19,7 @@
{{ form.markdown('description', label=_('Description'), id='field-description', placeholder=_('A little information about my organization...'), value=data.description, error=errors.description) }}
- {{ form.input('image_url', label=_('Image URL'), id='field-image-url', placeholder=_('http://example.com/my-image.jpg'), value=data.image_url, error=errors.image_url, classes=['control-full']) }}
-
- {% if h.uploads_enabled() %}
- {{ form.input('image_upload', label=_('Image Upload'), id='field-image-upload', type='file', placeholder='', value=data.image_url, error='', classes=['control-full']) }}
- {% if data.image_url and not data.image_url.startswith('http') %}
- {{ form.checkbox('clear_upload', label=_('Clear Upload'), id='field-clear-upload', value='true', error='', classes=['control-full']) }}
- {% endif %}
- {% endif %}
+ {{ form.image_upload(data, errors, image_url=c.group_dict.image_display_url, is_upload_enabled=h.uploads_enabled()) }}
{% endblock %}