Skip to content

Commit 846feb6

Browse files
committed
FileUpload now triggers dependsOn event
form.beforeRefresh event now uses dataholder pattern Improve exception handling in ControllerBehavior
1 parent e3ba89b commit 846feb6

File tree

5 files changed

+86
-35
lines changed

5 files changed

+86
-35
lines changed

modules/backend/behaviors/FormController.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ public function initForm($model, $context = null)
125125
$this->controller->formExtendFields($this->formWidget, $fields);
126126
});
127127

128-
$this->formWidget->bindEvent('form.beforeRefresh', function ($saveData) {
129-
return $this->controller->formExtendRefreshData($this->formWidget, $saveData);
128+
$this->formWidget->bindEvent('form.beforeRefresh', function ($holder) {
129+
$result = $this->controller->formExtendRefreshData($this->formWidget, $holder->data);
130+
if (is_array($result)) $holder->data = $result;
130131
});
131132

132133
$this->formWidget->bindEvent('form.refreshFields', function ($fields) {

modules/backend/classes/ControllerBehavior.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public function getConfig($name = null, $default = null)
103103
* Loop the remaining key parts and build a result
104104
*/
105105
foreach ($keyParts as $key) {
106-
if (!array_key_exists($key, $result)) {
106+
if (!is_array($result) || !array_key_exists($key, $result)) {
107107
return $default;
108108
}
109109

modules/backend/formwidgets/fileupload/assets/js/fileupload.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@
164164
$('.upload-remove-button', $preview).data('request-data', { file_id: response.id })
165165
$img.attr('src', response.thumb)
166166
}
167+
168+
/*
169+
* Trigger change event (Compatability with october.form.js)
170+
*/
171+
this.$el.closest('[data-field-name]').trigger('change.oc.formwidget')
167172
}
168173

169174
FileUpload.prototype.onUploadError = function(file, error) {

modules/backend/widgets/Form.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ protected function prepareVars()
287287
*/
288288
public function setFormValues($data = null)
289289
{
290-
if ($data == null) {
290+
if ($data === null) {
291291
$data = $this->getSaveData();
292292
}
293293

@@ -312,12 +312,10 @@ public function onRefresh()
312312
/*
313313
* Extensibility
314314
*/
315-
$eventResults = $this->fireEvent('form.beforeRefresh', [$saveData]) +
316-
Event::fire('backend.form.beforeRefresh', [$this, $saveData]);
317-
318-
foreach ($eventResults as $eventResult) {
319-
$saveData = $eventResult + $saveData;
320-
}
315+
$dataHolder = (object) ['data' => $saveData];
316+
$this->fireEvent('form.beforeRefresh', [$dataHolder]);
317+
Event::fire('backend.form.beforeRefresh', [$this, $dataHolder]);
318+
$saveData = $dataHolder->data;
321319

322320
/*
323321
* Set the form variables and prepare the widget
@@ -356,8 +354,10 @@ public function onRefresh()
356354
/*
357355
* Extensibility
358356
*/
359-
$eventResults = $this->fireEvent('form.refresh', [$result]) +
360-
Event::fire('backend.form.refresh', [$this, $result]);
357+
$eventResults = array_merge(
358+
$this->fireEvent('form.refresh', [$result]),
359+
Event::fire('backend.form.refresh', [$this, $result])
360+
);
361361

362362
foreach ($eventResults as $eventResult) {
363363
$result = $eventResult + $result;

modules/backend/widgets/form/assets/js/october.form.js

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,47 @@
55
* - Nil
66
*/
77
+function ($) { "use strict";
8+
var Base = $.oc.foundation.base,
9+
BaseProto = Base.prototype
810

911
var FormWidget = function (element, options) {
12+
this.$el = $(element)
13+
this.options = options || {}
1014

11-
var $el = this.$el = $(element);
15+
/*
16+
* Throttle dependency updating
17+
*/
18+
this.dependantUpdateInterval = 300
19+
this.dependantUpdateTimers = {}
20+
21+
$.oc.foundation.controlUtils.markDisposable(element)
22+
Base.call(this)
23+
this.init()
24+
}
1225

13-
this.$form = $el.closest('form')
14-
this.options = options || {};
26+
FormWidget.prototype = Object.create(BaseProto)
27+
FormWidget.prototype.constructor = FormWidget
28+
29+
FormWidget.prototype.init = function() {
30+
31+
this.$form = this.$el.closest('form')
1532

1633
this.bindDependants()
1734
this.bindCheckboxlist()
1835
this.toggleEmptyTabs()
1936
this.bindCollapsibleSections()
37+
38+
this.$el.one('dispose-control', this.proxy(this.dispose))
2039
}
2140

22-
FormWidget.DEFAULTS = {
23-
refreshHandler: null
41+
FormWidget.prototype.dispose = function() {
42+
this.$el.off('dispose-control', this.proxy(this.dispose))
43+
this.$el.removeData('oc.formwidget')
44+
45+
this.$el = null
46+
this.options = null
47+
48+
BaseProto.dispose.call(this)
2449
}
2550

2651
/*
@@ -51,13 +76,12 @@
5176
FormWidget.prototype.bindDependants = function() {
5277
var self = this,
5378
form = this.$el,
54-
formEl = this.$form,
5579
fieldMap = {}
5680

5781
/*
5882
* Map master and slave field map
5983
*/
60-
form.find('[data-field-depends]').each(function(){
84+
form.find('[data-field-depends]').each(function() {
6185
var name = $(this).data('field-name'),
6286
depends = $(this).data('field-depends')
6387

@@ -73,20 +97,37 @@
7397
* When a master is updated, refresh its slaves
7498
*/
7599
$.each(fieldMap, function(fieldName, toRefresh){
76-
form.find('[data-field-name="'+fieldName+'"]')
77-
.on('change', 'select, input', function(){
78-
formEl.request(self.options.refreshHandler, {
79-
data: toRefresh
80-
}).success(function(){
81-
self.toggleEmptyTabs()
82-
})
83-
84-
$.each(toRefresh.fields, function(index, field){
85-
form.find('[data-field-name="'+field+'"]:visible')
86-
.addClass('loading-indicator-container size-form-field')
87-
.loadIndicator()
88-
})
89-
})
100+
form
101+
.find('[data-field-name="'+fieldName+'"]')
102+
.on('change.oc.formwidget', $.proxy(self.onRefreshDependants, self, fieldName, toRefresh))
103+
})
104+
}
105+
106+
/*
107+
* Refresh a dependancy field
108+
* Uses a throttle to prevent duplicate calls and click spamming
109+
*/
110+
FormWidget.prototype.onRefreshDependants = function(fieldName, toRefresh) {
111+
var self = this,
112+
form = this.$el,
113+
formEl = this.$form
114+
115+
if (this.dependantUpdateTimers[fieldName] !== undefined) {
116+
window.clearTimeout(this.dependantUpdateTimers[fieldName])
117+
}
118+
119+
this.dependantUpdateTimers[fieldName] = window.setTimeout(function() {
120+
formEl.request(self.options.refreshHandler, {
121+
data: toRefresh
122+
}).success(function() {
123+
self.toggleEmptyTabs()
124+
})
125+
}, this.dependantUpdateInterval)
126+
127+
$.each(toRefresh.fields, function(index, field) {
128+
form.find('[data-field-name="'+field+'"]:visible')
129+
.addClass('loading-indicator-container size-form-field')
130+
.loadIndicator()
90131
})
91132
}
92133

@@ -99,7 +140,7 @@
99140
if (!tabControl.length)
100141
return
101142

102-
$('.tab-pane', tabControl).each(function(){
143+
$('.tab-pane', tabControl).each(function() {
103144
$('[data-target="#' + $(this).attr('id') + '"]', tabControl)
104145
.toggle(!!$('.form-group:not(:empty)', $(this)).length)
105146
})
@@ -123,6 +164,10 @@
123164
.nextUntil('.section-field').hide()
124165
}
125166

167+
FormWidget.DEFAULTS = {
168+
refreshHandler: null
169+
}
170+
126171
// FORM WIDGET PLUGIN DEFINITION
127172
// ============================
128173

@@ -157,7 +202,7 @@
157202
// FORM WIDGET DATA-API
158203
// ==============
159204

160-
$(document).render(function(){
205+
$(document).render(function() {
161206
$('[data-control="formwidget"]').formWidget();
162207
})
163208

0 commit comments

Comments
 (0)