วันศุกร์ที่ 12 เมษายน พ.ศ. 2562

Ionic 4 , Angular 7 & Django [ Picture]

สร้างโปรเจคโดยให้ Django เป็น server ที่บันทึกข้อมูล และให้ Ionic ทำงานในส่วนของ client ในการติดต่อรับส่งข้อมูลมาแสดงผล

1.สร้าง server ที่ Django

install rest_framework และ แอพพลิเคชัน upload

 สร้าง model มาเก็บค่าที่จะรับจาก client

เพิ่มฟังก์ชันในการรับค่าจาก client
create url ในการเรียกค่า
จากนั้น runserver Django รอไว้

2.ทำงานในส่วน client
start ionic project ด้วยคำสั่ง ionic start upload 

ทำการ Importing HttpClientModule ใน app.module.ts
            import { HttpClientModule } from '@angular/common/http';
           และเพิ่ม  HttpClientModule ลงในส่วน import

เรียกใช้ service โดย
      ionic generate service uploading

จากนั้นใส่ link ที่ต้องการเรียกใช้ server
  DJANGO_API_SERVER: string = "http://127.0.0.1:8000";
  constructor(private http: HttpClient) { }

  public uploadFormData(formData) {
    return this.http.post<any>(`${this.DJANGO_API_SERVER}/upload/`, formData);
  }

สร้างหน้าการ upload ด้วยคำสั่ง
     ionic generate page upload

พิมพ์คำสั่ง npm install --save ng2-file-upload ลงในคอมมานเพื่อใช้งาน package สำหรับการจัดการการอัพโหลด

import คำสั่ง import { FileUploadModule } from 'ng2-file-upload'; ใน upload.module.ts

ประกาศตัวแปร และ สร้างฟังก์ชันสำหรับเรียกข้อมูลจาก server และส่งข้อมูลไปยัง server

แก้ไขหน้า html สำหรับการแสดงผล

จะได้ผลลัพธ์ดังนี้
 เมื่อเข้าไปตรวจสอบในส่วนของ server ก็พบว่าสามารถ เพิ่มข้อมูลไปบันทึกที่ฐานข้อมูลของ server ได้



Ionic 4 & Angular 7 สูตรคูณ แบบ Local storage

ทำแอพพลิเคชันสูตรคูณ โดยให้ใส่ตัวเลขแม่สูตรคูณที่ต้องการลงในช่อง ENTER Number จากนั้นกดปุ่ม SHOW จะแสดง สูตรคูณแม่นั้นๆ โดยมีวิธีทำดังนี้

1 start project ด้วยคำสั่ง ionic start multiplication tabs

จะทำการสร้างโปรเจคชื่อ multiplication โดยมี tabs เริ่มต้น 3 tabs

2. แก้ไขหน้าการแสดงผลให้แสดงผล 2 tab คือ calculate และ history

3.ทดสอบการรับค่าจากช่องอินพุต
แก้ไขหน้า html เป็น
และแก้ไขในส่วน page.ts ให้ @ViewChild เพื่อเรียกค่าที่รับจาก html และเพิ่มฟังก์ชัน onclickMul() โดยเมื่อใรชีการกดปุ่มที่เรียกใช้ฟังก์ชันนี้จะให้ส่งค่าที่รับมาออกไปแสดง 

จะได้หน้าการแสดงผลดังนี้
ภาพซ้าย : หน้าเริ่มต้นก่อนการใส่ตัวเลข
ภาพขวา : การแสดงผลเมื่อใส่ตัวเลขและกดปุ่ม SHOW

4.ทำฟังก์ชันการคูณ

เปลี่ยนฟังก์ชัน onclickMul()ให้ทำการคูณค่าและส่งผลลัพธ์กับตัวคูณไปเก็บไว้ใน list 
จากนั้นแก้ไขหน้า html ให้ทำ loop เรียกค่าจาก list ที่เก็บค่าผลลัพธ์ไว้ออกมาแสดงผล


จะได้การแสดงผลดังนี้

4. ทำการเก็บค่าตัวเลขที่ใส่ลงในช่องรับข้อความด้วยการใช้ local storage เก็บค่าไว้

import storage ด้วยคำสั่ง
import { Storage } from '@ionic/storage';

ประกาศใน constructor

constructor(private storage: Storage){}

เพิ่มฟังก์ชัน savemul() ให้ทำการบันทึกข้อมูลลง storage และ showmul() เพื่อแสดงข้อมูลที่เก็บไว้ใน storage
จากนั้นในหน้าแสดงผลให้แสดงค่าตัวเลขที่มีการบันทึกไว้ด้วยจะได้ผลลัพธ์ดังนี้

ภาพซ้าย : ใส่เลข 1 ครั้งแรก เมื่อกด SHOW จะทำการแสดงสูตรคูณและบันทึกเลข 1 ลงในฐานข้อมูลครั้งแรก และเมื่อกด CONUT จะแสดงจำนวนครั้งที่บันทึกลงไปคือ 1 ครั้ง
ภาพกลาง : ใส่เลข 1 ลงไป กด SHOW และกด COUNT เป็นครั้งที่ 6
ภาพขวา : ใส่เลข 6 ลงไป กด SHOW และกด COUNT เป็นครั้งที่ 4

Ionic 4 & Angular 7 [ Firebase ]

Firebase คือ Platform ที่รวบรวมเครื่องมือต่าง ๆ สำหรับการจัดการในส่วนของ Backend หรือ Server side ซึ่งทำให้สามารถสร้าง Mobile Application ได้อย่างมีประสิทธิภาพ โดยใช้งานในส่วนของ Cloud Firestore ซึ่งเป็นบริการทางด้าน Database โดยได้ศึกษาการใช้งานและการติดต่อกนระหว่าง ionic กับ firebase ผ่านลิงก์ https://www.djamware.com/post/5b74e54f80aca74669894413/ionic-4-and-angular-6-tutorial-firebase-realtime-crud-mobile-app โดยในตัวอย่างแบ่งเป็น 6 ส่วน ดังนี้

