fb_ads

www.รับเขียนโปรแกรม.net รับเขียนโปรแกรม ระบบต่างๆ เช่น ระบบข้อมูลบุคคล ระบบข้อมูลลูกค้า ระบบซื้อขาย คลังสินค้า ระบบเช่าจอง ทำงานบน Website ด้วย PHP MySql NodeJs HTML5 JavaScript Ajax

ReactBootrap ตอน 3 สร้างตัวเลือกปฎิทินภาษาไทยแบบ ปี พ.ศ. ( DatePicker ) ด้วย React + Bootstrap


รับเขียนโปรแกรม ReactJS

เชื่อว่านักพัฒนาหลายคนต้องเคยมีปัญหากับตัวเลือกปฎิทินที่อยากได้ในรูปแบบปี พ.ศ. และเดือนที่เป็นภาษาไทย เราได้เคยเสนอวิธีแก้ปัญหาไปแล้วในบทความ

แก้ปัญหา Jquery Datepicker ให้เป็นรูปแบบ ปี พ.ศ.

สร้างตัวเลือกปฎิทินสำหรับปี พศ แบบ Mobile ( โดยไม่ต้องใช้ jquery date picker )

แต่ในบทความนี้จะแสดงวิธีสร้างตัวเลือกปฎิทิน ( Date Picker ) แบบปี พ.ศ. โดยใช้ React และ Bootstrap ซึ่งมีขั้นตอนดังนี้


 

 1.  เปิด  command prompt สร้างโปรเจคโดย ใช้คำสั่ง npx-create-react-app react_date_picker


2. เข้าไปที่ folder react_date_picker โดยใช้คำสั่ง cd react_date_picker กด enter

install ReactBootstrap โดยใช้สำสั่ง npm install react-bootstrap bootstrap@5.1.3 --save


3. install icon font awesome โดยใช้คำสั่ง
npm i --save @fontawesome/fontawesome-svg-core แล้วกด enter
npm install --save @fontawesome/free-solid-svg-icons แล้วกด enter
npm install --save @fontawesome/react-fontawesome แล้วกด enter


 

4. เปิดโปรเจคใน VS Code โดยพิมพ์ code . แล้วกด enter


5. สร้างไฟล์ date_picker.js สำหรับ Component DatePicker เพิ่ม Code สำหรับปฎิทิน ดังนี้

 
import React, {useState,useImperativeHandle,useEffect,useRef,forwardRef} from "react";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faChevronLeft,faChevronRight,faTimes } from "@fortawesome/free-solid-svg-icons";

