Skip to content

Commit 7865497

Browse files
Added readme contents for demo. DnD feature for changing order of todos, Implemented Rest webservice as a boot project, integration of rest web service with angular app.
1 parent 363ff42 commit 7865497

File tree

21 files changed

+766
-38
lines changed

21 files changed

+766
-38
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ testem.log
4040
# System Files
4141
.DS_Store
4242
Thumbs.db
43+
44+
# maven
45+
*/target/

README.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,166 @@
11
# todo-angular2
22
A TODO list app created in Angular 2
3+
4+
################################################
5+
# STEP 1 : Set up the Development Environment
6+
################################################
7+
8+
Install Node.js® and npm if they are not already on your machine
9+
10+
Visit : https://nodejs.org/en/download/
11+
12+
################################################
13+
# STEP 2 : Install Angular CLI
14+
################################################
15+
16+
npm install -g @angular/cli
17+
18+
################################################
19+
# STEP 3 : Create a new Project
20+
################################################
21+
22+
ng new my-application
23+
24+
################################################
25+
# STEP 4 : Serve the application
26+
################################################
27+
28+
cd my-app
29+
ng serve --open [ or ng serve -o ]
30+
31+
###############################################
32+
# To Generate Service Form CLI
33+
###############################################
34+
35+
ng g service restservice
36+
37+
################################################
38+
# BOOTSTRAP INTEGRATION
39+
################################################
40+
41+
# 1) Open below link
42+
43+
Visit : https://ng-bootstrap.github.io/#/home
44+
45+
# 2) Click on Installation button
46+
47+
# 3) Installation
48+
49+
npm install --save @ng-bootstrap/ng-bootstrap
50+
51+
# 4) Once installed you need to import our main module
52+
53+
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
54+
55+
# 5) Need to add imports in AppModule
56+
57+
Example :
58+
59+
@NgModule({
60+
declarations: [AppComponent, ...],
61+
imports: [NgbModule.forRoot(), ...], // forRoot is used to add application/singleton services.
62+
bootstrap: [AppComponent]
63+
})
64+
65+
export class AppModule {
66+
}
67+
68+
# 6) Install bootstrap (Using only for CSS reference)
69+
70+
npm install [email protected]
71+
72+
# 7) Add css link to .angular-cli.json file
73+
74+
Example :
75+
76+
"styles": [
77+
"styles.css",
78+
"../node_modules/bootstrap/dist/css/bootstrap.css"
79+
]
80+
81+
82+
#######################################################
83+
# TODO COMPONENT TEMPLATE
84+
#######################################################
85+
86+
<div class="container">
87+
<div class="col-xs-2">
88+
<ul class="list-group">
89+
<li class="list-group-item">
90+
</li>
91+
</ul>
92+
</div>
93+
</div>
94+
95+
########################################################
96+
# TASK COMPONENT TEMPLATE
97+
########################################################
98+
99+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
100+
<div class="container">
101+
<div class="row">
102+
<div class="col-sm-1">
103+
<!-- Checkbox -->
104+
</div>
105+
<div class="col-sm-9">
106+
<!-- Form -->
107+
</div>
108+
<div class="col-sm-1">
109+
<!-- delete button -->
110+
<span class="fa fa-trash-o" style="cursor:pointer;"></span>
111+
</div>
112+
</div>
113+
</div>
114+
115+
#######################################################
116+
# FORM Validation css
117+
#######################################################
118+
119+
<div class="form-group" [ngClass]="form.get('updatedTask').hasError('required') && isSubmitted ? 'has-danger' : ''">
120+
<input type="text" class="form-control input-sm form-control-danger" id="task" placeholder="Add a task" formControlName="updatedTask" focus/>
121+
<div class="form-control-feedback" \*ngIf="form.get('updatedTask').hasError('required') && isSubmitted">
122+
Task name is required
123+
</div>
124+
</div>
125+
126+
########################################################
127+
# STRIKETHROUGH CSS
128+
########################################################
129+
130+
<span [ngClass]="task.isDone ? 'task-done' : 'task'" (click)="enableEditing()" \*ngIf="!editable" style="cursor:pointer;" >
131+
</span>
132+
133+
#######################################################
134+
# How to make DRAG & DROP TODO
135+
#######################################################
136+
137+
1) Install DndModule
138+
139+
npm install ng2-dnd --save
140+
141+
2) Update App.module.ts
142+
143+
import {BrowserModule} from "@angular/platform-browser";
144+
import {NgModule} from '@angular/core';
145+
import {DndModule} from 'ng2-dnd';
146+
147+
@NgModule({
148+
imports: [
149+
BrowserModule,
150+
DndModule.forRoot()
151+
],
152+
bootstrap: [AppComponent]
153+
})
154+
export class AppModule {
155+
}
156+
157+
########################################################
158+
# Angular 2 Bootstrap + Bootstrap Styling
159+
########################################################
160+
161+
Using bootstrap components in Angular 2 Visit: https://valor-software.com/ng2-bootstrap/#/
162+
163+
164+
########################################################
165+
#
166+
########################################################

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@angular/router": "^4.0.0",
2323
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.22",
2424
"core-js": "^2.4.1",
25+
"ng2-dnd": "^4.0.2",
2526
"rxjs": "^5.1.0",
2627
"zone.js": "^0.8.4"
2728
},