1: Setup Firebase
เข้าเว็บไซต์ firebase.google.com กดเพิ่มโครงการใหม่ และ ตั้งชื่อโครงการ


2: Create a New App
โดยใช้คำสั่ง ionic start ionic-firebase-crud blank ในการเริ่มโปรเจคใหม่

3: Install and Configure Firebase Module
- รันคำสั่ง npm install --save firebase ในคอมมาน เพื่อติดตั้ง module
- เปิดไฟล์ app.component.ts และเพิ่ม code ส่วนimport
 import * as firebase from 'firebase';
กด < > ที่หน้าแรกของโปรเจค firebase และคัดลอก code ส่วน config ใส่ในส่วน
const config = { }; และ firebase.initializeApp(config); เพิ่มเข้าไปในส่วน initializeApp() {}

4: Add List of Bulletin Board
- import * as firebase from 'Firebase'; ไปในส่วนที่จะใช้งานฐานข้อมูล
- สร้างตัวแปรสำหรับรับข้อมูลมาเก็บลงในฐานข้อมูล
infos = [];
ref = firebase.database().ref('infos/');
- กำหนดค่าลงในส่วน constructor

constructor(public router: Router, public loadingController: LoadingController) {
  this.ref.on('value', resp => {
    this.infos = [];
    this.infos = snapshotToArray(resp);
  });
}

- เพิ่มฟังก์ชัน
1.สำหรับ response ค่าไปที่ firebase
export const snapshotToArray = snapshot => {
    let returnArr = [];

    snapshot.forEach(childSnapshot => {
        let item = childSnapshot.val();
        item.key = childSnapshot.key;
        returnArr.push(item);
    });

    return returnArr;
};
2.สำหรับเพิ่มหัวข้อ
addInfo() {
  this.router.navigate(['/add-info']);
}
3.สำหรับแก้ไข/เพิ่มคำอธิบาย
edit(key) {
  this.router.navigate(['/edit/'+key]);
}
4.สำหรับลบโดยเลือกจากหัวข้อ
async delete(key) {
  const alert = await this.alertController.create({
    header: 'Confirm!',
    message: 'Are you sure want to delete this info?',
    buttons: [
      {
        text: 'Cancel',
        role: 'cancel',
        cssClass: 'secondary',
        handler: (blah) => {
          console.log('cancel');
        }
      }, {
        text: 'Okay',
        handler: () => {
          firebase.database().ref('infos/'+key).remove();
        }
      }
    ]
  });

  await alert.present();
}
จากนั้นแก้ไขหน้า html ที่ใช้แสดงผล

5: Add Page for Create  Info
- ionic g page create ในคอมมาน เพื่อสร้างหน้าใหม่ที่ชื่อ create เพิ่ม
- import form ใน app/create.module.ts เพื่อใช้งานฟอร์ม
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
- กำหนดตัวแปรสำหรับส่งค่าไป firebase

ref = firebase.database().ref('infos/');
infoForm: FormGroup;

- กำหนดค่าใน constructor

constructor(private route: ActivatedRoute,
  public router: Router,
  private formBuilder: FormBuilder) {
    this.infoForm = this.formBuilder.group({
      'info_title' : [null, Validators.required],
      'info_description' : [null, Validators.required]
    });
  }

- เพิ่มฟังก์ชันสำหรับส่งค่าข้อมูลไป firebase

saveInfo() {
  let newInfo = firebase.database().ref('infos/').push();
  newInfo.set(this.infoForm.value);
  this.router.navigate(['/detail/'+newInfo.key]);
}

แก้ไขหน้า html ที่ใช้แสดงผล

6: Show Time!



วันจันทร์ที่ 8 เมษายน พ.ศ. 2562

[TDD] อธิบาย Commit (จบ)

Commit ที่ 13

742e005
 new URL, view and template to display lists

ตั้งค่าการเชื่อมโยง url ในโปรเจค มีการเปลี่ยนมาใช้ assertContains และเพิ่มฟังก์ชัน view_list ใน views.py
สร้างเทมเพลตใหม่โดยการใช้คำสั่งคัดลอกจากเทมเพลตเดิมที่มีอยู่และแก้ไขฟังก์ชันการใช้งานของเทมเพลตให้เหมาะสม


Commit ที่ 14

6b63788
move function to new class and create new url

เพิ่ม url และ ฟังก์ชันใหม่สำหรับ create list และสร้าง class ใหม่สำหรับการ test โดยย้ายฟังก์ชันเดิมมาใส่ไว้

Commit ที่ 15

561f0b3
create new model and test it

สร้าง model ใหม่ชื่อ List และเพิ่มตัวแปรให้ Item ที่มีอยู่ทำการ ForeignKey list มาจาก List

Commit ที่ 16

28ce562
Add unique URLs for each list

เพิ่ม url ใหม่ สำหรับ list ที่สร้างขึ้นมา และทดสอบการเรียกใช้ด้วย id

Commit ที่ 17

6118fbc
new URL + view for adding to existing lists. FT passes :-)

เพิ่มฟังก์ชันสำหรับการเพิ่ม item ใหม่
แก้ไขในเทมเพลตให้ส่งค่าไปที่ url /lists/{{ list.id }}/add_item และให้วน loop ใน list แล้วเรียก item ใน List ออกมาแสดงแทนที่การเรียก item โดยตรง

Commit ที่ 18

4179a2c
create new url for app list

แก้ไข url โดยการเพิ่ม url ของ app list  และให้ superlists include url จาก list ไปเรียกใช้

วันอังคารที่ 26 มีนาคม พ.ศ. 2562

Ionic 4 & Angular 7 CRUD Mobile Apps [continue]

5: View List of Data and Delete

