Skip to content

Commit 372dec6

Browse files
committed
Documentation, send js events for UI to pick up
1 parent 1cc9015 commit 372dec6

File tree

3 files changed

+86
-6
lines changed

3 files changed

+86
-6
lines changed

README.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
[![Version](http://img.shields.io/packagist/v/fullscreeninteractive/silverstripe-manyfield.svg)](https://packagist.org/packages/fullscreeninteractive/silverstripe-manyfield)
44
[![License](http://img.shields.io/packagist/l/fullscreeninteractive/silverstripe-manyfield.svg)](license.md)
55

6-
A reusable approach to a form field which allows you to create and delete rows.
6+
A reusable approach to a form field which allows you to create and delete rows
7+
in Forms.
8+
9+
This is designed to work on the front-end with limited javascript (i.e it does
10+
not require `GridField` or entwine).
711

812
Each row can relate to a DataObject subclass or simply to be used to capture the
9-
data
13+
data as an array.
1014

1115
## Installation
1216

@@ -31,4 +35,47 @@ $fields = new FieldList(
3135
);
3236
```
3337

34-
Data will either be saved as `setSwabList($data)`, `SwabList` database field or in the `SwabList` relation.
38+
Data will either be saved as `setSwabList($data)`, `SwabList` database field or
39+
in the `SwabList` relation. If you are saving into a relation such as `HasMany`
40+
or `ManyMany` list then make sure you include a hidden field in your field list.
41+
42+
```
43+
$many = ManyField::create('SwabList', [
44+
HiddenField::create('ID', ''),
45+
TextField::create('Swab'),
46+
TextField::create('TestSite'),
47+
TextField::create('Description'),
48+
TextField::create('Material')
49+
]);
50+
```
51+
52+
## Sorting
53+
54+
Include a Hidden field `Sort` and make sure sorting is enabled.
55+
56+
```
57+
$many = ManyField::create('SwabList', [
58+
HiddenField::create('ID', ''),
59+
HiddenField::create('Sort', ''),
60+
TextField::create('TestSite')
61+
])->setCanSort(true);
62+
```
63+
64+
## Required Fields
65+
66+
$many = ManyField::create('SwabList', [
67+
TextField::create('TestSite')->setRequired(true)
68+
])->setCanSort(true);
69+
70+
## Javascript Events
71+
72+
If you have UI handlers that need to run when fields are added or removed
73+
(such as Date Pickers) create a handler on your `<body>` element and listen for
74+
either:
75+
76+
* `manyFieldAdded`
77+
* `manyFieldRemoved`
78+
79+
## Licence
80+
81+
BSD 3-Clause License

client/js/ManyField.src.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,21 @@
4242
parents.find('.manyfield__row').last().after(data)
4343

4444
wrapManyFields()
45+
46+
$('body').trigger('manyFieldAdded', {
47+
parents
48+
})
4549
})
4650
})
4751

4852
$('body').on('click', '.manyfield__remove', function() {
4953
var parent = $(this).parents('.manyfield__row')
5054

5155
parent.remove()
56+
57+
$('body').trigger('manyFieldRemoved', {
58+
parent
59+
})
5260
})
5361
})
5462
})(jQuery)

src/ManyField.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,17 @@ public function AddLink()
268268
);
269269
}
270270

271+
public function setValue($value, $data = null)
272+
{
273+
if (!$value && $data) {
274+
if ($data->hasMethod($this->name)) {
275+
$value = $data->{$this->name}();
276+
}
277+
}
278+
279+
parent::setValue($value, $data);
280+
}
281+
271282
/**
272283
* Return the list of fields. We'll create a row for each of the values if
273284
* they exist otherwise we'll only return
@@ -277,8 +288,9 @@ public function AddLink()
277288
public function FieldList() {
278289
$output = FieldList::create();
279290
$index = 0;
280-
291+
281292
if ($this->value) {
293+
282294
foreach ($this->value as $record) {
283295
$output->push($this->generateRow($index++, $record));
284296
}
@@ -305,6 +317,7 @@ public function generateRow($index, $value = null)
305317
foreach ($this->manyChildren as $child) {
306318
$field = clone $child;
307319
$field->name = $this->name . '['.$child->name . ']['. $index . ']';
320+
$field->setValue(($value) ? $value->{$child->name} : null);
308321

309322
if (isset($this->fieldCallbacks[$child->name])) {
310323
call_user_func($this->fieldCallbacks[$name], $field, $index, $this);
@@ -385,16 +398,28 @@ public function updateRelation(DataObjectInterface $record, $delete = true)
385398
}
386399

387400
foreach ($updatedData as $key => $data) {
401+
// if all data is empty then skip adding this record.
402+
$empty = array_filter($data);
403+
404+
if (empty($empty)) {
405+
continue;
406+
}
407+
408+
// if mapped to an existing record then find and update.
409+
$record = null;
410+
388411
if (isset($idKeyMap[$key])) {
389412
$record = $existing->find('ID', $idKeyMap[$key]);
390-
413+
}
414+
415+
if ($record) {
391416
$record->update($data);
392417
$record->write();
393418
} else {
394419
$create = Injector::inst()->create($existing->dataClass());
395420
$create->update($data);
396-
397421
$create->write();
422+
398423
$existing->add($create);
399424
}
400425
}

0 commit comments

Comments
 (0)