src/app/app.module.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { FocusDirective } from './directive/focus.directive';
1111
import { SearchComponent } from './search/search.component';
1212
import {InMemoryTodoService} from './service/in-memory-todo.service';
1313
import {LocalStorageTodoService} from './service/local-storage-todo.service';
14+
import {DndModule} from 'ng2-dnd';
15+
import {TodoRestService} from './service/todo-rest.service';
1416

1517
const routes = [
1618
{path: '', component: TodoComponent},
@@ -30,9 +32,10 @@ const routes = [
3032
FormsModule,
3133
ReactiveFormsModule,
3234
HttpModule,
33-
RouterModule.forRoot(routes)
35+
RouterModule.forRoot(routes),
36+
DndModule.forRoot()
3437
],
35-
providers: [LocalStorageTodoService],
38+
providers: [LocalStorageTodoService, TodoRestService],
3639
bootstrap: [AppComponent]
3740
})
3841
export class AppModule { }

src/app/model/task.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ export class Task {
88
this.name = name;
99
this.isDone = isDone;
1010
}
11+
12+
getName(): string {
13+
return this.name;
14+
}
1115
}

src/app/search/search.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {Component, Input, Output, EventEmitter, OnInit} from '@angular/core';
22
import {Task} from '../model/task';
33
import {LocalStorageTodoService} from '../service/local-storage-todo.service';
4+
import {TodoRestService} from '../service/todo-rest.service';
45