const DatePicker=forwardRef((props,ref)=>{

        const [show_cal,set_show_cal]=useState(false);
        const [year_arr,set_year_arr]=useState([]);

        const [date_value,set_date_value]=useState("");

        const [sel_month,set_sel_month]=useState("");
        const [sel_year,set_sel_year]=useState("");

        const [cal_row,set_cal_row]=useState([]);

        const get_value=()=>{

                return date_value;
        }

        const set_value=(date)=>{

                set_show_cal(false);
                set_date_value(date);

                date=date.trim();
                let date_arr=date.split("/");
                let m = date_arr[1].toString();
                m=m.length==1?"0"+m:m;
                let y = (parseInt(date_arr[2])-543).toString();

                set_sel_month(m);
                set_sel_year(y);

        }

        useImperativeHandle(ref ,()=>{
        
                return {
                    "get_value":get_value,
                    "set_value":set_value
                }
                
        });

        const go_next_month=()=>{

                let m=parseInt(sel_month);
                let y=parseInt(sel_year);
                m++;
                if(m==13)
                {
                        m=1;
                        y++;
                }

                m=m.toString();
                m=m.length==1?"0"+m:m;

                set_sel_month(m);
                set_sel_year(y);
        }

        const go_pre_month=()=>{

                let m=parseInt(sel_month);
                let y=parseInt(sel_year);
                m--;
                if(m==0)
                {
                        m=12;
                        y--;
                }

                m=m.toString();
                m=m.length==1?"0"+m:m;

                set_sel_month(m);
                set_sel_year(y);
        }

        const select_date=(d)=>{
                if(d=="")
                {
                    return;
                }

                d=d.toString();
                let m=sel_month.toString();
                let y=parseInt(sel_year)+543;

                d=d.length==1?"0"+d:d;
                m=m.length==1?"0"+m:m;

                set_date_value(d+"/"+m+"/"+y);
                set_show_cal(false);
        }

      
        useEffect(()=>{

                let min_year=0;
                let max_year=0;
                let year_arr=[];
                if(
                    (props.min_year!=null) && (props.max_year!=null ) &&
                    ( parseInt(props.min_year) <= parseInt(props.max_year) )
                )
                {
                        min_year=parseInt(props.min_year);
                        max_year=parseInt(props.max_year);
                }
                else
                {
                        let y=(new Date()).getFullYear();
                        min_year=y-2;
                        max_year=y+2;
                }

                do
                {
                     year_arr.push(min_year);
                     min_year++;

                }while(min_year < max_year)

                set_year_arr(year_arr);

        },[]);

        useEffect(()=>{
        
            if(show_cal)
            {
                if( sel_month=="" )
                {
                        let m=(new Date()).getMonth()+1;
                        m=m.toString();
                        m=m.length==1?"0"+m:m

                        set_sel_month(m);
                }

                if( sel_year=="" )
                {
                        let y=(new Date()).getFullYear();
                        if(y > parseInt(year_arr[year_arr.length-1]))
                        {
                                y=year_arr[year_arr.length-1];
                        }
                        y=y.toString();
                        set_sel_year(y);
                }
            }
                

        },[show_cal]);

        useEffect(()=>{
                
                if(sel_month=="" || sel_year==""){ return; }
                
                let d=new Date ( parseInt(sel_year),parseInt(sel_month)-1,1 );
                
                let arr=[];
                let temp=[];

                for(var i=0;i<d.getDay();i++)
                {
                        temp.push("");
                }

                while(d.getMonth()==(parseInt(sel_month)-1))
                {
                        let d_str=d.getDate().toString();
                        d_str=d_str.length==1?"0"+d_str:d_str;

                        temp.push(d_str);
                        if(d.getDay()==6)
                        {
                                arr.push(temp);
                                temp=[];
                        }
                        d.setDate(d.getDate() + 1);
                }

                if(temp.length!=0)
                {
                        while(temp.length!=7)
                        {
                                temp.push("");
                        }
                        arr.push(temp);
                }
               
                set_cal_row(arr);

        },[sel_year,sel_month]);

        return (<>
           
            <input  className="form-control form-control-sm"  value={date_value}
                    onClick={event=>{if(show_cal){set_show_cal(false);}else{set_show_cal(true);}}}
                    onChange={event=>{event.target.value="";}}
                    
            />
            {(show_cal)?
                <div className="mt-2 bg-white" style={{width:"100%"}} >

                        <div className="row">
                                <div className="col-3  text-end">
                                        <button type="button" className="btn btn-primary btn-sm" onClick={event=>{go_pre_month()}}>
                                                <FontAwesomeIcon icon={faChevronLeft} />
                                        </button>
                                </div>
                                <div className="col-3">
                                    <select className="form-select form-select-sm" value={sel_month} onChange={event=>set_sel_month(event.target.value)}>
                                            <option value="01">มกราคม</option>
                                            <option value="02">กุมภาพันธ์</option>
                                            <option value="03">มีนาคม</option>
                                            <option value="04">เมษายน</option>
                                            <option value="05">พฤษภาคม</option>
                                            <option value="06">มิถุนายน</option>
                                            <option value="07">กรกฎาคม</option>
                                            <option value="08">สิงหาคม</option>
                                            <option value="09">กันยายน</option>
                                            <option value="10">ตุลาคม</option>
                                            <option value="11">พฤศจิกายน</option>
                                            <option value="12">ธันวาคม</option>
                                    </select>
                                </div>
                                <div className="col-3">
                                    <select className="form-select form-select-sm" value={sel_year} onChange={event=>set_sel_year(event.target.value)}>
                                        {year_arr.map(item=>
                                                <option value={item} >{parseInt(item)+543}</option>        
                                        )}
                                    </select>
                                </div>
                                <div className="col-3">
                                        <button type="button" className="btn btn-primary btn-sm" onClick={event=>{go_next_month()}}>
                                                <FontAwesomeIcon icon={faChevronRight} />
                                        </button>
                                </div>
                        </div>

                        <table className="table table-sm mt-2" style={{width:"100%"}}>
                                <thead>
                                        <tr className="table-active text-center">
                                                <th>อา</th>
                                                <th>จ</th>
                                                <th>อ</th>
                                                <th>พ</th>
                                                <th>พฤ</th>
                                                <th>ศ</th>
                                                <th>ส</th>
                                        </tr>

                                </thead>
                                <tbody className="text-center">
                                        {cal_row.map(item=>
                                                <tr>
                                                        {item.map(item2=>
                                                                <td className="text-cenetr" style={{cursor:"pointer"}}
                                                                        onClick={event=>{select_date(item2)}}
                                                                >{item2}</td>
                                                        )}
                                                </tr>
                                        )}
                                </tbody>
                        </table>
                        
                        <div className="text-end">
                                <button className="btn btn-sm btn-danger" type="button" onClick={event=>{
                                        set_date_value("");
                                        set_show_cal(false);
                                }}>
                                        <FontAwesomeIcon icon={faTimes} />  ล้างข้อมูลปฎิทิน
                                </button>
                        </div>

                </div>
            :null}
            

        </>)

});