- แก้ไขหน้า Home สำหรับแสดงข้อมูลสินค้าทั้งหมดที่มี โดยแก้ไขที่ไฟล์ home.page.ts โดยการ import module เข้ามาและสร้าง list สำหรับเก็บข้อมูลสินค้าและ sync ไปที่ฟังก์ชัน getProduct() เพื่อเรียกข้อมูลออกมาแสดง
- แก้ไข html ให้แสดงสินค้าทั้งหมดและเมื่อกดที่สินค้าให้เปลี่ยนไปยังหน้าแสดงรายละเอียด ( Details )

6: Display Data Details

- รับ id ของสินค้าเข้ามา และแสดงรายละเอียดข้อมูลตาม id
- เมื่อแสดงรยละเอียดแล้วผู้ใช้สามารถทำการแก้ไข หรือ ลบ สินค้านั้นๆ ได้ โดยการใช้งานฟังก์ชันลบ หรือ ฟังก์ชันแก้ไข
- แก้ไข html ให้แสดงรายละเอียด ปุ่มลบ และปุ่มแก้ไขข้อมูล

7: Edit and Update Data

- แก้ไขในส่วนของ tab edit โดยการใช้ฟังก์ชัน getProduct ในการเรียกข้อมูลสินค้าผ่าน id ของสินค้า และใช้ฟังก์ชัน onForm มาใช้ในการรับข้อมูลที่แก้ไขและเรียกใช้ฟังก์ชัน updateProduct ในการอัพเดทข้อมูลของสินค้าให้เป็นไปตามที่ได้แก้ไข
- แก้ไข html ให้แสดงฟอร์มการแก้ไข และปุ่ม submit

8: Add Data

- เพิ่มการทำงานในส่วนของการเพิ่มข้อมูลสินค้า โดยการใช้ Form รับ input เข้ามาและนำไปใช้ที่ฟังก์ชัน addProduct เพื่อเพิ่มข้อมูลสินค้า
- แก้ไข html ให้แสดงฟอร์มการเพิ่มข้อมูล และปุ่ม submit

9: Run and Test The App

- save and run App ด้วยคำสั่ง ionic serve -l

การแสดงผล


หน้า HOME


หน้า ADD


หน้า EDIT

ปัญหา :
ไม่มีข้อมูลให้นำมาแสดง



วันจันทร์ที่ 25 มีนาคม พ.ศ. 2562

Ionic 4 & Angular 7 CRUD Mobile Apps

ศึกษาตาม tutorial จากเว็บไซต์ https://www.djamware.com/post/5be52ce280aca72b942e31bc/ionic-4-angular-7-and-cordova-tutorial-build-crud-mobile-apps ซึ่งเนื้อหาภายในเป็นการสร้างแอพพลิเคชันที่แสดงข้อมูลสินค้าได้แก่ ชื่อสินค้า ราคา และ คำอธิบาย โดยสามารถทำการ เพิ่ม ลบ เรียกดู และ แก้ไขข้อมูลได้ โดยแบ่งการสร้างเป็น 9 part ดังนี้

1: Create a New Application

เริ่มสร้างโปรเจคด้วยคำสั่ง ionic start ionic4-angular7-crud ใน command line จะได้โฟลเดอร์ของโปรเจค


2: Install Material and CDK

ติดตั้งสิ่งที่จำเป็นในการใช้งานลงไปในโปรเจค โดย

- พิมพ์คำสั่งใน command line
ng add @angular/material

- import Module ใน app.module.ts
import {
  MatInputModule,
  MatPaginatorModule,
  MatProgressSpinnerModule,
  MatSortModule,
  MatTableModule,
  MatIconModule,
  MatButtonModule,
  MatCardModule,
  MatFormFieldModule } from "@angular/material";
import { DragDropModule } from '@angular/cdk/drag-drop';
import { ScrollingModule } from '@angular/cdk/scrolling';

- register all module in @ngModule
imports: [
  BrowserModule,
  IonicModule.forRoot(),
  AppRoutingModule,
  BrowserAnimationsModule,
  DragDropModule,
  ScrollingModule,
  MatInputModule,
  MatPaginatorModule,
  MatProgressSpinnerModule,
  MatSortModule,
  MatTableModule,
  MatIconModule,
  MatButtonModule,
  MatCardModule,
  MatFormFieldModule
],

3: Create RESTful API Service

REST ย่อมาจาก Representational State Transfer เป็นรูปแบบหนึ่งในการออกแบบ open web technology เป็นการทำให้ข้อมูลอยู่ในรูปแบบของ resource ส่วนการกระทำต่าง ๆ เป็นไปตาม HTTP  Method (GET, POST, PUT, DELETE) และทำงานแบบ Stateless ทำให้สามารถสามารถพัฒนาได้ง่ายเนื่องจากอยู่บนมาตรฐาน HTTP และมีประสิทธิภาพในการทำงานที่ดี

- import module
- สร้าง class Product
- generate service ด้วยคำสั่ง ng g service api ใน command line
- กำหนด constant ใน src/app/api.service.ts

const httpOptions = {
  headers: new HttpHeaders({'Content-Type': 'application/json'})
};
const apiUrl = "/api/v1/products";

- สร้างฟังก์ชันในการทำงาน 4 ฟังก์ชัน ได้แก่ การเพิ่มสินค้า การลบสินค้า การเรียกข้อมูลมาแสดง และ การอัพเดทค่าเมื่อมีการแก้ไข โดยใช้ id เป็นตัวกำหนด

4: Modify Tabs Page

- สร้าง tab Details ด้วยคำสั่ง ionic g page details
- แก้ไขหน้า tab1 tab2 tab3 เดิมที่มีอยู่เป็น Home Edit Add และแก้ไข code ภายในให้เรียบร้อย
- import หน้าต่างๆมาที่ tabs และกำหนด router ในการ route ไปยังหน้าการใช้งานต่างๆ โดยกำหนดให้หน้าแรกเป็นหน้า Home
const routes: Routes = [
  {
    path: 'tabs',
    component: TabsPage,
    children: [
      {
        path: 'home',
        children: [
            {
              path: '',
              loadChildren: '../home/home.module#HomePageModule'
            }
          ]
      },
      {
        path: 'add',
        children: [
          {
            path: '',
            loadChildren: '../add/add.module#AddPageModule'
          }
        ]
      },
      {
        path: ':id',
        children: [
          {
            path: '',
            loadChildren: '../edit/edit.module#EditPageModule'
          }
        ]
      },
      {
        path: ':id',
        children: [
          {
            path: '',
            loadChildren: '../details/details.module#DetailsPageModule'
          }
        ]       
      }
    ]
  },
  {
    path: '',
    redirectTo: '/tabs/home',
    pathMatch: 'full'
  }
];