56
@Component({
67
selector: 'app-search',
@@ -12,7 +13,7 @@ export class SearchComponent implements OnInit {
1213
query: string;
1314
searchRes: Task[];
1415

15-
constructor(private todoService: LocalStorageTodoService) { }
16+
constructor(private todoService: TodoRestService) { }
1617

1718
ngOnInit() {
1819

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { TestBed, inject } from '@angular/core/testing';
2+
3+
import { TodoRestService } from './todo-rest.service';
4+
5+
describe('TodoRestService', () => {
6+
beforeEach(() => {
7+
TestBed.configureTestingModule({
8+
providers: [TodoRestService]
9+
});
10+
});
11+
12+
it('should ...', inject([TodoRestService], (service: TodoRestService) => {
13+
expect(service).toBeTruthy();
14+
}));
15+
});

src/app/service/todo-rest.service.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { Injectable } from '@angular/core';
2+
import { Http, Headers, RequestOptions } from '@angular/http';
3+
import {Task} from '../model/task';
4+
import 'rxjs/add/operator/toPromise';
5+
6+
@Injectable()
7+
export class TodoRestService {
8+
id: number;
9+
url: "http://localhost:8090/rest/api/todos/";
10+
11+
constructor(private http: Http) { }
12+
13+
getAll(): Promise<Task[]> {
14+
return this.http.get("http://localhost:8090/rest/api/todos/")
15+
.toPromise()
16+
.then(response => response.json())
17+
.catch(this.handleError);
18+
}
19+
20+
add(name: string): Promise<Task> {
21+
22+
let headers = new Headers({ 'Content-Type': 'application/json' });
23+
let options = new RequestOptions({ headers: headers });
24+
25+
return this.http.post("http://localhost:8090/rest/api/todos/", new Task(null, name, false), options)
26+
.toPromise()
27+
.then(response => response.json() as Task)
28+
.catch(this.handleError);
29+
}
30+
31+
updateDone(id: string, isDone: boolean): Promise<void> {
32+
33+
let headers = new Headers({ 'Content-Type': 'application/json' });
34+
let options = new RequestOptions({ headers: headers });
35+
36+
return this.http.put("http://localhost:8090/rest/api/todos/"+ id, {isDone: isDone}, options )
37+
.toPromise()
38+
.then(response => response.json() as Task)
39+
.then(response => Promise.resolve())
40+
.catch(this.handleError);
41+
}
42+
43+
44+
delete(id: string): Promise<void> {
45+
46+
let headers = new Headers({ 'Content-Type': 'application/json' });
47+
let options = new RequestOptions({ headers: headers });
48+
49+
return this.http.delete("http://localhost:8090/rest/api/todos/"+ id, options )
50+
.toPromise()
51+
.then(response => Promise.resolve())
52+
.catch(this.handleError);
53+
}
54+
55+
56+
update(task: Task): Promise<void> {
57+
58+
let headers = new Headers({ 'Content-Type': 'application/json' });
59+
let options = new RequestOptions({ headers: headers });
60+
61+
return this.http.put("http://localhost:8090/rest/api/todos/"+ task.id, {name: task.getName()}, options )
62+
.toPromise()
63+
.then(response => response.json() as Task)
64+
.then(response => Promise.resolve())
65+
.catch(this.handleError);
66+
}
67+
68+
69+
handleError(error: any): Promise<any> {
70+
console.error('An error occurred', error); // for demo purposes only
71+
return Promise.reject(error.message || error);
72+
}
73+
74+
75+
76+
}

src/app/todo/task.component.html

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,14 @@
88
<span [ngClass]="task.isDone ? 'task-done' : 'task'" (click)="enableEditing()" *ngIf="!editable" style="cursor:pointer;" >
99
{{task.name}}
1010
</span>
11-
12-
<!-- <form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
13-
14-
<div class="form-group" [ngClass]="form.get('newTask').hasError('required') && isSubmitted ? 'has-danger' : ''">
15-
<input type="text" class="form-control form-control-danger" id="task" placeholder="Add a task" formControlName="newTask">
16-
<div class="form-control-feedback" *ngIf="form.get('newTask').hasError('required') && isSubmitted">Task name is required</div>
17-
</div>
11+
<form novalidate *ngIf="editable" [formGroup]="form" (submit)="editName(form)">
12+
<div class="form-group" [ngClass]="form.get('updatedTask').hasError('required') && isSubmitted ? 'has-danger' : ''">
13+
<input type="text" class="form-control input-sm form-control-danger" id="task" placeholder="Add a task" formControlName="updatedTask" (blur)="disableEditing()" focus/>
14+
<div class="form-control-feedback" *ngIf="form.get('updatedTask').hasError('required') && isSubmitted">Task name is required</div>
15+
</div>
1816
</form>
19-
-->
20-
21-
<form novalidate *ngIf="editable" [formGroup]="form" (submit)="editName(form)">
22-
<div class="form-group" [ngClass]="form.get('updatedTask').hasError('required') && isSubmitted ? 'has-danger' : ''">
23-
<input type="text" class="form-control input-sm form-control-danger" id="task" placeholder="Add a task" formControlName="updatedTask" (blur)="disableEditing()" focus/>
24-
<div class="form-control-feedback" *ngIf="form.get('updatedTask').hasError('required') && isSubmitted">Task name is required</div>
25-
</div>
26-
</form>
27-
28-
<!-- <form novalidate *ngIf="editable" class="form-group" (submit)="editName()">
29-
<input type="text" class="form-control input-sm" [(ngModel)] = "editedName" name="newName" (blur)="disableEditing()" focus/>
30-
</form>
31-
-->
3217
</div>
3318
<div class="col-sm-1">
34-
<span class="glyphicon glyphicon-trash" aria-hidden="true" style="cursor:pointer;"></span>
3519
<span (click)="deleteTask()" class="fa fa-trash-o" style="cursor:pointer;"></span>
3620
</div>
3721
</div>

src/app/todo/task.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Component, Input, Output, EventEmitter, OnInit} from '@angular/core';
22
import {Task} from '../model/task';
3-
import {LocalStorageTodoService} from '../service/local-storage-todo.service';
3+
import {TodoRestService} from '../service/todo-rest.service';
44

55
import { FormGroup, FormBuilder, FormControl, Validators} from '@angular/forms';
66

@@ -19,7 +19,7 @@ export class TaskComponent implements OnInit {
1919
isSubmitted = false;
2020
form: FormGroup;
2121

22-
constructor(private todoService: LocalStorageTodoService, private fb: FormBuilder) {
22+
constructor(private todoService: TodoRestService, private fb: FormBuilder) {
2323
console.log('task component created: ');
2424
}
2525

@@ -59,7 +59,7 @@ export class TaskComponent implements OnInit {
5959
updatedTask: this.task.name
6060
});
6161
console.log(this.form.get('updatedTask').value);
62-
62+
6363
}
6464

6565
editName({value, valid}: {value: FormGroup, valid: boolean}) {

0 commit comments

Comments
 (0)