export default DatePicker;


 6. สำหรับการเรียกใช้งาน Component DatePicker

import 'bootstrap/dist/css/bootstrap.min.css';
import {useRef} from "react";
//นำเข้า Component DatePicker
import DatePicker from './date_picker';

function App() {

  //สร้างตัวแปรอ้างอิงค์ Component DatePicker โดยใช้ชื่อว่า DatePicker
  const date_picker=useRef();

  return (
    <div>
        <div className="container mt-5" >
          <div className="mb-3">
              <label  className="form-label">วันที่</label>
              {/* ----สร้าง Component DatePicker--- */}
              <DatePicker ref={date_picker} label="วันที่"  />
          </div>
          <div className="mb-3">
              <button className="btn btn-primary" type="button" onClick={event=>{
                date_picker.current.set_value("01/01/2565");
                //.set_value("วัน/เดือน/ปี พ.ศ. ")
              }} >
                Set Date Picker
              </button>
              &nbsp;
              <button className="btn btn-primary" type="button" onClick={event=>{
                alert(date_picker.current.get_value());
                //.get_value() สำหรับรับค่าวันที่ที่เลือกซึ่งจะ return ค่าเป็น string รูปแบบ "วัน/เดือน/ปี พ.ศ. "
              }} >
                Get Date Picker
              </button>
          </div>
        </div>
    </div>
  );

}

export default App;


ผลลัพธ์ที่ได้คือ


ReactBootrap ตอน 2 การสร้างเมนูด้านข้างด้วย ReactBootrap และการใช้งานร่วมกับ react-router-dom

จากบทความ วิธีสร้าง Responsive Side Menu (Bootstrap เมนูด้านข้าง) สำหรับ Bootstrap5  ในบทความนี้จะนำเสนอวิธีการสร้างเมนูด้านข้าง ( Side Menu ) ด้วย React โดยใช้ Bootstrap 

หมายเหตุ ตัวอย่างนี้ใช้ react-router-dom version 5.3.0 ซึ่งตอนนี้มี version react-router-dom ใหม่แล้ว

 รับเขียนโปรแกรม ReactJS

Link ที่เกี่ยวข้อง
วิธีสร้าง Responsive Side Menu (Bootstrap เมนูด้านข้าง) สำหรับ Bootstrap5

ReactBootrap ตอน 1 การสร้าง Master Page และ ตัวอย่างการใช้งาน react-router-dom ใน ReactBootrap

 


1. จาก  โปรเจคที่แล้ว ReactBootrap ตอน 1 การสร้าง Master Page และ ตัวอย่างการใช้งาน react-router-dom ใน ReactBootrap ให้เพิ่ม Font Awesome สำหรับ React เพื่อใช้เป็น icon สำหรับ เมนูบาร์

ด้วยคำสั่ง

npm i --save @fortawesome/fontawesome-svg-core
npm install  --save @fortawesome/free-solid-svg-icons
npm install  --save @fortawesome/react-fontawesome