- สร้าง html สำหรับแสดงผลหน้าหลัก

Touch Typing [update]

ทดสอบผ่านเว็บไซต์ https://10fastfingers.com/typing-test/english


วันอังคารที่ 19 มีนาคม พ.ศ. 2562

Angular

Angular
คือ เฟรมเวิร์ค (framework) ที่พัฒนาโดย Google สำหรับสร้างแอพลิเคชั่นในฝั่ง Client ในรูปแบบ Single Page Applications ก็คือแอพพลิเคชันถูกโหลดมารวมในหน้าเดียว โดยติดตั้ง npm คือ
Node Package Manager เป็นการจัดการ Package ต่างๆ ที่ถูกติดตั้งบนแอพพลิเคชันที่ถูกติดตั้งมาพร้อมกับ Node.js โดยมีการใช้งานผ่านไฟล์หลัก 3 ไฟล์ คือ :
app.component.ts เป็นการ code ส่วนของ logic โดยเขียนในรูปแบบ TypeScript.
app.component.html เป็นการกำหนด template โดยเขียนในรูปแบบ HTML.
app.component.css เป็นการกำหนด CSS styles

คำสั่งหลัก
ng new my-app      สร้างแอพใหม่ชื่อ my-app
ng serve แสดง link http://localhost:4200/ ให้นำไปใช้งาน
ng serve --open                               เปิด browser http://localhost:4200/ โดยอัตโนมัติ
ng generate component heroes สร้าง component ใหม่ชื่อ heroes

วันจันทร์ที่ 18 มีนาคม พ.ศ. 2562

Test ครั้งที่ 2

ทดสอบการเปิดเว็บไซต์
ดู Header ว่าตรงหรือไม่
ทดสอบการเพิ่มคำถามเข้าไป

https://github.com/Freezzes/testtwo

วันจันทร์ที่ 11 มีนาคม พ.ศ. 2562

วันอาทิตย์ที่ 10 มีนาคม พ.ศ. 2562

[TDD] อธิบาย Commit (ต่อ)

Commit ที่ 9

caa1dd6
Model for list Items and associated migration

เริ่มนำ models เข้ามาใช้งาน และทดสอบการบันทึก object ใหม่ลงใน model โดยเมื่อเรายังไม่ได้ทำการสร้างตัว model เมื่อเราทำการ test จะหา model ไม่พบ และเมื่อเราสร้าง model แล้วก็ต้องทำการ migrate model ด้วย เพื่อบอกให้ฐานข้อมูลรับทราบว่ามีการเปลี่ยนแปลง model และเมื่อมีการเปลี่ยนแปลงข้อมูลใน model จะต้องทำการตั้ง default และ makemigrations ใหม่ทุกครั้ง


Commit ที่ 10

f894a48
Redirect after POST, and show all items in template

บันทึกข้อความที่ใส่ลงในช่อง input เข้าฐานข้อมูลโดยเริ่มจากการ test ว่ามีการบันทึกข้อมูลหรือไม่โดยการรับคำที่ใส่ลงใน input มาเก็บในตัวแปร และ save ลงในฐานข้อมูล(เมื่อเปิดขึ้นมาจะเกิด error เนื่องจากยังไม่มี input) หลังจากนั้นเพิ่มฟังก์ชันให้บันทึกลงในฐานข้อมูลโดยการกำหนด test ให้เป็นข้อความหนึ่ง เมื่อมีการรัน test ข้อความนั้นจะไปปรากฏในส่วนของช่อง input และถูกส่งมาบันทึกลงบนฐานข้อมูลด้วย method POST และแสดงผลบนเว็บไซต์ด้วยการ return redirect มาที่หน้าเดิม และให้แสดงผลครั้งที่รันกับข้อความที่แสดงแต่ละครั้งที่รัน



Commit ที่ 11

eb983d5 
make functional_tests an app, use LiveServerTestCase

แก้ไขฟังก์ชัน functional test โดยไม่ใช้ setUp และ tearDown โดยการเปลี่ยนไปใช้ class LiveServerTestCase ซึ่งเป็นความสามารถของ Django โดยเมื่อเรารัน test ใหม่ข้อมูลเดิมที่ได้รันและบันทึกไว้ก็จะหายไปและเป็นการเริ่มใหม่เสมอ และจะสังเกตุเห็นได้ว่า url เปลี่ยนไป จาก 8000 เป็น 62582 ซึ่งเป็น url จาก LiveServerTestCase



Commit ที่ 12

0d4e613 
try to get url

เปลี่ยน time.sleeps เป็น ฟังก์ชัน wait_for_row_in_list_table และกำหนดเวลาในการรอ test ให้มีขอบข่ายที่ชัดเจน 
เพิ่ม url สำหรับการทำงานเฉพาะอย่าง ใช้ assertRegex สำหรับตรวจสอบ regular expression แล้วจึงเพิ่มการ test เพื่อดู url

[TDD] อธิบาย Commit (ต่อ)

Commit ที่ 5

28ed91e
Functional test now checks we can input a to-do item

เพิ่มความสนใจการ test ไปที่ส่วน header ด้วย ทำให้เกิด error เนื่องจากไม่มีการกำหนด header ไว้

Commit ที่ 6

6dc0830
Refactor home page view to use a template

