|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Encore\Admin\Grid\Displayers; |
|
4
|
|
|
|
|
5
|
|
|
use Encore\Admin\Admin; |
|
6
|
|
|
use Encore\Admin\Grid\Selectable; |
|
7
|
|
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany as Relation; |
|
8
|
|
|
use Illuminate\Support\Arr; |
|
9
|
|
|
|
|
10
|
|
|
class BelongsToMany extends AbstractDisplayer |
|
11
|
|
|
{ |
|
12
|
|
|
use BelongsToRelation; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* Other key for many-to-many relation. |
|
16
|
|
|
* |
|
17
|
|
|
* @var string |
|
18
|
|
|
*/ |
|
19
|
|
|
protected static $otherKey = []; |
|
20
|
|
|
|
|
21
|
|
|
/** |
|
22
|
|
|
* @return $this |
|
23
|
|
|
*/ |
|
24
|
|
View Code Duplication |
public function addScript() |
|
|
|
|
|
|
25
|
|
|
{ |
|
26
|
|
|
$script = <<<SCRIPT |
|
27
|
|
|
(function () { |
|
28
|
|
|
var modal = $('#{$this->modalID}'); |
|
29
|
|
|
var related = null; |
|
30
|
|
|
var selected = []; |
|
31
|
|
|
|
|
32
|
|
|
var load = function (url) { |
|
33
|
|
|
$.get(url, function (data) { |
|
34
|
|
|
modal.find('.modal-body').html(data); |
|
35
|
|
|
modal.find('.select').iCheck({ |
|
36
|
|
|
radioClass:'iradio_minimal-blue', |
|
37
|
|
|
checkboxClass:'icheckbox_minimal-blue' |
|
38
|
|
|
}); |
|
39
|
|
|
modal.find('.box-header:first').hide(); |
|
40
|
|
|
|
|
41
|
|
|
modal.find('input.select').each(function (index, el) { |
|
42
|
|
|
if ($.inArray($(el).val().toString(), selected) >=0 ) { |
|
43
|
|
|
$(el).iCheck('toggle'); |
|
44
|
|
|
} |
|
45
|
|
|
}); |
|
46
|
|
|
}); |
|
47
|
|
|
}; |
|
48
|
|
|
|
|
49
|
|
|
var update = function (callback) { |
|
50
|
|
|
$.ajax({ |
|
51
|
|
|
url: "{$this->getResource()}/" + related.attr('key'), |
|
52
|
|
|
type: "POST", |
|
53
|
|
|
data: { |
|
54
|
|
|
{$this->columnName}: selected, |
|
55
|
|
|
_token: LA.token, |
|
56
|
|
|
_method: 'PUT' |
|
57
|
|
|
}, |
|
58
|
|
|
success: function (data) { |
|
59
|
|
|
callback(data); |
|
60
|
|
|
} |
|
61
|
|
|
}); |
|
62
|
|
|
}; |
|
63
|
|
|
|
|
64
|
|
|
modal.on('show.bs.modal', function (e) { |
|
65
|
|
|
related = $(e.relatedTarget); |
|
66
|
|
|
selected = related.data('val').map(function (value) { |
|
67
|
|
|
return value.toString(); |
|
68
|
|
|
}); |
|
69
|
|
|
|
|
70
|
|
|
load("{$this->getLoadUrl(1)}"); |
|
71
|
|
|
}).on('click', '.page-item a, .filter-box a', function (e) { |
|
72
|
|
|
load($(this).attr('href')); |
|
73
|
|
|
e.preventDefault(); |
|
74
|
|
|
}).on('click', 'tr', function (e) { |
|
75
|
|
|
$(this).find('input.select').iCheck('toggle'); |
|
76
|
|
|
e.preventDefault(); |
|
77
|
|
|
}).on('submit', '.box-header form', function (e) { |
|
78
|
|
|
load($(this).attr('action')+'&'+$(this).serialize()); |
|
79
|
|
|
e.preventDefault(); |
|
80
|
|
|
}).on('ifChecked', 'input.select', function (e) { |
|
81
|
|
|
var val = $(this).val().toString(); |
|
82
|
|
|
if (selected.indexOf(val) < 0) { |
|
83
|
|
|
selected.push(val); |
|
84
|
|
|
} |
|
85
|
|
|
}).on('ifUnchecked', 'input.select', function (e) { |
|
86
|
|
|
var val = $(this).val().toString(); |
|
87
|
|
|
var index = selected.indexOf(val); |
|
88
|
|
|
if (index !== -1) { |
|
89
|
|
|
selected.splice(index, 1); |
|
90
|
|
|
} |
|
91
|
|
|
}).find('.modal-footer .submit').click(function () { |
|
92
|
|
|
update(function (data) { |
|
93
|
|
|
related.data('val', selected); |
|
94
|
|
|
related.find('.text').html(data.display["{$this->columnName}"]); |
|
95
|
|
|
related.find('a').toggleClass('text-green text-muted'); |
|
96
|
|
|
|
|
97
|
|
|
setTimeout(function () { |
|
98
|
|
|
related.find('a').toggleClass('text-green text-muted'); |
|
99
|
|
|
}, 2000); |
|
100
|
|
|
|
|
101
|
|
|
modal.modal('toggle'); |
|
102
|
|
|
|
|
103
|
|
|
toastr.success(data.message); |
|
104
|
|
|
}); |
|
105
|
|
|
}); |
|
106
|
|
|
})(); |
|
107
|
|
|
SCRIPT; |
|
108
|
|
|
|
|
109
|
|
|
Admin::script($script); |
|
110
|
|
|
|
|
111
|
|
|
return $this; |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* Get other key for this many-to-many relation. |
|
116
|
|
|
* |
|
117
|
|
|
* @throws \Exception |
|
118
|
|
|
* |
|
119
|
|
|
* @return string |
|
120
|
|
|
*/ |
|
121
|
|
|
protected function getOtherKey() |
|
122
|
|
|
{ |
|
123
|
|
|
if (isset(static::$otherKey[$this->getName()])) { |
|
124
|
|
|
return static::$otherKey[$this->getName()]; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
$model = $this->getGrid()->model()->getOriginalModel(); |
|
|
|
|
|
|
128
|
|
|
|
|
129
|
|
|
if (is_callable([$model, $this->getName()]) && |
|
130
|
|
|
($relation = $model->{$this->getName()}()) instanceof Relation |
|
131
|
|
|
) { |
|
132
|
|
|
/* @var Relation $relation */ |
|
133
|
|
|
$fullKey = $relation->getQualifiedRelatedPivotKeyName(); |
|
134
|
|
|
$fullKeyArray = explode('.', $fullKey); |
|
135
|
|
|
|
|
136
|
|
|
return static::$otherKey[$this->getName()] = end($fullKeyArray); |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
throw new \Exception('Column of this field must be a `BelongsToMany` relation.'); |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* @return false|string|void |
|
144
|
|
|
* @throws \Exception |
|
145
|
|
|
*/ |
|
146
|
|
|
protected function getOriginalData() |
|
147
|
|
|
{ |
|
148
|
|
|
$relations = $this->getColumn()->getOriginal(); |
|
149
|
|
|
|
|
150
|
|
|
if (is_string($relations)) { |
|
151
|
|
|
$data = explode(',', $relations); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
if (!is_array($relations)) { |
|
155
|
|
|
return; |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
$first = current($relations); |
|
159
|
|
|
|
|
160
|
|
|
if (is_null($first)) { |
|
161
|
|
|
$data = null; |
|
162
|
|
|
|
|
163
|
|
|
// MultipleSelect value store as an ont-to-many relationship. |
|
164
|
|
|
} elseif (is_array($first)) { |
|
165
|
|
|
foreach ($relations as $relation) { |
|
166
|
|
|
$data[] = Arr::get($relation, "pivot.{$this->getOtherKey()}"); |
|
|
|
|
|
|
167
|
|
|
} |
|
168
|
|
|
|
|
169
|
|
|
// MultipleSelect value store as a column. |
|
170
|
|
|
} else { |
|
171
|
|
|
$data = $relations; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
return json_encode($data); |
|
175
|
|
|
} |
|
176
|
|
|
} |
|
177
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.