質問編集履歴
1
根本変更いたしました。
test
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Angular
|
1
|
+
Angular 項目を並べ替えるボタンを追加する (↑↓ボタンをクリックで、項目が前後に移動する)
|
test
CHANGED
@@ -4,55 +4,135 @@
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
##
|
7
|
+
## 仮説
|
8
|
-
|
8
|
+
|
9
|
-
-
|
9
|
+
- 配列の値を取得→条件式→移動
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
コード
|
14
|
+
|
15
|
+
-
|
10
16
|
|
11
17
|
|
12
18
|
|
13
19
|
```html
|
14
20
|
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
<h1>Todo App</h1>
|
26
|
+
|
15
|
-
|
27
|
+
<form [formGroup]="rForm">
|
16
|
-
|
28
|
+
|
17
|
-
<la
|
29
|
+
<div class="form-group registItemArea">
|
30
|
+
|
18
|
-
|
31
|
+
<div class="input-group">
|
32
|
+
|
19
|
-
<input id="title" t
|
33
|
+
<input id="title" class="form-control" placeholder="Title" formControlName="title" />
|
34
|
+
|
20
|
-
|
35
|
+
<span class="input-group-btn">
|
36
|
+
|
21
|
-
<button type="
|
37
|
+
<button class="btn btn-default" type="button" (click)="hasDetail = !hasDetail">詳細</button>
|
38
|
+
|
39
|
+
</span>
|
40
|
+
|
41
|
+
</div>
|
42
|
+
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<div class="card card-block card-header" (click)="hasDetail = !hasDetail">
|
46
|
+
|
47
|
+
<div class="form-group">
|
48
|
+
|
49
|
+
<label for="description">
|
50
|
+
|
51
|
+
<strong>詳細:</strong>
|
52
|
+
|
53
|
+
</label>
|
54
|
+
|
55
|
+
<textarea id="text" class="form-control" formControlName="description"></textarea>
|
56
|
+
|
57
|
+
</div>
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
<div class="form-group">
|
62
|
+
|
63
|
+
<label for="date">
|
64
|
+
|
65
|
+
<strong>日付:</strong>
|
66
|
+
|
67
|
+
</label>
|
68
|
+
|
69
|
+
<input type="date" class="form-control" formControlName="date" />
|
70
|
+
|
71
|
+
</div>
|
72
|
+
|
73
|
+
</div>
|
22
74
|
|
23
75
|
</form>
|
24
76
|
|
25
|
-
|
26
|
-
|
27
|
-
<
|
77
|
+
<div class=" row ">
|
28
|
-
|
78
|
+
|
29
|
-
<div class="
|
79
|
+
<div class="col-sm-2 ">
|
30
|
-
|
31
|
-
|
80
|
+
|
32
|
-
|
33
|
-
<div
|
34
|
-
|
35
|
-
cdkDropList
|
36
|
-
|
37
|
-
#todoList="cdkDropList"
|
38
|
-
|
39
|
-
[cdkDropListData]="todo"
|
40
|
-
|
41
|
-
[cdkDropListConnectedTo]="[]"
|
42
|
-
|
43
|
-
class="todo-list"
|
44
|
-
|
45
|
-
(cdkDropListDropped)="drop($event)">
|
46
|
-
|
47
|
-
<
|
81
|
+
<button class="createBtn btn btn-success " [disabled]="this.rForm.invalid" (click)="onSaveTodoItem()">作成</button>
|
48
82
|
|
49
83
|
</div>
|
50
84
|
|
51
85
|
</div>
|
52
86
|
|
53
|
-
|
87
|
+
<hr>
|
88
|
+
|
54
|
-
|
89
|
+
<div class="row itemListArea ">
|
90
|
+
|
55
|
-
|
91
|
+
<div class="col-sm-12">
|
92
|
+
|
93
|
+
<li *ngFor="let item of itemList; let i=index;">
|
94
|
+
|
95
|
+
<div accordion-heading [class.isComplete]="item.isComplete">
|
96
|
+
|
97
|
+
<button class="btn btn-danger" (click)="onUpItem(i)">↑</button>
|
98
|
+
|
99
|
+
<button class="btn btn-danger" (click)="onDownItem(i)">↓</button>
|
100
|
+
|
101
|
+
{{item.title}}
|
102
|
+
|
103
|
+
</div>
|
104
|
+
|
105
|
+
<div>
|
106
|
+
|
107
|
+
<strong>詳細:</strong>
|
108
|
+
|
109
|
+
<pre>{{item.description ? item.description : "-"}}</pre>
|
110
|
+
|
111
|
+
</div>
|
112
|
+
|
113
|
+
<div>
|
114
|
+
|
115
|
+
<strong>日付:</strong>
|
116
|
+
|
117
|
+
<span>{{item.date ? item.date : "-"}}</span>
|
118
|
+
|
119
|
+
</div>
|
120
|
+
|
121
|
+
<div>
|
122
|
+
|
123
|
+
<button class="btn btn-danger" (click)="onDeleteItem(i)">削除</button>
|
124
|
+
|
125
|
+
<button class="btn btn-success" (click)="item.isComplete = !item.isComplete ">{{item.isComplete ? "未完了に戻す" : "完了にする"}}</button>
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
</div>
|
130
|
+
|
131
|
+
</li>
|
132
|
+
|
133
|
+
</div>
|
134
|
+
|
135
|
+
</div>
|
56
136
|
|
57
137
|
```
|
58
138
|
|
@@ -70,134 +150,160 @@
|
|
70
150
|
|
71
151
|
import { FormArray } from '@angular/forms';
|
72
152
|
|
73
|
-
|
153
|
+
|
74
154
|
|
75
155
|
interface TodoItem {
|
76
156
|
|
157
|
+
title: string;
|
158
|
+
|
159
|
+
description: string;
|
160
|
+
|
77
161
|
isComplete: boolean;
|
78
162
|
|
163
|
+
date: any;
|
164
|
+
|
79
165
|
}
|
80
166
|
|
167
|
+
|
168
|
+
|
81
169
|
@Component({
|
82
170
|
|
83
171
|
selector: 'app-form-practice',
|
84
172
|
|
85
173
|
templateUrl: './form-practice.component.html',
|
86
174
|
|
87
|
-
styleUrls: ['./form-practice.component.css']
|
175
|
+
styleUrls: ['./form-practice.component.scss']
|
88
176
|
|
89
177
|
})
|
90
178
|
|
91
|
-
export class FormPracticeComponent implements OnInit {
|
179
|
+
export class FormPracticeComponent implements OnInit {
|
92
|
-
|
93
|
-
|
180
|
+
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
181
|
+
|
98
|
-
|
182
|
+
|
99
|
-
|
183
|
+
// 詳細が表示されているか
|
100
|
-
|
184
|
+
|
101
|
-
|
185
|
+
public hasDetail = false;
|
102
|
-
|
186
|
+
|
103
|
-
|
187
|
+
// アイテムリスト
|
104
|
-
|
105
|
-
|
188
|
+
|
106
|
-
|
107
|
-
|
189
|
+
public itemList: Array<TodoItem> = new Array<TodoItem>();
|
108
|
-
|
109
|
-
|
110
190
|
|
111
191
|
|
112
192
|
|
193
|
+
rForm: FormGroup;
|
194
|
+
|
113
|
-
constructor(pr
|
195
|
+
constructor(protected fb: FormBuilder) {
|
196
|
+
|
114
|
-
|
197
|
+
}
|
115
|
-
|
116
|
-
|
198
|
+
|
117
|
-
|
199
|
+
ngOnInit() {
|
200
|
+
|
118
|
-
|
201
|
+
this.createForm();
|
202
|
+
|
203
|
+
}
|
204
|
+
|
205
|
+
createForm(): void {
|
206
|
+
|
119
|
-
//
|
207
|
+
// Form の作成と初期値設定をします。
|
120
|
-
|
208
|
+
|
121
|
-
|
209
|
+
this.rForm = this.fb.group({
|
210
|
+
|
211
|
+
title: ['',
|
212
|
+
|
213
|
+
[
|
214
|
+
|
215
|
+
Validators.required
|
216
|
+
|
217
|
+
]
|
218
|
+
|
219
|
+
],
|
220
|
+
|
221
|
+
description: [''],
|
222
|
+
|
223
|
+
date: [''],
|
224
|
+
|
225
|
+
isComplete: [false]
|
226
|
+
|
227
|
+
});
|
122
228
|
|
123
229
|
}
|
124
230
|
|
125
231
|
|
126
232
|
|
233
|
+
// todoItem を 保存します
|
234
|
+
|
127
|
-
|
235
|
+
onSaveTodoItem(): void {
|
236
|
+
|
128
|
-
|
237
|
+
const item: TodoItem = {
|
238
|
+
|
129
|
-
|
239
|
+
title: this.rForm.get('title').value,
|
240
|
+
|
241
|
+
isComplete: false,
|
242
|
+
|
243
|
+
description: null,
|
244
|
+
|
245
|
+
date: null
|
246
|
+
|
247
|
+
};
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
if (this.hasDetail) {
|
252
|
+
|
253
|
+
item.description = this.rForm.get('description').value;
|
254
|
+
|
255
|
+
item.date = this.rForm.get('date').value;
|
256
|
+
|
257
|
+
}
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
this.itemList.push(item);
|
262
|
+
|
263
|
+
this.clearForm();
|
264
|
+
|
265
|
+
console.log(this.itemList);
|
130
266
|
|
131
267
|
}
|
132
268
|
|
133
269
|
|
134
270
|
|
271
|
+
// フォームの値をリセット
|
272
|
+
|
135
|
-
|
273
|
+
clearForm(): void {
|
136
|
-
|
274
|
+
|
137
|
-
|
275
|
+
this.rForm.reset();
|
138
|
-
|
276
|
+
|
139
|
-
}
|
277
|
+
}
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
updateProfile() {
|
144
|
-
|
145
|
-
this.profileForm.setValue({
|
146
|
-
|
147
|
-
title: '',
|
148
|
-
|
149
|
-
});
|
150
|
-
|
151
|
-
}
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
onRemoveAt(index: number): void {
|
156
|
-
|
157
|
-
this.aliases.removeAt(index);
|
158
|
-
|
159
|
-
}
|
160
278
|
|
161
279
|
|
162
280
|
|
281
|
+
// 指定した要素を削除
|
282
|
+
|
163
|
-
n
|
283
|
+
onDeleteItem(index: number): void {
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
284
|
+
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
drop(event: CdkDragDrop<string[]>) {
|
174
|
-
|
175
|
-
if (event.previousContainer === event.container) {
|
176
|
-
|
177
|
-
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
|
178
|
-
|
179
|
-
} else {
|
180
|
-
|
181
|
-
transferArrayItem(event.previousContainer.data,
|
182
|
-
|
183
|
-
event.container.data,
|
184
|
-
|
185
|
-
event.previousIndex,
|
186
|
-
|
187
|
-
|
285
|
+
this.itemList.splice(index, 1);
|
188
286
|
|
189
287
|
}
|
190
288
|
|
289
|
+
|
290
|
+
|
291
|
+
// 指定した要素を上に移動
|
292
|
+
|
293
|
+
onUpItem(index: number): void {
|
294
|
+
|
295
|
+
this.itemList.splice(0, index);
|
296
|
+
|
191
|
-
}
|
297
|
+
}
|
298
|
+
|
192
|
-
|
299
|
+
// 指定した要素を下に移動
|
300
|
+
|
193
|
-
|
301
|
+
onDownItem(index: number): void {
|
302
|
+
|
303
|
+
this.itemList.splice(-1, index);
|
304
|
+
|
305
|
+
}
|
194
306
|
|
195
307
|
}
|
196
308
|
|
197
|
-
|
198
|
-
|
199
309
|
```
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
すみませんが知識をお借りしたいです。
|