สร้างเทมเพลตมาใช้งาน และ ทดลอง test การเรียกใช้งานเทมเพลตในตอนแรกจะมีการ error เนื่องจากยังไม่มีการ install apps และเมื่อ installs app แล้วก็จะใช้งานได้

Commit ที่ 7

c540754
Front page HTML now generated from a template

เพิ่มในส่วนของ header ลงไปในเทมเพลต ทำให้เทมเพลตสามารถเรียกใช้งานได้แล้วไม่เกิด error เมื่อ test ที่ส่วน header


Commit ที่ 8

1940dd3
change functional test and home.html

ใช้งาน method POST ในเทมเพลต โดยการใส่ลงใน form และทำการเพิ่ม time.sleep จาก 1 เป็น 10 (time.sleep เป็นการกำหนดค่าเวลาที่จะทำการหยุดการทดสอบชั่วคราวและแสดงผลหน้าต่างเว็บไซต์ที่ได้) ซึ่งเมื่อมีการใช้ method POST ทำให้หน้าเว็บแสดงค่า error เนื่องจากไม่มีการใส่ tag CSRF

หลังจากนั้นมีการกำหนดค่า functional test สนใจไปที่การใส่ input และ การเรียกข้อความออกมาแสดงผล โดยการกำหนดให้รับข้อความจากช่อง input มาแสดงในส่วนของ table โดยการเรียกมาใช้แบบ dict.get โดยเมื่อทำการใส่ข้อความลงไปในช่อง input และกด enter ข้อความที่ใส่จะไปปรากฏทางด้านล่างในส่วนที่เรียกผลลัพธ์ออกมาแสดง

ใส่ตัวอักษร y ลงในช่อง input


แสดงผลเป็นตัวอักษร y ที่ด้านล่าง

วันพฤหัสบดีที่ 7 มีนาคม พ.ศ. 2562

[TDD] อธิบาย Commit

commit ที่ 1

f26b0fe
First commit

เริ่มสร้าง functional_tests.py เพื่อทดสอบว่า Django พร้อมใช้งานแล้วและทดสอบการทำงานโดย
- webdriver แสดงผลการเปิดหน้าเว็บบน Firefox
- เปิดหน้าเว็บที่คาดว่าจะได้จาก local
- ดูว่า title ที่แสดงเหมือนกับชื่อที่ assert
จากนั้นสร้างโปรเจคชื่อ superlists ไว้


commit ที่ 2

e8533ab
Add app for lists, with deliberately failing unit test

บทที่2
ลอง test ว่ามี To-Do อยู่ใน title หรือไม่ จากนั้นเปลี่ยนวิธีการทดสอบโดยการ import module unittest มาใช้โดย
- สร้าง class ที่ใช้ในการทดสอบ ซึ่งใน class สามารถมีได้หลายฟังก์ชันทดสอบ
- setUp และ tearDown เป็น method พิเศาษที่จะทำงานตอนเริ่มและยุติการ test
- ถ้ามีการ test แล้ว fail จะแสดง error message 'Finish the test!'
บทที่3
ต้องการสร้างหน้า Home page
- สร้างแอพใหม่ชื่อ lists
- ทำการ test ทั้ง 2 แบบ คือ test ด้วย functional_tests.py และ test ด้วย unittest เนื่องจาก
functional_tests.py  เป็นการ test โดยการเปิดหน้าเว็บขึ้นมาและแสดงในแบบของการใช้งานของผู้ใช้ ซึ่งหากมีส่วนที่เออเร่อ จะทำให้เว็บไม่ทำงาน
unittest เป็นการ test ในส่วนของผู้พัฒนา ซึ่งจะไม่มีการเรียกเปิดหน้าเว็บใดๆขึ้นมา ซึ่งการ test จะสามารถแยก test เป็นส่วนๆได้


ทดสอบผ่าน py functional_tests.py 


ทดสอบผ่าน py manage.py test



Commit ที่ 3

0c5dfe2
First unit test and url mapping, dummy view

- test การใช้งาน url และ ฟังก์ชันใน views โดยการ import จาก views.py มา test ใน test.py จะเห็นว่า error เนื่องจากใน views.py ยังไม่มีการตั้งค่า home page
- เมื่อตั้งค่า homepage ใน views.py แล้ว ก็ต้องตั้งค่า url ด้วย เพื่อเรียกใช้งานฟังก์ชันใน views.py เมื่อ test ด้วย py manage.py test จะเห็นว่าสามารถทำงานได้แล้ว


Commit ที่ 4

816aef3
Basic view now returns minimal HTML

เพิ่มการ test เพื่อทดสอบดูหน้า homepage ให้แสดง title เป็น To-Do lists การทดสอบให้รันด้วย unit test หากเจอข้อผิดพลาดก็ให้แก้ไขและรันซ้ำจนกว่าจะได้ผลลัพธ์ตามที่ต้องการ
- เปลี่ยนแปลงฟังก์ชันใน views.py ให้ def Home_page return title เป็น To-Do lists
- เมื่อทดสอบ unit test ได้ผลลัพธ์ตามที่ต้องการแล้ว ก็ให้ทดสอบด้วย functional_tests ซ้ำอีกครั้ง
- ทดสอบเปิดหน้าเว็บ ทำงานได้

หน้าเว็บแสดง title เป็น To-Do lists ตามที่ต้องการ


วันพุธที่ 6 มีนาคม พ.ศ. 2562

TDD

            TDD ย่อมาจาก Test Driven Development ที่หมายถึงการพัฒนาโดยการสร้าง test ขึ้นมาก่อน และทำการ test ตามการทำงานย่อยของโปรแกรมที่เราออกแบบ และเมื่อ test ผ่านแล้วจึงนำโค้ดไปใช้งานได้อย่างมั่นใจ ทำให้การทำงานมีประสิทธิภาพมากขึ้น
 

            โดยในการ test ครั้งนี้ จะใช้ selenium 3 และ geckodriver test ผ่าน Firefox

วันเสาร์ที่ 23 กุมภาพันธ์ พ.ศ. 2562