ดังรูป


2. เปิด VS Code ด้วยคำสั่ง .code


3. แก้ไฟล์ใน master_page.js ใน folder src ดังนี้


import { Navbar, Container } from 'react-bootstrap';
// import Offcanvas, ListGroup จาก react-bootstrap
import { Offcanvas, ListGroup} from 'react-bootstrap';
// import icon bars จาก react-fontawesome
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBars } from "@fortawesome/free-solid-svg-icons";
//เรียก ใช้ useState ( ของ React Hook )
import { useState } from "react";
//เรียก ใช้ useHistory จาก react-router
import { useHistory } from "react-router";

import 'bootstrap/dist/css/bootstrap.min.css';
//สร้าง Component Master Page
const MasterPage=(props)=>{

    const [show_menu, set_show_menu] = useState(false);//สถานะสำหรับเปิดปิดเมนูข้าง
    const history = useHistory();//สำหรับเปลี่ยนหน้า

    return (<>
    {/*-------สร้าง แถบเมนูด้านบน ด้วย Navbar จาก ReactBootstrap-----------*/}
    <Navbar bg="light" expand="lg">
        <Container>
          <Navbar.Brand
            style={{ cursor: "pointer" }}
            onClick={(event) => {
              set_show_menu(true);
            }}
          >
            <FontAwesomeIcon icon={faBars} /> React-Bootstrap
          </Navbar.Brand>
        </Container>
    </Navbar>
    
    {/*-------- Offcanvas สำหรับเมนูด้านข้าง --------- */}
    <Offcanvas
        show={show_menu}
        onHide={(event) => {
          set_show_menu(false);
        }}
        style={{ maxWidth: "300px" }}
      >
        <Offcanvas.Header closeButton>
          <Offcanvas.Title>Menu</Offcanvas.Title>
        </Offcanvas.Header>
        <Offcanvas.Body>
          <ListGroup variant="flush">
            {/* ------สร้างเมนูสำหรับ Link ไปหน้า Page1----- */}
            <ListGroup.Item
              action
              onClick={(event) => {
                set_show_menu(false);//เมื่อคลิก เมนู page1 ให้ซ่อน side menu
                history.push("/page1");//ไปที่หน้า page1
              }}
            >
              Page1
            </ListGroup.Item>
             {/* ------สร้างเมนูสำหรับ Link ไปหน้า Page2----- */}
            <ListGroup.Item
              action
              onClick={(event) => {
                set_show_menu(false);//เมื่อคลิก เมนู page2 ให้ซ่อน side menu
                history.push("/page2");//ไปที่หน้า page2
              }}
            >
              Page2
            </ListGroup.Item>

          </ListGroup>
        </Offcanvas.Body>
      </Offcanvas>

        <div className="container">
            {/*--------ส่วนของเนื้อหาเว็บที่จะมาแสดง-----*/}
            {props.children}
        </div>
        

    </>)

}

export default MasterPage;

4. ทดลองรันโดยกลับไปที่หน้า command line แล้วพิมพ์ npm run start

ผลลัพธ์ที่ได้คือ


เมื่อลองเปิด เมนูด้สนข้างจะปรากฎ offcanvas ดังนี้





ReactBootrap ตอน 1 การสร้าง Master Page และ ตัวอย่างการใช้งาน react-router-dom ใน ReactBootrap

การทำ Master Page เกิดจากการที่ หน้าเว็บจะมีส่วนต่างๆที่เหมือนๆ กันในแต่ละหน้า เช่น Header Menu Footer หากเรามีหน้าเว็บ 20 หน้า และมีการเพิ่ม เมนูขึ้นมาทีหลังเราต้องแก้เมนูทั้ง 20 ไฟล์ แต่จะดีกว่าหากเราสามารถแก้ไขข้อมูลในไฟล์เดียว แล้วหน้าเว็บทั้ง 20 หน้า เปลี่ยนตามไปด้วย

ในบทความนี้จะแสดงตัวอย่างการทำ Master Page โดยใช้ ReactJS  Bootstrap และ react-router-dom และเป็นการแสดงตัวอย่างของ การใช้งาน ReactBootstrap ร่วมกับ react-router-dom อีกด้วย

