hydra-editor 2.0.0 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/hydra-editor/field_manager.es6 +149 -0
- data/app/assets/javascripts/hydra-editor/hydra-editor.js +2 -0
- data/app/assets/javascripts/hydra-editor/manage_repeating_fields.js +19 -134
- data/app/assets/stylesheets/hydra-editor/multi_value_fields.scss +34 -11
- data/lib/hydra_editor/engine.rb +3 -0
- data/lib/hydra_editor/version.rb +1 -1
- metadata +33 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae1264f3bb248877d4bb16d74eea0136075dffbe
|
4
|
+
data.tar.gz: 3aeb4937cbc2cfea2b3124187f1720393ac90753
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cae0f7bd208b58511724e4192a8241808dee3b5f8be1a5be074bb612d46f590624cb9e4ab5a2c76456a97d440495466ce5e9807333b53f627d67e06ce16d56d3
|
7
|
+
data.tar.gz: a424534ddced8cd2a29217f66e9d93294886dad16d5f135f9eb933b94acaf0fa48540b24007ea9f385a2a0b937f42edc81146737a0546b701fc45bbed18cd90b
|
@@ -0,0 +1,149 @@
|
|
1
|
+
export class FieldManager {
|
2
|
+
constructor(element, options) {
|
3
|
+
this.element = $(element);
|
4
|
+
this.options = options;
|
5
|
+
|
6
|
+
this.options.label = this.getFieldLabel(this.element, options)
|
7
|
+
|
8
|
+
this.adder = this.createAddHtml(this.options);
|
9
|
+
this.remover = this.createRemoveHtml(this.options);
|
10
|
+
|
11
|
+
this.controls = $(options.controlsHtml);
|
12
|
+
this.fieldWrapperClass = options.fieldWrapperClass;
|
13
|
+
this.warningClass = options.warningClass;
|
14
|
+
this.listClass = options.listClass;
|
15
|
+
|
16
|
+
this.init();
|
17
|
+
}
|
18
|
+
|
19
|
+
init() {
|
20
|
+
this._addInitialClasses();
|
21
|
+
this._addAriaLiveRegions()
|
22
|
+
this._appendControls();
|
23
|
+
this._attachEvents();
|
24
|
+
this._addCallbacks();
|
25
|
+
}
|
26
|
+
|
27
|
+
_addInitialClasses() {
|
28
|
+
this.element.addClass("managed");
|
29
|
+
$(this.fieldWrapperClass, this.element).addClass("input-group input-append");
|
30
|
+
}
|
31
|
+
|
32
|
+
_addAriaLiveRegions() {
|
33
|
+
$(this.element).find('.listing').attr('aria-live', 'polite')
|
34
|
+
}
|
35
|
+
|
36
|
+
_appendControls() {
|
37
|
+
$(this.fieldWrapperClass, this.element).append(this.controls);
|
38
|
+
$(this.fieldWrapperClass + ' .field-controls', this.element).append(this.remover);
|
39
|
+
|
40
|
+
if ($(this.element).find('.add').length == 0) {
|
41
|
+
$(this.element).find(this.listClass).after(this.adder);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
_attachEvents() {
|
46
|
+
this.element.on('click', '.remove', (e) => this.removeFromList(e));
|
47
|
+
this.element.on('click', '.add', (e) =>this.addToList(e));
|
48
|
+
}
|
49
|
+
|
50
|
+
_addCallbacks() {
|
51
|
+
this.element.bind('managed_field:add', this.options.add);
|
52
|
+
this.element.bind('managed_field:remove', this.options.remove);
|
53
|
+
}
|
54
|
+
|
55
|
+
_manageFocus() {
|
56
|
+
$(this.element).find(this.listClass).children('li').last().find('.form-control').focus();
|
57
|
+
}
|
58
|
+
|
59
|
+
addToList( event ) {
|
60
|
+
event.preventDefault();
|
61
|
+
let $listing = $(event.target).closest('.multi_value').find(this.listClass)
|
62
|
+
let $activeField = $listing.children('li').last()
|
63
|
+
|
64
|
+
if (this.inputIsEmpty($activeField)) {
|
65
|
+
this.displayEmptyWarning();
|
66
|
+
} else {
|
67
|
+
this.clearEmptyWarning();
|
68
|
+
$listing.append(this._newField($activeField));
|
69
|
+
}
|
70
|
+
|
71
|
+
this._manageFocus()
|
72
|
+
}
|
73
|
+
|
74
|
+
inputIsEmpty($activeField) {
|
75
|
+
return $activeField.children('input.multi-text-field').val() === '';
|
76
|
+
}
|
77
|
+
|
78
|
+
_newField ($activeField) {
|
79
|
+
var $newField = this.createNewField($activeField);
|
80
|
+
return $newField;
|
81
|
+
}
|
82
|
+
|
83
|
+
createNewField($activeField) {
|
84
|
+
let $newField = $activeField.clone();
|
85
|
+
let $newChildren = $newField.children('input');
|
86
|
+
$newChildren.val('').removeProp('required');
|
87
|
+
$newChildren.first().focus();
|
88
|
+
this.element.trigger("managed_field:add", $newChildren.first());
|
89
|
+
return $newField;
|
90
|
+
}
|
91
|
+
|
92
|
+
_changeControlsToRemove($activeField) {
|
93
|
+
var $removeControl = this.remover.clone();
|
94
|
+
$activeFieldControls = $activeField.children('.field-controls');
|
95
|
+
$('.add', $activeFieldControls).remove();
|
96
|
+
$activeFieldControls.prepend($removeControl);
|
97
|
+
}
|
98
|
+
|
99
|
+
clearEmptyWarning() {
|
100
|
+
let $listing = $(this.listClass, this.element)
|
101
|
+
$listing.children(this.warningClass).remove();
|
102
|
+
}
|
103
|
+
|
104
|
+
displayEmptyWarning() {
|
105
|
+
let $listing = $(this.listClass, this.element)
|
106
|
+
var $warningMessage = $("<div class=\'message has-warning\'>cannot add another with empty field</div>");
|
107
|
+
$listing.children(this.warningClass).remove();
|
108
|
+
$listing.append($warningMessage);
|
109
|
+
}
|
110
|
+
|
111
|
+
removeFromList( event ) {
|
112
|
+
event.preventDefault();
|
113
|
+
var $listing = $(event.target).closest('.multi_value').find(this.listClass)
|
114
|
+
var $field = $(event.target).parents(this.fieldWrapperClass).remove();
|
115
|
+
this.element.trigger("managed_field:remove", $field);
|
116
|
+
|
117
|
+
this._manageFocus();
|
118
|
+
}
|
119
|
+
|
120
|
+
destroy() {
|
121
|
+
$(this.fieldWrapperClass, this.element).removeClass("input-append");
|
122
|
+
this.element.removeClass("managed");
|
123
|
+
}
|
124
|
+
|
125
|
+
getFieldLabel($element, options) {
|
126
|
+
var label = '';
|
127
|
+
var $label = $element.find("label");
|
128
|
+
|
129
|
+
if ($label.size && options.labelControls) {
|
130
|
+
var label = $label.data('label') || $.trim($label.contents().filter(function() { return this.nodeType === 3; }).text());
|
131
|
+
label = ' ' + label;
|
132
|
+
}
|
133
|
+
|
134
|
+
return label;
|
135
|
+
}
|
136
|
+
|
137
|
+
createAddHtml(options) {
|
138
|
+
var $addHtml = $(options.addHtml);
|
139
|
+
$addHtml.find('.controls-add-text').html(options.addText + options.label);
|
140
|
+
return $addHtml;
|
141
|
+
}
|
142
|
+
|
143
|
+
createRemoveHtml(options) {
|
144
|
+
var $removeHtml = $(options.removeHtml);
|
145
|
+
$removeHtml.find('.controls-remove-text').html(options.removeText);
|
146
|
+
$removeHtml.find('.controls-field-name-text').html(options.label);
|
147
|
+
return $removeHtml;
|
148
|
+
}
|
149
|
+
}
|
@@ -2,150 +2,35 @@
|
|
2
2
|
// There are a lot of assumptions about the structure of the classes and elements.
|
3
3
|
// These assumptions are reflected in the MultiValueInput class.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
this.remover = $(options.removeButtonHtml);
|
12
|
-
this.adder = $(options.addButtonHtml);
|
13
|
-
|
14
|
-
this.fieldWrapperClass = options.fieldWrapperClass;
|
15
|
-
this.warningClass = options.warningClass;
|
16
|
-
this.listClass = options.listClass;
|
17
|
-
|
18
|
-
this.init();
|
19
|
-
}
|
20
|
-
|
21
|
-
FieldManager.prototype = {
|
22
|
-
init: function () {
|
23
|
-
this._addInitialClasses();
|
24
|
-
this._appendControls();
|
25
|
-
this._attachEvents();
|
26
|
-
this._addCallbacks();
|
27
|
-
},
|
28
|
-
|
29
|
-
_addInitialClasses: function () {
|
30
|
-
this.element.addClass("managed");
|
31
|
-
$(this.fieldWrapperClass, this.element).addClass("input-group input-append");
|
32
|
-
},
|
33
|
-
|
34
|
-
_appendControls: function() {
|
35
|
-
$(this.fieldWrapperClass, this.element).append(this.controls);
|
36
|
-
$(this.fieldWrapperClass+':not(:last-child) .field-controls', this.element).append(this.remover);
|
37
|
-
$('.field-controls:last', this.element).append(this.adder);
|
38
|
-
},
|
39
|
-
|
40
|
-
_attachEvents: function() {
|
41
|
-
var _this = this;
|
42
|
-
this.element.on('click', '.remove', function (e) {
|
43
|
-
_this.removeFromList(e);
|
44
|
-
});
|
45
|
-
this.element.on('click', '.add', function (e) {
|
46
|
-
_this.addToList(e);
|
47
|
-
});
|
48
|
-
},
|
49
|
-
|
50
|
-
_addCallbacks: function() {
|
51
|
-
this.element.bind('managed_field:add', this.options.add);
|
52
|
-
this.element.bind('managed_field:remove', this.options.remove);
|
53
|
-
},
|
54
|
-
|
55
|
-
addToList: function( event ) {
|
56
|
-
event.preventDefault();
|
57
|
-
var $activeField = $(event.target).parents(this.fieldWrapperClass)
|
58
|
-
|
59
|
-
if (this.inputIsEmpty($activeField)) {
|
60
|
-
this.displayEmptyWarning();
|
61
|
-
} else {
|
62
|
-
var $listing = $(this.listClass, this.element);
|
63
|
-
this.clearEmptyWarning();
|
64
|
-
$listing.append(this._newField($activeField));
|
65
|
-
}
|
66
|
-
},
|
67
|
-
|
68
|
-
inputIsEmpty: function($activeField) {
|
69
|
-
return $activeField.children('input.multi-text-field').val() === '';
|
70
|
-
},
|
71
|
-
|
72
|
-
_newField: function ($activeField) {
|
73
|
-
var $newField = this.createNewField($activeField);
|
74
|
-
// _changeControlsToRemove must come after createNewField
|
75
|
-
// or the new field will not have an add button
|
76
|
-
this._changeControlsToRemove($activeField);
|
77
|
-
return $newField;
|
78
|
-
},
|
79
|
-
|
80
|
-
createNewField: function($activeField) {
|
81
|
-
$newField = $activeField.clone();
|
82
|
-
$newChildren = $newField.children('input');
|
83
|
-
$newChildren.val('').removeProp('required');
|
84
|
-
$newChildren.first().focus();
|
85
|
-
this.element.trigger("managed_field:add", $newChildren.first());
|
86
|
-
return $newField
|
87
|
-
},
|
88
|
-
|
89
|
-
_changeControlsToRemove: function($activeField) {
|
90
|
-
var $removeControl = this.remover.clone();
|
91
|
-
$activeFieldControls = $activeField.children('.field-controls');
|
92
|
-
$('.add', $activeFieldControls).remove();
|
93
|
-
$activeFieldControls.prepend($removeControl);
|
94
|
-
},
|
95
|
-
|
96
|
-
clearEmptyWarning: function() {
|
97
|
-
$listing = $(this.listClass, this.element),
|
98
|
-
$listing.children(this.warningClass).remove();
|
99
|
-
},
|
100
|
-
|
101
|
-
displayEmptyWarning: function () {
|
102
|
-
$listing = $(this.listClass, this.element)
|
103
|
-
var $warningMessage = $("<div class=\'message has-warning\'>cannot add new empty field</div>");
|
104
|
-
$listing.children(this.warningClass).remove();
|
105
|
-
$listing.append($warningMessage);
|
106
|
-
},
|
107
|
-
|
108
|
-
removeFromList: function( event ) {
|
109
|
-
event.preventDefault();
|
110
|
-
|
111
|
-
var field = $(event.target).parents(this.fieldWrapperClass)
|
112
|
-
field.remove();
|
113
|
-
|
114
|
-
this.element.trigger("managed_field:remove", field);
|
115
|
-
},
|
116
|
-
|
117
|
-
destroy: function() {
|
118
|
-
$(this.fieldWrapperClass, this.element).removeClass("input-append");
|
119
|
-
this.element.removeClass( "managed" );
|
120
|
-
}
|
121
|
-
}
|
5
|
+
(function($){
|
6
|
+
var DEFAULTS = {
|
7
|
+
/* callback to run after add is called */
|
8
|
+
add: null,
|
9
|
+
/* callback to run after remove is called */
|
10
|
+
remove: null,
|
122
11
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
remove: null,
|
12
|
+
controlsHtml: '<span class=\"input-group-btn field-controls\">',
|
13
|
+
fieldWrapperClass: '.field-wrapper',
|
14
|
+
warningClass: '.has-warning',
|
15
|
+
listClass: '.listing',
|
128
16
|
|
17
|
+
addHtml: '<button type=\"button\" class=\"btn btn-link add\"><span class=\"glyphicon glyphicon-plus\"></span><span class="controls-add-text"></span></button>',
|
18
|
+
addText: 'Add another',
|
129
19
|
|
130
|
-
|
131
|
-
|
132
|
-
removeButtonHtml: "<button type=\"button\" class=\"btn btn-danger remove\"><i class=\"icon-white glyphicon-minus\"></i><span>Remove</span></button>",
|
133
|
-
warningClass: '.has-warning',
|
134
|
-
listClass: '.listing',
|
135
|
-
fieldWrapperClass: '.field-wrapper'
|
136
|
-
}
|
20
|
+
removeHtml: '<button type=\"button\" class=\"btn btn-link remove\"><span class=\"glyphicon glyphicon-remove\"></span><span class="controls-remove-text"></span> <span class=\"sr-only\"> previous <span class="controls-field-name-text">field</span></span></button>',
|
21
|
+
removeText: 'Remove',
|
137
22
|
|
138
|
-
|
139
|
-
}
|
23
|
+
labelControls: true,
|
24
|
+
}
|
140
25
|
|
141
|
-
(function($){
|
142
26
|
$.fn.manage_fields = function(option) {
|
27
|
+
var hydra_editor = require('hydra-editor/field_manager')
|
143
28
|
return this.each(function() {
|
144
29
|
var $this = $(this);
|
145
30
|
var data = $this.data('manage_fields');
|
146
|
-
var options = $.extend({},
|
31
|
+
var options = $.extend({}, DEFAULTS, $this.data(), typeof option == 'object' && option);
|
147
32
|
|
148
|
-
if (!data) $this.data('manage_fields', (data = new
|
33
|
+
if (!data) $this.data('manage_fields', (data = new hydra_editor.FieldManager(this, options)));
|
149
34
|
})
|
150
35
|
}
|
151
36
|
})(jQuery);
|
@@ -1,6 +1,14 @@
|
|
1
1
|
.multi_value {
|
2
|
-
.btn.
|
3
|
-
|
2
|
+
.btn.remove {
|
3
|
+
color: $brand-danger;
|
4
|
+
}
|
5
|
+
|
6
|
+
.btn.remove, .btn.add {
|
7
|
+
text-decoration: underline;
|
8
|
+
}
|
9
|
+
|
10
|
+
.btn.add {
|
11
|
+
padding-left: 0;
|
4
12
|
}
|
5
13
|
|
6
14
|
.field-wrapper {
|
@@ -11,20 +19,19 @@
|
|
11
19
|
margin-left: 0;
|
12
20
|
max-width: 40em;
|
13
21
|
padding-left: 0px;
|
14
|
-
|
15
|
-
margin-bottom: 1px;
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
.field-controls span {
|
20
|
-
margin-left:.2em;
|
22
|
+
margin-bottom: 0;
|
21
23
|
}
|
22
24
|
|
23
25
|
.field-controls {
|
24
26
|
margin-left: 2em;
|
25
27
|
}
|
26
28
|
|
27
|
-
.
|
29
|
+
.remove .glyphicon-remove,
|
30
|
+
.add .glyphicon-plus {
|
31
|
+
margin-right: 0.3rem
|
32
|
+
}
|
33
|
+
|
34
|
+
.message {
|
28
35
|
background-size: 40px 40px;
|
29
36
|
background-image: linear-gradient(135deg, rgba(255, 255, 255, .05) 25%, transparent 25%,
|
30
37
|
transparent 50%, rgba(255, 255, 255, .05) 50%, rgba(255, 255, 255, .05) 75%,
|
@@ -39,7 +46,7 @@
|
|
39
46
|
border-radius: $border-radius-base;
|
40
47
|
}
|
41
48
|
|
42
|
-
.has-error{
|
49
|
+
.has-error {
|
43
50
|
background-color: #de4343;
|
44
51
|
border-color: #c43d3d;
|
45
52
|
}
|
@@ -48,6 +55,22 @@
|
|
48
55
|
background-color: #eaaf51;
|
49
56
|
border-color: #d99a36;
|
50
57
|
}
|
58
|
+
|
59
|
+
.listing li:not(:last-child) {
|
60
|
+
margin-bottom: 0.5rem;
|
61
|
+
}
|
62
|
+
|
63
|
+
.listing li:only-of-type {
|
64
|
+
width: 100%;
|
65
|
+
|
66
|
+
input {
|
67
|
+
border-radius: 4px;
|
68
|
+
}
|
69
|
+
|
70
|
+
.remove {
|
71
|
+
display: none;
|
72
|
+
}
|
73
|
+
}
|
51
74
|
}
|
52
75
|
|
53
76
|
// The contributor listing needs some normalization
|
data/lib/hydra_editor/engine.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module HydraEditor
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
require 'simple_form'
|
4
|
+
require 'sprockets/es6'
|
5
|
+
require 'almond-rails'
|
4
6
|
engine_name 'hydra_editor'
|
5
7
|
config.eager_load_paths += %W(
|
6
8
|
#{config.root}/app/helpers/concerns
|
@@ -8,6 +10,7 @@ module HydraEditor
|
|
8
10
|
)
|
9
11
|
initializer 'hydra-editor.initialize' do
|
10
12
|
require 'cancan'
|
13
|
+
Sprockets::ES6.configuration = { 'modules' => 'amd', 'moduleIds' => true }
|
11
14
|
end
|
12
15
|
end
|
13
16
|
end
|
data/lib/hydra_editor/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra-editor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -67,6 +67,34 @@ dependencies:
|
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 3.1.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: sprockets-es6
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: almond-rails
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 0.0.2
|
91
|
+
type: :runtime
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 0.0.2
|
70
98
|
- !ruby/object:Gem::Dependency
|
71
99
|
name: sqlite3
|
72
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,6 +246,7 @@ files:
|
|
218
246
|
- README.md
|
219
247
|
- Rakefile
|
220
248
|
- app/assets/javascripts/hydra-editor/editMetadata.js
|
249
|
+
- app/assets/javascripts/hydra-editor/field_manager.es6
|
221
250
|
- app/assets/javascripts/hydra-editor/hydra-editor.js
|
222
251
|
- app/assets/javascripts/hydra-editor/manage_repeating_fields.js
|
223
252
|
- app/assets/stylesheets/hydra-editor/hydra-editor.scss
|
@@ -259,9 +288,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
259
288
|
version: '0'
|
260
289
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
261
290
|
requirements:
|
262
|
-
- - "
|
291
|
+
- - ">"
|
263
292
|
- !ruby/object:Gem::Version
|
264
|
-
version:
|
293
|
+
version: 1.3.1
|
265
294
|
requirements: []
|
266
295
|
rubyforge_project:
|
267
296
|
rubygems_version: 2.5.1
|