ความคืบหน้าโปรเจค

การทำงานตาม use case สามารถทำงานได้ดังนี้
1 สามารถค้นหาข้อมูลรายละเอียดของร้านอาหารจากชื่อร้านได้
2 สามารถค้นหารายชื่อร้านอาหารจากประเภทของร้านอาหารได้

สิ่งที่กำลังดำเนินการ
ส่วนการรีวิวร้านอาหารที่สามารถรีวิวได้แล้ว แต่เหลือในส่วนของการกำหนดชื่อร้านโดยไม่มีการพิมพ์ชื่อร้านใส่ลงไป และเปลี่ยนการให้คะแนนเป็นแบบ radio

use case ที่ยังไม่ได้ดำเนินการ
การสุ่มร้านอาหาร

วันพฤหัสบดีที่ 21 กุมภาพันธ์ พ.ศ. 2562

Continue project


https://github.com/Freezzes/foodproject

Commit ที่ 6
create base template
สร้าง template ส่วนที่แสดง link ด้านบน และนำไปใช้ในทุกหน้า template

Commit ที่ 7
can search data from restaurant name
เพิ่มฟังก์ชันให้สามารถค้นหาข้อมูลได้เมื่อใส่ชื่อร้านที่ถูกต้องตรงกับในฐานข้อมูล

Commit ที่ 8
create template
สร้างหน้าค้นหาด้วยประเภทของร้านค้า

Commit ที่ 9
modify model & can search from category
แยกประเภทของร้านเป็น 1 โมเดลแล้วให้ร้านค้าต่างๆอยู่ในประเภทร้านค้า

Commit ที่ 10
search by name
แก้ไขการเรียกใช้งานฟังก์ชันค้นหาด้วยชื่อ

Commit ที่ 11
create review template
สร้างหน้าเทมเพลตสำหรับการรีวิว

Commit ที่ 12
change method post to get
เปลี่ยน method ที่ใช้เรียกข้อมูลออกมาแสดงเป็น GET

Commit ที่ 13
change function name
เปลียนชื่อฟังก์ชันให้สื่อถึงสิ่งที่ฟังก์ชันทำงานมากขึ้น

Commit ที่ 14
change models name & add DateTimeField
เปลี่ยนชื่อ class เป็นตัวพิมพ์ใหญ่
เพิ่มวันที่ลงในโมเดลรีวิว

Commit ที่ 15
filter shop name,review shop
กรองการค้นหาด้วยอักษรตัวแรกของชื่อร้าน และทำให้หน้ารีวิวสามารถใช้งานได้

วันเสาร์ที่ 16 กุมภาพันธ์ พ.ศ. 2562

Start Project

https://github.com/Freezzes/foodproject

เริ่มสร้างโฟลเดอร์และค่อยๆเพิ่มส่วนต่างๆของ app เข้าไป

commit ที่ 1

start project
- สร้างโปรเจค และ แอพชื่อว่า bistro

commit ที่ 2

create model
-สร้างโมเดล 2 ส่วนคือ ส่วนแรกเก็บข้อมูลร้าน ส่วนที่สองเก็บข้อมูลการรีวิว

commit ที่ 3

modify model
-แก้ไข     shop_name = models.CharField(maxlength=200)
                category = models.CharField(maxlength=20)
  เป็น
                shop_name = models.CharField(max_length=200)
                category = models.CharField(max_length=20)

commit ที่ 4

active admin & insert test data
-เปิดใช้งาน admin
-ใส่ข้อมูลร้านอาหารสำหรับทดลองใช้โปรแกรม 6 ร้าน 4 หมวดหมู่

commit ที่ 5

create url
-สร้างเทมเพลตหน้าหลักและสร้าง link ไปที่หน้าการใช้งานตาม use case

วันพุธที่ 13 กุมภาพันธ์ พ.ศ. 2562

Projectร้านอาหาร

Use Case

1 ค้นหาที่ตั้งร้านอาหารจากชื่อร้าน
2 ค้นหาร้านอาหารจากประเภทอาหาร
3 สุ่มร้านอาหาร
4 รีวิวความพึงพอใจ

Case ที่ 1
  ค้นหาที่ตั้งร้านอาหารจากชื่อร้าน
1) พิมพ์ชื่อร้านลงไปในช่องค้นหา
2) กดค้นหา
3) แสดงข้อมูลที่ตั้งร้านว่าอยู่ตรงไหน

Case ที่ 2
  ค้นหาร้านอาหารจากประเภทร้านอาหาร
1) เลือกประเภทร้านอาหาร เช่น ร้านอาหารตามสั่ง ร้านก๋วยเตี๋ยว ร้านของหวาน ฯลฯ
2) จะแสดงชื่อร้านอาหารที่ได้รับรีวิวในหมวดนั้นๆ โดยเรียงลำดับจากคะแนนมากสุดไปน้อยสุด

Case ที่ 3
  สุ่มร้านอาหาร
1) กดเข้าเมนูสุ่มร้านอาหาร
2) กดสุ่ม
3) จะแสดงชื่อร้านอาหารที่สุ่มได้ พร้อมคะแนนรีวิวร้าน
4) ถ้าต้องการสุ่มใหม่ให้กดสุ่มอีกครั้ง

Case ที่ 4
  รีวิวความพึงพอใจ
1) เลือกร้านอาหารที่ต้องการรีวิว
2) ใส่ชื่อเมนูที่จะรีวิว
3) ใส่ข้อความรีวิว
4) ให้คะแนน
5) ลงชื่อผู้รีวิว
6) กดยืนยัน


ข้อมูลที่ต้องการเก็บไว้ในฐานข้อมูลได้แก่
ชื่อร้าน :
ประเภท :
  ตามสั่ง
  ก๋วยเตี๋ยว
  ขนมหวาน
  เครื่องดื่ม
คะแนนร้าน : ( max 5 min 0 )
รีวิว         : ค่าเริ่มต้นคือไม่มี
  ชื่อเมนู
  ข้อความรีวิว
 