หมายเหตุ ตัวอย่างนี้ใช้ react-router-dom version 5.2.0 ซึ่งตอนนี้มี version react-router-dom ใหม่แล้ว

รับเขียนโปรแกรม ReactJS

 Link ที่เกี่ยวข้อง ตัวอย่างการใช้งาน React Router DOM ใน React Material UI ตอน 1

ดู code ในcode sand box

https://codesandbox.io/embed/intelligent-wind-hhnln?fontsize=14&hidenavigation=1&theme=dark

 

1. สร้าง Project ชื่อว่า ด้วยคำสั่ง npx  create-react-app react_bootstrap

2. เข้าไปใน folder react_bootstrap ที่เพิ่งสร้าง ด้วยคำสั่ง cd react_bootstrap และ install ReactBoostrap ด้วยคำสั่ง npm install react-bootstrap@next bootstrap@5.1.1 --save

 

3.install react-router-dom ด้วยคำสั่ง npm install react-router-dom --save

4. เปิด project ใน visual studio code ด้วนคำสั่ง code . 


5. สร้างไฟล์ master page ชื่อว่า master_page.js

 


 ใส่ code ดังนี้

import { Navbar, Container ,Nav} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
//สร้าง Component Master Page
const MasterPage=(props)=>{


    return (<>
    {/*-------สร้าง แถบเมนูด้านบน ด้วย Navbar จาก ReactBootstrap-----------*/}
    <Navbar bg="light" expand="lg">
    <Container>
        <Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
        <Nav className="me-auto">
            {/*--------สร้าง Link ไปที่ page1----------*/}
            <Nav.Link href="#/page1">Page1</Nav.Link>
            {/*--------สร้าง Link ไปที่ page2----------*/}
            <Nav.Link href="#/page2">Page2</Nav.Link>
        </Nav>
        </Navbar.Collapse>
    </Container>
    </Navbar>

        <div className="container">
            {/*--------ส่วนของเนื้อหาเว็บที่จะมาแสดง-----*/}
            {props.children}
        </div>
        

    </>)

}

export default MasterPage;

6. สร้างไฟล์ page1.js และ page2.js โดยมี code ดังนี้ 

ไฟล์ page1.js

//import ไฟล์ master page
import MasterPage from "./master_page";

const Page1=()=>{

    return(<MasterPage>

        <h4>Page1</h4>

    </MasterPage>);
}

export default Page1;

ไฟล์ page2.js

//import ไฟล์ master page
import MasterPage from "./master_page";

const Page2=()=>{

    return(<MasterPage>

        <h4>page2</h4>

    </MasterPage>);
}

export default Page2;

7. แก้ไฟล์ App.js เพื่อกำหนด Route

//เรียกใช้ Object ใน react-router-dom
import {
  HashRouter,
  Switch,
  Route,
  useParams,
  useHistory
} from "react-router-dom";
import Page1 from "./page1";
import Page2 from "./page2";

function App() {
  return (
    <>
    <HashRouter>
      <Switch>
        <Route exact path="/" children={<Page1 />}></Route>
        {/*  เมื่อเปิดมาหน้าแรกให้แสดง Component  Page1  */}
        <Route path="/page1" children={<Page1 />}></Route>
        {/*  สำหรับ Path /page1 ให้แสดง Component  Page1  */}
        <Route path="/page2" children={<Page2 />}></Route>
        {/*  สำหรับ Path /page2 ให้แสดง Component  Page2  */}
        <Route path="*" children={<Page1 />}></Route>
        {/* ถ้าไม่ตรงกับ path ตามที่กำหนเไว้ด้านบนให้แสดง Component  Page1  */}
      </Switch>
    </HashRouter>
  </>
  );
}

export default App;

ผลลัพธ์ที่ได้คือ


 

หากเราต้องการเพิ่มเมนู หรือแก้ไข ้ข้อความ header เราสามารถเพิ่มได้ในเมนู ในไฟล์ master_page.js แล้วทั้งหน้า page1 กับ page2 ก็จะเปลี่ยนตาม


เนื้อหาถัดไป ReactBootrap ตอน 2 การสร้างเมนูด้านข้างด้วย ReactBootrap และการใช้งานร่วมกับ react-router-dom