การทดสอบ

ใส่ข้อมูลร้านลงไปในฐานข้อมูล  5 ร้าน
ทดลองใช้งานตาม use case
1 ค้นหาที่ตั้งร้านอาหารจากชื่อร้าน
1) พิมพ์ชื่อร้าน ชั้นฟ้า ลงในช่องค้นหา
2) กด ค้นหา
3) แสดงข้อความ  “ ร้านชั้นฟ้า เป็นร้านอาหารตามสั่ง ตั้งอยู่บริเวณสะพานข้ามคลองประปาหลังมอ จุดสังเกตุเป็นรั้วสีเขียวทางด้านขวามือ ”

2 ค้นหาร้านอาหารจากประเภทอาหาร
1) กดเลือกประเภทร้านอาหารเป็น เครื่องดื่ม
2) จะแสดงชื่อร้านเรียงตามลำดับคะแนนรีวิว
     Waiting floor  4/5 คะแนน
     มาเฟีย         3/5 คะแนน

3 สุ่มร้านอาหาร
1) กดเข้าเมนูสุ่มร้านอาหาร
2) กดสุ่ม
3) จะแสดงชื่อร้านอาหารที่สุ่มได้ พร้อมคะแนนรีวิวร้าน
ชั้นฟ้า 5/5 คะแนน
4) ถ้าต้องการสุ่มใหม่ให้กดสุ่มอีกครั้ง
ซารุ 4/5 คะแนน



4 รีวิวความพึงพอใจ
1) เลือกร้าน ชั้นฟ้า
2) ใส่ชื่อเมนู ข้าวคอหมูย่าง
3) ใส่ข้อความรีวิว ข้าวเยอะหมูสุกกำลังดี บางวันอร่อยบางวันหมูเค็มไปนิดนึง น้ำจิ้มอร่อยมาก
4) ให้คะแนน 4
5) ลงชื่อผู้รีวิว น้องไอซ์คนดีที่1เลย
6) กดยืนยัน
  แสดงรีวิวของร้านชั้นฟ้าทั้งหมดที่มี



วันอังคารที่ 12 กุมภาพันธ์ พ.ศ. 2562

test ครั้งที่ 1

ให้แสดงสูตรคูณโดยการรับเลขมาจาก url และรับมาจาก input แบบ text

เริ่มจาก

รับเลขจาก url มาแสดง 3 ตัว

ในไฟล์ index.html
ให้แสดงเลขที่รับมา 3 รอบแบบไม่เว้นบรรทัด

<h1>{{number}}</h1>

    <label >{{ number }}</label>
    <label >{{ number }}</label>
    <label >{{ number }}</label>

ในไฟล์ views.py
เมื่อมีการส่ง request เข้ามา ให้ส่งค่าตัวเลขจาก url มาด้วย และนำตัวเลขนั้นไปใส่ลงใน context เพื่อส่งค่าไปใช้ที่ index.html

def show(request,id):
    context = {'number': id }
    return render(request, 'mulnum/index.html', context)

ในไฟล์ urls.py
ในการเรียก url ให้ใส่ตัวเลขลงมาด้วย
app_name = 'm'
urlpatterns = [
    path('<int:id>/', views.show, name='index'),

]

การแสดงผลการทำงาน เมื่อรับเลข 1 จาก url มา จะส่งไปให้ฟังก์ชัน
ทำการแสดงค่าผ่านเทมเพลตที่ชื่อว่า index.html


รับเเลขจาก input แบบ text มาแสดง 3 ตัว

ในไฟล์ index.html
เพิ่มในส่วนของ <form> เข้ามารับค่า input แบบ text

<h1>NUMBER</h1>

<body>
<form action= "{% url 'm:mult' %}" method="post">
        {% csrf_token %}
        <input type="text" name="inte"  >
        <input type="submit" value="SHOW">
</form>
</body>

    <label >{{ number }}</label>
    <label >{{ number }}</label>
    <label >{{ number }}</label>

ในไฟล์ views.py
สร้างฟังก์ชันให้แสดงส่วนรับ input เข้ามา และเปลี่ยนให้ context ที่นำไปแสดงผลเป็นค่าที่มาจากการป้อน input โดยการเรียก request.POST['inte']

def inputnum(request):
    return render(request,'mulnum/index.html')

def show(request):
    context = {'number': request.POST['inte'] }
    return render(request, 'mulnum/index.html', context)

ในไฟล์ urls.py
เพิ่ม path โดย input/ คือการแสดงช่อง text ที่ใช้รับ input และ mult/ คือ ให้แสดงตัวเลขที่รับมา 3 ครั้ง

app_name = 'm'
urlpatterns = [
    path('input/', views.inputnum, name='index'),
    path('mult/',views.show, name='mult')

]

    ใส่เลข 5 ลงในช่อง text
   แสดงผลเป็นเลข 5 3 ตัว



 แสดงสูตรคูณโดยการรับเลขมาจาก url

views.py
เพิ่ม loop ให้ id ที่รับมานำมาคูณกับเลขตั้งแต่ 1 - 12 และเก็บแต่ละค่าลงใน list ชื่อ number และส่ง id , number ให้แสดงผลโดยใช้เทมเพลต index.html

def show(request,id):
    number = []
    for i in range(1,13):
        ans = id * i
        number.append(ans)
    context = {
        'id': id,
        'num': number
    }
    return render(request, 'mulnum/index.html', context)

ในไฟล์ index.html
ให้แสดงสูตรคูณไว้ตรงกลางหน้าต่างแสดงผลโดยการวน loop

<h1>NUMBER</h1>

{% for i in num %}
    <center>{{id}} x {{forloop.counter}} = {{i}}</center>
    <br>
{% endfor %}
 

ในไฟล์ urls.py
ในการเรียก url ให้ใส่ตัวเลขลงมาด้วย
app_name = 'm'
urlpatterns = [
    path('<int:id>',views.show,name='mul'),

]

การแสดงผลเมื่อในเลข 4 ลงไปใน url

 แสดงสูตรคูณโดยการรับเลขมาจาก input แบบ text

ใน index.html
เพิ่มส่วนที่สร้าง input แบบ text โดยให้ไปทำฟังก์ชันที่เกี่ยวข้องกันกับ url name mult

<h1>NUMBER</h1>
<head>
    <meta charset="UTF-8">
</head>
<body>
<form action= "{% url 'm:mult' %}" method="post">
        {% csrf_token %}
        <input type="text" name="inte"  >
        <input type="submit" value="SHOW">
    </form>
</body>

<hr>

{% for i in num %}
    <center>{{id}} x {{forloop.counter}} = {{i}}</center>
    <br>
{% endfor %}
    

ใน views.py
ฟังก์ชันแรกให้แสดง textbox สำหรับให้ผู้ใช้ใส่ตัวเลขลงไป ส่วนอีกฟังก์ชันเป็นการรับค่าจาก text ที่ผู้ใช้ใส่ลงไปมาแสดงผลเป็นสูตรคูณ

def inputnum(request):
    return render(request,'mulnum/index.html')

def mul(request):
    number = []
    for i in range(1,13):
        ans = int(request.POST['inte']) * i
        number.append(ans)
    context = {
        'id': request.POST['inte'],
        'num': number
    }
    return render(request, 'mulnum/index.html', context)

ใน urls.py
เพิ่ม path mult ให้เชื่อมกันกับฟังก์ชัน mul ที่ทำการคูณค่าและเก็บไว้ใน context

app_name = 'm'
urlpatterns = [
    path('input/', views.inputnum, name='index'),   # show text box
    path('<int:id>',views.show,name='mul'),         #multiplication by number in url
    path('mult/',views.mul,name='mult'),            #multiplication by number from text box
 
]

การแสดงผลก่อนในเลขลงใน textbox

เมื่อใส่เลข 16 ลงไปและกด SHOW





 

วันอาทิตย์ที่ 10 กุมภาพันธ์ พ.ศ. 2562

[HTML] CSS


     CSS ย่อมาจาก Cascading Style Sheets เป็นภาษาที่ใช้สำหรับตกแต่งเอกสาร HTML ให้มีหน้าตา สีสัน ระยะห่าง พื้นหลัง เส้นขอบและอื่นๆ ตามที่เราต้องการ ด้วยการกำหนดคุณสมบัติให้กับ Element ต่างๆ ของ HTML เช่น <body>, <p>, <h1> เป็นต้น ซึ่ง CSS ได้รับความนิยมในการใช้งานเป็นอย่างมาก

ประโยชน์ของ CSS

     1.การใช้ CSS ในการจัดรูปแบบการแสดงผล จะช่วยลดการใช้ภาษา HTML ในการตกแต่งเอกสารเว็บเพจ ทำให้ code ภายในเอกสาร HTML เหลือเพียงส่วนเนื้อหา ทำให้เข้าใจง่ายขึ้น การแก้ไขเอกสารทำได้ง่ายและรวดเร็ว
     2.สามารถกำหนดการแสดงผลในรูปแบบที่เหมาะกับสื่อชนิดต่างๆ ไม่ว่าจะเป็นการแสดงผลบนหน้าจอ, บนกระดาษเมื่อสั่งพิมพ์, บนมือถือ หรือบน PDA โดยที่เป็นเนื้อหาเดียวกัน
     3.ทำให้เว็บไซต์มีความเป็นมาตรฐานมากขึ้นและมีความทันสมัย สามารถรองรับการใช้งานในอนาคตได้

ทดลองใช้งาน CSS

<html>
<head>
<style>
body { background-color: lightpink; }

h1 {   color: blue;
          text-align: center; }
p {     font-family: verdana;
          font-size: 20px; }
</style>
</head>
<body>

<h1>My First CSS</h1>
<p>This is a paragraph.</p>

<h1>My Second CSS</h1>
<p>This is a paragraph.</p>

</body>
</html>
---------------------
ในส่วน <style> เป็นการกำหนดลักษณะของการแสดงผลข้อความว่าต้องการให้แสดงผลในรูปแบบใด



   การแสดงผลแบบไม่มีการใช้งาน CSS  การแสดงผลเมื่อมีการใช้งาน CSS

--------------------------------------------------------------------------------------------------------------------------
การตั้งค่าตาราง

<html>
<head>
<style>
#customers {
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

#customers td, #customers th {
  border: 1px solid #ddd;
  padding: 8px;
}

#customers th {
  padding-top: 12px;
  padding-bottom: 12px;
  text-align: left;
  background-color: #4CFF70;
  color: white;
}
</style>
</head>
<body>

<table id="customers">
  <tr>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Berglunds snabbköp</td>
    <td>Christina Berglund</td>
    <td>Sweden</td>
  </tr>
  <tr>
    <td>Königlich Essen</td>
    <td>Philip Cramer</td>
    <td>Germany</td>
  </tr>
</table>
</body>
</html>
----------------------

  การแสดงผลแบบไม่มีการใช้งาน CSS การแสดงผลเมื่อมีการใช้งาน CSS

--------------------------------------------------------------------------------------------------------------------------
การแบ่งการแสดงผลเป็นหลาย column

<html>
<head>
<style>
.newspaper {
  -webkit-column-count: 3; /* Chrome, Safari, Opera */
  -moz-column-count: 3; /* Firefox */
  column-count: 3;
}
</style>
</head>
<body>

<p><b>Note:</b> Internet Explorer 9, and earlier versions, does not support the column-count property.</p>

<div class="newspaper">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
</div>

</body>
</html>

-----------------------
 การแสดงผลแบบไม่มีการใช้งาน CSS

 การแสดงผลเมื่อมีการใช้งาน CSS

--------------------------------------------------------------------------------------------------------------------------

Cr : https://blog.sogoodweb.com/Article/Detail/79237
       https://www.hellomyweb.com/course/CSS/