Category: Javascript

  • เค้าเอาไฟล์ MP4 บน Google Drive ไปแสดงใน Video Player บนเว็บได้อย่างไร

    สมมุติว่า เรามีไฟล์วิดีโอเป็น .mp4 อยู่ไฟล์หนึ่ง อยู่ใน Google Drive ต้องการเผยแพร่ เฉพาะบน Website ของเราเท่านั้น จะต้องทำอย่างไร?

    Javascript video player

    สิ่งแรกที่ต้องมีคือ ตัว Video Player บนเว็บ ลอง Google ด้วยคำว่า “javascript video player” ดู มีหลายตัวให้เลือกใช้ แต่ในที่นี้ ขอทดลองกับ video.js (เว็บไซต์ https://videojs.com )

    คลิกที่ USE NOW ( https://videojs.com/getting-started/ )

    จากนั้น ลองสร้างไฟล์ test.html โดยเอา Code จาก Video.js CDN ไปแปะเลย

    <head>
      <link href="https://vjs.zencdn.net/7.6.5/video-js.css" rel="stylesheet">
    
      <!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
      <script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
    </head>
    
    <body>
      <video id='my-video' class='video-js' controls preload='auto' width='640' height='264'
      poster='MY_VIDEO_POSTER.jpg' data-setup='{}'>
        <source src='MY_VIDEO.mp4' type='video/mp4'> <!-- แก้ตรงนี้ -->
        <source src='MY_VIDEO.webm' type='video/webm'>
        <p class='vjs-no-js'>
          To view this video please enable JavaScript, and consider upgrading to a web browser that
          <a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
        </p>
      </video>
    
      <script src='https://vjs.zencdn.net/7.6.5/video.js'></script>
    </body>

    จาก Code นี้ JavaScript จาะเรียกไฟล์ .MP4 จากไฟล์ชื่อ MY_VIDEO.mp4 ซึ่ง ถ้าเอา test.html นี้ไปวางบน Web Server ก็หมายความว่า เราต้องมีไฟล์ MY_VIDEO.mp4 ด้วย

    ไฟล์ MP4 บน Google Drive

    ตัวอย่างเช่น เราอาจอัดคลิปวิดีโอการสอน อยากจะเผยแพร่บนเว็บไซต์ของหน่วยงาน ผ่าน JavaScript Video Player อย่าง video.js ข้างต้น ก็สามารถทำได้ดังนี้

    1. แชร์ไฟล์ดังกล่าว ให้เป็น Anyone with the link can View
    2. แล้ว copy link นั้นมา หน้าตาประมาณนี้

      https://drive.google.com/open?id=FILE_ID
    3. จะเห็นคำว่า id= FILE_ID ตรงนี้ให้ Copy เก็บไว้

    แต่การที่เราจะเอา Link นี้ไปใช้ใน Video Player ตรง ๆ ไม่ได้ เพราะมันเป็นการเรียกใช้ Google Drive ไม่ใช่การเรียก File Content

    GoogleAPI

    วิธีการที่จะ Get Content ของไฟล์ที่ต้องการออกมากจาก Google Drive สามารถเรียกผ่าน Google API ซึ่ง หากจะทำเองก็สามารถทำได้ มีพวก node.js ให้ใช้งานอยู่ แต่พบว่า สามารถเรียกใช้ www.googleapis.com ได้ โดยอ้างอิงจาก https://googleapis.github.io/

    ในที่นี้ จะเรียกผ่าน Google Drive API ใน Version 3 รูปแบบ URL จะเป็นดังนี้

    https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media&key=API_KEY

    ในการใช้งาน ต้องการ 2 ส่วน

    • FILE_ID ได้จากการแชร์ไฟล์ข้างต้น
    • API_KEY ได้มาจากการสร้าง Credential บน Google Cloud Platform วิธีการทำตามนี้ https://cloud.google.com/docs/authentication/api-keys

    การใช้งาน Google API นั้น มีส่วนทั้งที่ต้องจ่ายเงิน และส่วนที่ใช้ฟรี แต่ถูกจำกัด Quota ในกรณี Google Drive API สามารถใช้ได้ฟรี แต่จะมี Quota อยู่ โดยดูได้จาก https://developers.google.com/drive/api/v3/about-sdk

    ประกอบร่าง

    เมื่อได้ FILE_ID และ API_KEY มาแล้ว ก็เอาไปใส่ใน Code ข้างต้น

    <head>
      <link href="https://vjs.zencdn.net/7.6.5/video-js.css" rel="stylesheet">
    
      <!-- If you'd like to support IE8 (for Video.js versions prior to v7) -->
      <script src="https://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
    </head>
    
    <body>
      <video id='my-video' class='video-js' controls preload='auto' width='640' height='264'
      poster='MY_VIDEO_POSTER.jpg' data-setup='{}'>
        <source src='https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media&key=API_KEY' type='video/mp4'> <!-- เปลี่ยนตรงนี้ -->
        <source src='MY_VIDEO.webm' type='video/webm'>
        <p class='vjs-no-js'>
          To view this video please enable JavaScript, and consider upgrading to a web browser that
          <a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
        </p>
      </video>
    
      <script src='https://vjs.zencdn.net/7.6.5/video.js'></script>
    </body>

    หวังว่าจะเป็นประโยชน์ครับ

    Disclaimer: จุดประสงค์ของบทความนี้ เพื่อแนะนำวิธีการทำเท่านั้น โปรดนำความรู้นี้ไปใช้งานอย่างสร้างสรรค์นะครับ ผู้เขียนบทความไม่เกี่ยวข้องใด ๆ กับผู้นำไปใช้ทั้งสิ้น

  • Hello…Flatpickr!!

    หลายคนอาจะเคยพบปัญหาการเลือก วัน เดือน ปี ในcalendar การกรอกข้อมูลที่เป็นวันที่ใน web ต่างๆ การเลือกช่วงวันที่ใช้งานยาก โดยเฉพาะในการเลือก ช่วงเวลา ที่ย้อนหลัง ไปหลายปี บาง web อาจต้องกดเลื่อนเดือนที่ละเดือนไปเรื่อยๆ ต้องใช้เวลานาน ทำให้รู้สึกเบื่อ… วันนี้เราจะมานำเสนอ Flatpickr ที่เป็นไลบรารี่ javascript ใช้สำหรับรับ input ที่เป็น datetime picker ที่ยืดหยุ่น มีขนาดเล็กและใช้ง่าย โดย output ที่ได้จะเป็น String ตาม format ที่เราต้องการ

    Flatpickr js รูปแบบจะเป็นแนว Lean กับ UX-driven สามารถใช้งานได้กับ JS ธรรมดาหรือ jQuery โดย Flatpickr รองรับภาษาไทยได้โดยเลือก Localization เป็นไทยเพื่อให้สามารถแสดงเป็นภาษาไทย และรองรับรูปแบบเวลาที่แสดง 24 ชม. เพราะจะเข้าใจง่ายกว่า AM กับ PM ซึ่ง library อื่นๆ อีกหลายตัวยังไม่สามารถรองรับ จุดเด่น คือ มีความสวยงาม ไม่ต้องการ dependencies ใดๆ สามารถใช้งานได้ทันที

    การใช้งานสามารถใช้ได้ง่ายๆ โดยใช้แค่ 2 ไฟล์ ก็สามารถใช้ option ได้เกือบครบ ซึ่งไฟล์ ที่จำเป็นประกอบด้วย ไฟล์ js 1 ไฟล์ และ ไฟล์ css 1 ไฟล์

    <link rel=”stylesheet” href=”flatpickr.css”>

    <script src=”flatpickr.js”></script>

    ถ้าใช้งานร่วมกับ jquery ก็ต้อง เพิ่ม library jquery เข้ามาด้วย

      <script src=”jquery.min.js”></script>

    การใช้งาน

    $(“.selector”).flatpickr(
    optional_config
    );

    ตัวอย่างกล่อง input ที่ใช้เลือก วันที่

     <input type=”text” id=”timePicker” placeholder=”Please select Time”>

    การแสดงเวลาแบบ Basic
    $(“#basicDate”).flatpickr({
    enableTime: true,
    dateFormat: “F, d Y H:i”,
    time_24hr: true
    });

    ภาพที่ 1 ฺBasic Calendar

    เราสามารถกำหนดช่วงของวันที่ค้นหาได้ง่ายขึ้น เนื่องจากมี Range Calendar (ภาพที่ 2) ให้ใช้งาน หรือจะเป็นเลือกแบบ Multiple เลือกทีละหลายๆวันก็ได้ และยังมี Plugin หรือ Theme ให้เลือกใช้งานอีกด้วย

    การแสดงเวลาแบบ Range Datetime
    $(“#rangeDate”).flatpickr({
    mode: ‘range’,
    dateFormat: “Y-m-d”
    });

    ภาพที่ 2 Range Calendar
  • Uploading Files into Database with ASP.NET MVC

    การ    upload  file มีหลายรูปแบบ ไม่ว่าจะเป็นการ upload file  แบบ copy ไว้บน server หรือจะเป็นการบันทึกลงในฐานข้อมูลเลยโดยตรง วันนี้จะขอนำเสนอในส่วนของการ upload   file  และบันทึกลงฐานข้อมูล     โดยใช้ ASP.NET MVC  ดังนี้

     

    กำหนดไฟล์ที่ต้องการ upload ให้มีรูปแบบดังนี้

          public class UploadModel

    {

    [Required]

    public HttpPostedFileBase File { get; set; }

    }

     

    ในส่วนของ    View

     

    <form id=”uploader” enctype=”multipart/form-data” method=”POST”>

    <a type=”submit” href=”#” onclick=”uploadConfirm();” class=”btn btn-info”><span class=”glyphicon glyphicon-save”></span>&nbsp;Upload</a>

    </form>

    ในส่วนของ java script (สำหรับเรียก Controller)

      function uploadConfirm() {

    $.ajax({

    type: ‘POST’,

    contentType: ‘application/json; charset=utf-8’,

    url: ‘@Url.Action(“CheckDataBeforeUpload”, “NoteUpload”)’,

    data: “{ ‘periodID’:’” + $(‘#selectedlistPeriods’).val() +

    “‘ ,’financeID’:’” + $(‘#selectedlistFinance’).val() +

    “‘ }”,

    success: function (resultSave) {

     

    },

    error: function (data) {

    alert(data);

    }

    });

    }

     

    ในส่วนของ Controller

    public async Task<ActionResult> UploadFile(UploadModel model, FormCollection form)

    {

     

    string fileName = Path.GetFileName(model.File.FileName); //แสดงชื่อไฟล์

    string strFileName = Path.GetFileNameWithoutExtension(fileName); //แสดงชื่อไฟล์

    string contentType = model.File.ContentType;  //แสดงนามสกุลไฟล์

     

    string FileExtension = fileName.Substring(fileName.LastIndexOf(‘.’) + 1).ToLower();

    using (Stream fs = model.File.InputStream) //

    {

    using (BinaryReader br = new BinaryReader(fs))

    {

    byte[] bytes = br.ReadBytes((Int32)fs.Length);

     

    //TO DO:  Code ในส่วนที่ต้องการ insert ข้อมูลลง Database

    }

    }

     

    return RedirectToAction(“Index”);

    }

     

    จากตัวอย่างข้างต้น จะเป็นการ upload file ลงฐานข้อมูลโดยตรงในส่วนของรูปแบบการพัฒนาแบบ MVC ผู้เขียนหวังว่าอาจจะเป็นอีกทางเลือกหนึ่งของผู้พัฒนา ในการนำไปพัฒนาโปรแกรมต่อไปนะคะ ^_^

    แหล่งอ้างอิง

    https://stackoverflow.com/questions/15106190/uploading-files-into-database-with-asp-net-mvc

    https://stackoverflow.com/questions/21677038/mvc-upload-file-with-model-second-parameter-posted-file-is-null/21677156

  • การปรับเปลี่ยนรูปแบบการแสดงผลเส้นทางระหว่างพิกัดจุดบนแผนที่ Google Map APIs ด้วย DirectionsTravelMode

              ก่อนที่เราจะไปเริ่มเนื้อหาของบทความี้ ผู้เขียนต้องขอท้าวความเดิมตอนที่แล้วของบทความก่อน ซึ่งผู้เขียนได้พูดถึงวิธีการแสดงผลเส้นทางทางระหว่างพิกัดจุดบนแผนที่ Google Map APIs ด้วย DirectionsService ในเบื้องต้นไว้ (สามารถศึกษาเพิ่มเติมได้จากบทความ : การแสดงเส้นทางระหว่างพิกัดจุดบนแผนที่ Google Map APIs ด้วย DirectionsService ในเบื้องต้น )  สำหรับในบทความนี้ผู้เขียนจึงอยากต่อยอดการทำงาน และเพิ่มลูกเล่นให้กับการแสดงผลแผนที่ด้วยการปรับเปลี่ยนการกำหนดรูปแบบการแสดงผลของเส้นทางให้ผู้เยี่ยมชมเว็บไซต์  ซึ่งเราจะให้ผู้ใช้สามารถเลือกรูปแบบในการแสดงผลได้ว่า ต้องการดูเส้นทางในรูปแบบใดตามรูปแบบ Mode ที่ผู้ใช้เลือกมา เช่น เส้นทางเดิน ทางถนน หรือขนส่งสาธารณะ เป็นต้น โดยวิธีการดังกล่าวนี้เหมาะกับเว็บไซต์ที่มีความเกี่ยวข้องกับความต้องการที่ต้องการทราบเส้นทางในแต่ละรูปแบบ เพื่อเป็นประโยชน์ในการนำไปประยุกต์ใช้กับงานของแต่ละท่านได้ค่ะ

       ตัวอย่างผลลัพธ์ที่ได้จากบทความที่แล้ว 

    ซึ่งจากตัวอย่างโค้ดในบทความที่แล้ว การกำหนด DirectionsTravelMode เป็น DRIVIING ซึ่งในความเป็นจริงแล้วยังมีรูปแบบอื่นๆให้เลือกใช้ด้วยกันทั้งหมด 4 รูปแบบ ดังนี้

    DRIVING (Default):เป็นโหมดตั้งต้นให้หากไม่ได้มีการกำหนดไว้ ซึ่งเป็นโหมดที่แสดงเส้นทางการขับขี่ด้วยยานพาหนะ
    BICYCLING: เป็นโหมดสำหรับเส้นทางที่เตรียมไว้สำหรับผู้ขับขี่จักรยาน
    TRANSIT: เป็นโหมดสำหรับแสดงเส้นทางระบบขนส่งสาธารณะ เช่น  รถบัส รถไฟ หรือแม้แต่เครื่องบิน เป็นต้น
    WALKING: เป็นโหมดสำหรับแสดงเส้นทางการเดินถนน

              ซึ่งผู้เขียนจะขอยกตัวอย่างในส่วนของการเลือกรูปแบบเส้นทางและผลลัพธ์ของแต่ละรูปแบบ ดังตัวอย่างโค้ดต่อไปนี้

    • การกำหนดรูปแบบของเส้นทางในการแสดงผลบนแผนที่
    1. โค้ด Javascript
       <script type="text/javascript">
      function initialize() {
       // ประกาศเรียกใช้งาน DirectionsService เพื่อการแสดงผลให้มีลักษณะเป็น Global
       window.directionsService = new google.maps.DirectionsService();
       window.directionsDisplay = new google.maps.DirectionsRenderer();
       var map;
       var bounds = new google.maps.LatLngBounds();
       var mapOptions = {
       mapTypeId: 'roadmap'
       };
      
      // แสดงผลแผนที่ในหน้าจอตาม Element ที่กำหนด
       map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
       map.setTilt(45);
      
      // กำหนดพิกัดจุดให้กับจุดเริ่มต้นและเส้นสุด
       window.markers = [
       ['Place1', 51.501546, -0.142000],
       ['Place2', 51.512051,-0.091225]
       ];
      // ให้แสดงผลสิ่งที่ตั้งค่าไว้ในพื้นที่แผนที่ที่กำหนด
       directionsDisplay.setMap(map);
      // กำหนดค่าเริ่มต้นของรูปแบบให้เป็นเส้นทางการเดิน (walking mode)
       calcRoute();
      }
      // เป็นฟังก์ชั่นในการคำนวณเส้นทางระหว่างสองจุดพิกัดบนแผนที่และเลือกกำหนดค่า Mode ในการแสดงผล
       function calcRoute() {
        var selectedMode = document.getElementById('travelType').value;
        var request = {
       
        origin: new google.maps.LatLng(markers[0][1], markers[0][2]),
       
        destination: new google.maps.LatLng(markers[1][1], markers[1][2]),
      
      //// //กำหนดรูปแบบการแสดงผลเส้นทางโดยเริ่มต้นให้เป็นเส้นทางการเดิน(ตามรายการแรกที่เลือก)
        travelMode: google.maps.TravelMode[selectedMode]
        };
        
       directionsService.route(request, function(response, status) {
       if (status == google.maps.DirectionsStatus.OK) {
       directionsDisplay.setDirections(response);
       }
       });
       }
       </script>
    2. ส่วนของการแสดงผลใน body
      <body> 
      <div id="map_wrapper">
       <div id="map_canvas" class="mapping"></div>
      </div>
      <div id="travel_selector">
       <p><strong>Mode of Travel: </strong>
       <select id="travelType" onchange="calcRoute();">
       <option value="WALKING">Walking</option>
       <option value="BICYCLING">Bicycling</option>
       <option value="DRIVING">Driving</option>
       <option value="TRANSIT">Transit</option>
       </select></p>
      </div>
      </body>
    3. ผลลัพธ์ในแต่ละรูปแบบ
    • แบบที่ 1 DRIVING Mode :

     

    • แบบที่ 2 BICYCLING Mode:

    • แบบที่ 3 TRANSIT Mode:


    • แบบที่ 4 WALKING Mode:


                จากตัวอย่างจะเห็นได้ว่าเป็นพิกัดของประเทศในต่างแดน เนื่องจากก่อนหน้านี้ ผู้เขียนลองใช้พิกัดจุดบนพื้นที่ประเทศไทย แต่พบว่ามีบาง Mode ยังไม่รองรับ เช่น เส้นทางจักรยาน ซึ่งเมื่อเลือกกำหนดโหมดดังกล่าวจะไม่เห็นการเปลี่ยนแปลงใดๆ จึงหันไปยกตัวอย่างจาก London แทนเพื่อให้ผู้อ่านได้เห็นความแตกต่างในการแสดงผลแต่ละแบบได้ชัดเจนขึ้น แต่เพื่อไม่ให้เป็นการน้อยเนื้อต่ำใจกัน ผู้เขียนก็ได้ลองเอาพิกัดของพื้นที่ในประเทศไทยมาลองทำดูให้ผู้อ่านได้เห็นแถมมาด้วยว่าพื้นที่ของเราจะเห็นเส้นทางเป็นยังไงในแต่ละแบบกันบ้าง ดังนี้ค่ะ
      ตัวอย่างการแสดงเส้นทางระหว่างสนามบินสุวรรณภูมิและเขตจตุจักร
      1) แบบ Transit mode

       

      จะเห็นได้ว่า เมื่อคลิกที่รูปสัญลักษณ์เครื่องหมายคำพูด จะแสดงรายละเอียดเกี่ยวกับข้อมูลการขนส่งสาธารณะนั้นๆ เช่น รถเมล์สายใด รถไฟฟ้า BTS สายใด เป็นต้น

      2) แบบ Walking Mode


      3) แบบ Driving Mode

                จากบทความ จะเห็นได้ว่านี่เป็นอีกหนึ่งตัวอย่างในการเพิ่มลูกเล่นให้กับการใช้งานแผนที่เท่านั้น โดยยังมีอีกหลายวิธีการรอให้เราศึกษาเพื่อนำมาประยุกต์ใช้และเพิ่มความสามารถให้กับการใช้งานแผนที่ในเว็บไซต์ของเรา ผู้เขียนหวังว่าบทความนี้จะเป็นประโยชน์กับผู้อ่านสามารถหยิบยกไปใช้ประโยชน์ได้ไม่มากก็น้อย หากมีข้อผิดพลาดประการใดผู้เขียนขออภัยไว้ ณ ที่นี้ด้วยนะคะ ขอบคุณค่ะ ^^


      แหล่งข้อมูลอ้างอิง :

     

  • การเรียกใช้งาน (Register) Bootbox.js ด้วย C#.NET

    ในการออกแบบเว็บฟอร์มบันทึกข้อมูลลงฐานข้อมูลนั้น นักพัฒนาเว็บแอ๊พปลิเคชั่นส่วนใหญ่จะออกแบบเป็นลำดับขั้นตอนการทำงานประมาณนี้

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

    การพัฒนาเว็บด้วย ASP.NET นั้นในขั้นตอนที่ 4 จะถูกเขียนด้วยโค้ด C#.NET ซึ่งเป็น Server Side Script ส่วนขั้นตอนที่ 5 นั้นเราสามารถใช้ Dialog ของ Bootbox.js ซึ่งเป็น Client Side Script มาช่วยได้ ซึ่งในบทความนี้จะแสดงวิธีการเขียนโค้ด C#.NET ให้เรียกใช้ Bootbox Dialog ได้เลย  (อ่านบทความ การสร้าง JavaScript Dialog ด้วย Bootbox.js ได้ที่นี่) และสร้างเป็นฟังก์ชั่นสำเร็จรูปไว้เรียกใช้งานใหม่ได้ (Reuse)

     

    การรันคำสั่ง Bootbox.js ซึ่งเป็น JavaScript ผ่าน C#.NET นั้นจะต้องใช้ ScriptManager ช่วยลงทะเบียนสคริปต์ (Register Script) ดังนี้

    รูปที่ 1 การ Register Script ด้วย ScriptManager

    เพียงเท่านี้ก็สามารถนำส่วนของโค้ดดังรูปที่ 1 ไปใช้ในการแสดงข้อความแจ้งผู้ใช้หลังการบันทึกข้อมูลลงฐานข้อมูลได้แล้ว โดยมีตัวอย่างดังรูปที่ 2

    รูปที่ 2 การแสดงข้อความแจ้งผู้ใช้หลังการบันทึกข้อมูล

    ผลลัพธ์ที่ได้จากโค้ดข้างต้นจะเป็นดังรูปที่ 3

    รูปที่ 3 ผลลัพธ์ของข้อความแจ้งเตือนจากการบันทึกข้อมูล

    แน่นอนว่าในการพัฒนาเว็บแอ๊พปลิเคชัน 1 ครั้ง จะประกอบด้วยฟอร์มบันทึกข้อมูลมากมาย ทำให้ต้องเขียนโค้ดซ้ำๆ กันหลายครั้ง จากโค้ดข้างต้นเราสามารถ Optimize โค้ดได้อีกโดยให้สามารถเรียกใช้งานและแก้ไขโค้ดในภายหลังได้ง่ายขึ้น โดยการย้ายส่วนลงทะเบียนสคริปต์ไปไว้ในฟังก์ชั่นกลางสร้างเป็น Library (ในที่นี้จะตั้งชื่อว่า CoreBLL) สำเร็จรูปไว้ใช้ต่อไปดังนี้

    รูปที่ 4 CoreBLL

    หลังจากที่สร้าง CoreBLL เสร็จแล้วให้แก้ไขโค้ดบันทึกข้อมูลดังรูปที่ 5

    รูปที่ 5 โค้ดบันทึกข้อมูลลงฐานข้อมูล

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

     

  • การสร้าง JavaScript Dialog ด้วย Bootbox.js

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

    JavaScript Confirm บน Google Chrome

     

    JavaScript Confirm บน Mozilla Firefox

    ตัวอย่างโค้ดเรียกใช้งาน JavaScript Confirm

    จากรูปจะเห็นว่า JavaScript Confirm บน Google Chrome และ Mozilla Firefox หน้าตาไม่เหมือนกัน ทั้งๆที่ใช้โค้ดเดียวกัน และปัญหาอีกอย่างหนึ่งที่พบคือ หากเราต้องการให้ข้อความ “คุณต้องการลบข้อมูลรายการนี้ใช่หรือไม่?” มีการขึ้นบรรทัดใหม่ ใส่สี เพิ่มขนาดฟอนต์ จัดตัวหนา ตัวเอียงก็ไม่สามารถทำได้เลย แต่ถ้าต้องการให้แก้ปัญหาเหล่านี้ได้ก็ต้องใช้ตัวช่วย นั่นคือ Bootbox.js ซึ่งเป็น JavaScript library ที่ใช้งานร่วมกับ Bootstrap โดยใช้ Bootstrap modal มาทำหน้าที่แทน JavaScript Dialog ต่างๆ ทั้ง Alert, Confirm, Prompt และรวมถึง Custom Dialog ด้วย ทำให้หน้าตาของ Dialog จะเหมือนกันทุก Browser และสามารถจัดรูปแบบการแสดงผลได้ตามต้องการโดยใช้ CSS

    วิธีการติดตั้ง

    1. เข้าไปที่เว็บไซต์ http://bootboxjs.com และเลือกดาวน์โหลดไฟล์ชื่อ bootbox.min.js หรือถ้าไม่ต้องการดาวน์โหลดก็สามารถใช้ CDN (https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js) ได้เช่นกัน
    2. ใส่โค้ดอ้างอิงไปยัง bootbox.min.js ใน header tag ดังนี้
      <script src=”path/to/script/bootbox.min.js”></script>
      หรือ
      <script src=https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js></script>

    ตัวอย่างการใช้งาน Confirm Dialog

    1. กำหนดชื่อ CSS class ให้กับปุ่มลบ ในที่ตั้งชื่อว่า “confirm”

      กำหนดชื่อ CSS Class ให้กับปุ่มลบ
    2. แทรกโค้ด JavaScript ใน HTML ดังนี้

      JavaScript สำหรับ Confirm Dialog
    3. ลองเปิดเว็บด้วย Google Chrome และ Mozilla Firefox ก็จะได้ผลลัพธ์เหมือนกันดังรูป

      Confirm Dialog ที่สร้างขึ้นด้วย Bootbox.js

    นอกจาก Confirm Dialog แล้ว ท่านสามารถดูตัวอย่าง Dialog แบบอื่นๆ ได้จากที่นี่ เพียงเท่านี้ก็จะสามารถสร้าง Dialog สวยๆ และมีความยืดหยุ่นไว้ใช้งานได้แล้ว

     

  • Pass special characters in JavaScript function

    ในการพัฒนาโปรแกรมไม่ว่าจะพัฒนาด้วยภาษาใดก็ตาม ทุกภาษาจะมี special characters ซึ่ง special characters บางตัวอาจจะถูกระบุให้เป็นตัวแปร หรือ ใช้อักขระพิเศษเพื่อระบุอยู่ลำดับสุดท้ายของข้อความของบรรทัด เป็นต้น   ซึ่งตรงส่วนนี้จะทำให้ประสบปัญหาในการนำ special characters ไปใช้งาน นั่นคือจะทำให้เกิด Error ทำให้โปรแกรมไม่สามารถทำงานต่อได้ ซึ่งJavaScript ก็เป็นอีกหนึ่งภาษาที่ประสบปัญหานี้ เช่น การส่ง parameter ผ่าน function ของ JavaScript โดยค่าของ parameter ที่ส่งไปเป็น special characters ทำให้เกิด Error และโปรแกรมไม่สามารถทำงานต่อได้

     

    วันนี้จะขอแนะนำเทคนิคในการแก้ปัญหาดังกล่าว นั่นก็คือ การ Encoding และ Decoding ในที่นี้ผู้เขียนได้พัฒนาในรูปแบบ MVC โดยใช้ JavaScript ในการเรียก Controller จึงใช้วิธีการ Encoding กับ JavaScript และ ทางฝั่ง Controller จะใช้ C# จึงใช้ C# ในการ Decoding ค่ะ
    1.วิธีการ Encoding in JavaScript ในการจะส่ง parameter ผ่านทาง function ของ JavaScript โดยข้อความนั้นมี special characters จำเป็นที่จะต้องมีการ Encoding ในที่นี้เราจะใช้ฟังก์ชัน Escape() ของ JavaScript
    ตัวอย่าง Encoding in JavaScript

    <script>   
    
      function SaveData() {
    
            var txtDocTitle = $('#txtDocTitle').val();
    
    
            $('#pleaseWaitDialog').modal();
            $.ajax({
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                url: "@Url.Action("SaveDataToTable", "I_EXPENSE")",
                data: "{'budgetYear':'" + valueYear +
                    "' ,'docTitle':'" + escape(txtDocTitle) +
                    "'}",
                success: function (data) {
    
                },
                error: function (data) {
                    alert(data);
                }
            });
        }
          </script>

    จากตัวอย่างกรณีป้อนข้อมูลที่มี special characters เช่น “I’m *&^$ special characters” เมื่อใช้ function escape(“I’m *&^$ special characters”) จะได้ผลลัพธ์ดังนี้

     ผลลัพธ์จากการเรียกใช้ escape()

    I%u2019m%20*%26%5E%24%20special%20characters
    

    หลังจากที่มีการเรียกใช้ escape() จะทำให้สามารถส่ง parameter ที่มี special characters ไปได้โดยไม่พบ Error โปรแกรมสามารถทำงานได้ปกติ เป็นอันผ่านไปหนึ่งด่านในส่วนของการเรียกใช้งาน function ของ JavaScript แต่ทว่าการที่เราจะนำข้อความที่ผ่านการ Encoding มาใช้งานไม่ได้ เนื่องจากจะไม่ถูกต้องตามความต้องการของผู้ใช้งาน จากตัวอย่างข้างต้น ผู้ใช้งานป้อนข้อมูล “I’m *&^$ special characters” สิ่งที่โปรแกรมต้องทำการบันทึกก็ต้องเป็น “I’m *&^$ special characters” ไม่ใช่ “I%u2019m%20*%26%5E%24%20special%20characters” ดังนั้นจึงจำเป็นจะต้องมีการ Decoding เพื่อให้ได้ข้อมูลที่ถูกต้อง
    2.Decoding in C# เมื่อมีการ Encoding เราจำเป็นที่จะต้อง Decoding เพื่อให้ได้ข้อมูลที่ถูกต้องตามที่ผู้ใช้งานได้ป้อนข้อมูล
    ตัวอย่าง Decoding in C#

          var docTitle = HttpUtility.UrlDecode(docTitle, System.Text.Encoding.Default);
           //ตรงส่วนนี้ตัวแปร docTitle จะมีค่าเท่ากับ “I’m *&^$ special characters”  ค่ะ
          

    เมื่อ Decoding แล้ว ก็จะได้ข้อความที่ถูกต้องตามที่ผู้ใช้งานได้ป้อนข้อมูลและสามารถนำไปใช้งานได้อย่างถูกต้องแล้วนะคะ

     

    สำหรับบทความนี้ก็ขอจบเพียงเท่านี้และหวังว่าผู้พัฒนาคงหมดกังวลในส่วนของ Special character ที่ส่งค่า parameter ผ่านทาง JavaScript ได้อย่างไม่มี error มากวนใจผู้พัฒนากันอีกแล้วนะคะ ^_^

     

     

    แหล่งอ้างอิง :

    https://developer.mozilla.org/th/docs/Web/JavaScript/Reference/Global_Objects/escape

    http://stackoverflow.com/questions/3778165/unescape-javascripts-escape-using-c-sharp

  • การค้นหาสถานที่ด้วย Places search box และแสดงผลภาพจากข้อมูล Street View บน Google Maps

           ความเดิมจากตอนที่แล้วของบทความ “การดึงค่าละติจูดและลองจิจูดของสถานที่ด้วย Places search box บน Google Maps” เพื่อแก้ปัญหาในการดึงค่าละติจูด-ลองจิจูดจากชื่อสถานที่ที่ผู้ใช้พิมพ์ค้นหาไว้ โดยมีการนำ “Places search box” มาใส่ไว้ในแผนที่ที่เราต้องการแทนนั้น ถือเป็นตัวช่วยให้กับผู้ใช้ในระดับหนึ่ง  แต่สำหรับในบทความนี้ ผู้เขียนจะขอต่อยอดความรู้ดังกล่าว โดยได้ศึกษาและนำวิธีการแสดงผลภาพจากข้อมูล Street view มาประยุกต์ใช้ร่วมด้วย เพื่อให้ผู้ใช้สามารถมองเห็นสถานที่จริงที่เลือกได้จากแผนที่ได้ด้วย ซึ่งจะยิ่งช่วยอำนวยความสะดวกให้กับผู้ใช้ ทำให้ผู้ใช้สามารถตรวจสอบได้ว่าสถานที่ดังกล่าวเป็นสถานที่ที่ต้องการจะดึงค่าละติจูด-ลองจิจูดจริงหรือไม่ได้อีกทางหนึ่งนั่นเอง ซึ่งวิธีการบางส่วนจะขอยกยอดมาจากบทความก่อนหน้านี้ เกี่ยวกับเรื่องการดึงค่าละติจูด-ลองจิจูดจากการค้นหาโดยใช้ Places search box และจะขอเพิ่มเติมความสามารถในการแสดงผลภาพ Street View  รวมทั้งสามารถคลิกจุดพิกัดใหม่บนแผนที่ เพื่อค้นหาตำแหน่ง สถานที่ตั้ง และรายละเอียด รวมถึงภาพจาก Street View ได้อีกด้วย เพื่อให้การดึงค่าพิกัดใกล้เคียงความจริงมากที่สุด โดยมีวิธีการดังนี้

    • ส่วนของสไตล์ชีทในการแสดงผล ขึ้นกับการตกแต่งของผู้พัฒนาแต่ละท่าน
    <!—ส่วนของ Style Sheets->
    <style>
    html, body {
     height: 100%;
     margin: 0;
     padding: 0;
    }
    #map {
     width: 100%;
     height: 400px;
    }
    .controls {
     margin-top: 10px;
     border: 1px solid transparent;
     border-radius: 2px 0 0 2px;
     box-sizing: border-box;
     -moz-box-sizing: border-box;
     height: 32px;
     outline: none;
     box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    }
    #searchInput {
     background-color: #fff;
     font-family: Roboto;
     font-size: 15px;
     font-weight: 300;
     margin-left: 12px;
     padding: 0 11px 0 13px;
     text-overflow: ellipsis;
     width: 80%;
    }
    #searchInput:focus {
     border-color: #4d90fe;
    }
    
    </style>
    
    • ส่วนของการอ้างอิง libraries เพื่อใช้งาน Google API
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRbMoDPc_mTv3D3QPqe0Ar84nSvRhA8nk&libraries=places&callback=initMap" async defer></script>
    
    • ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล
      • ฟังก์ชั่น initMap() ซึ่งจะเรียกใช้งานตอนเริ่มต้นโหลดหน้าจอขึ้นมา
    <script>
     var panorama;
     var map;
     var markers = [];
    /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่*****/
     function initMap() {
    
    /***** ประกาศตำแหน่งพิกัดกึ่งกลางให้กับการแสดงผลแผนที่ ในที่นี้กำหนดเป็นกรุงเทพมหานคร*****/
     var center_point = { lat: 13.7563309, lng: 100.50176510000006 };
     var sv = new google.maps.StreetViewService();
    
    /***** เป็นส่วนของการแสดงผลภาพจาก Street View *****/
     panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'));
    
     /***** กำหนดรายละเอียดคุณสมบัติของแผนที่*****/
     var map = new google.maps.Map(document.getElementById('map'), {
     center: {lat: center_point.lat, lng: center_point.lng},
     zoom: 13,
     streetViewControl: false // เป็นส่วนที่ Set เพิ่มเติมจากปกติ
     });
    
    sv.getPanorama({ location: center_point, radius: 50 }, processSVData);
    
    /***** กำหนด event เมื่อมีการคลิกแผนที่*****/
     map.addListener('click', function(event) {
     
    /***** ล้างข้อมูลการกำหนดจุด เพื่อให้มีการกำหนดจุดพิกัดเพียงจุดเดียว*****/
     for (i = 0; i < markers.length; i++) {
     markers[i].setMap(null);
     }
    
    /***** ดึงค่าข้อมูลจาก Street View ตามพิกัดที่คลิกบนแผนที่ *****/
     sv.getPanorama({ location: event.latLng, radius: 50 }, processSVData);
     var geocoder = new google.maps.Geocoder();
     geocoder.geocode({
     'latLng': event.latLng
     }, function(results, status) {
     if (status == google.maps.GeocoderStatus.OK) {
    
    /***** แสดงผลข้อมูลรายละเอียดสถานที่*****/
     if (results[0]) {
        var place = results[0];
         for (var i = 0; i < place.address_components.length; i++) {
           if (place.address_components[i].types[0] == 'postal_code') {
             document.getElementById('postal_code').innerHTML = place.address_components[i].long_name;
          }
     if (place.address_components[i].types[0] == 'country') {
     document.getElementById('country').innerHTML = place.address_components[i].long_name;
        }
      }
     document.getElementById('location').innerHTML = results[0].formatted_address;
     document.getElementById('lat').innerHTML = results[0].geometry.location.lat();
     document.getElementById('lon').innerHTML = results[0].geometry.location.lng();
        }
       }
     });
     });
     /***** กำหนดตำแหน่งที่ตั้งของ control ที่จะวางในแผนที่*****/
     var input = document.getElementById('searchInput');
     map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
    
     /***** เพิ่ม Feature ให้กับ textbox ให้สามารถพิมพ์ค้นหาสถานที่ได้*****/
     var autocomplete = new google.maps.places.Autocomplete(input);
     autocomplete.bindTo('bounds', map);
    
     var infowindow = new google.maps.InfoWindow();
     
     /***** กำหนดคุณสมบัติให้กับตัวพิกัดจุดหรือ marker *****/
     var marker = new google.maps.Marker({
     map: map,
     anchorPoint: new google.maps.Point(0, -29)
     });
    markers.push(marker); //เก็บค่าการกำหนดจุดพิกัดไว้ในตัวแปร markers เพื่อใช้ล้างข้อมูลการกำหนดจุดได้
    
     /***** ทำงานกับ event place_changed หรือเมื่อมีการเปลี่ยนแปลงค่าสถานที่ที่ค้นหา*****/
     autocomplete.addListener('place_changed', function() {
     infowindow.close();
     marker.setVisible(false);
     var place = autocomplete.getPlace();
     if (!place.geometry) {
     window.alert("ไม่ค้นพบพิกัดจากสถานที่ดังกล่าว");
     return;
     }
    
     /***** แสดงผลบนแผนที่เมื่อพบข้อมูลที่ต้องการค้นหา *****/
     if (place.geometry.viewport) {
     map.fitBounds(place.geometry.viewport);
     } else {
     map.setCenter(place.geometry.location);
     sv.getPanorama({ location: place.geometry.location, radius: 50 }, processSVData);
     map.setZoom(17);
     }
     marker.setIcon(({
     url: place.icon,
     size: new google.maps.Size(71, 71),
     origin: new google.maps.Point(0, 0),
     anchor: new google.maps.Point(17, 34),
     scaledSize: new google.maps.Size(35, 35)
     }));
     marker.setPosition(place.geometry.location);
     marker.setVisible(true);
     
     /***** แสดงรายละเอียดผลลัพธ์การค้นหา *****/
     var address = '';
     if (place.address_components) {
     address = [
     (place.address_components[0] && place.address_components[0].short_name || ''),
     (place.address_components[1] && place.address_components[1].short_name || ''),
     (place.address_components[2] && place.address_components[2].short_name || '')
     ].join(' ');
     }
     /***** แสดงรายละเอียดผลลัพธ์การค้นหาเป็น popup โดยมีชื่อและสถานที่ดังกล่าว *****/
     infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
     infowindow.open(map, marker);
    
     /***** แสดงรายละเอียดผลลัพธ์การค้นหา ซึ่งประกอบด้วย ที่อยู่ รหัสไปรษณีย์ ประเทศ ละติจูดและลองจิจูด *****/
     for (var i = 0; i < place.address_components.length; i++) {
     if(place.address_components[i].types[0] == 'postal_code'){
     document.getElementById('postal_code').innerHTML = place.address_components[i].long_name;
     }
     if(place.address_components[i].types[0] == 'country'){
     document.getElementById('country').innerHTML = place.address_components[i].long_name;
     }
     }
     document.getElementById('location').innerHTML = place.formatted_address;
     document.getElementById('lat').innerHTML = place.geometry.location.lat();
     document.getElementById('lon').innerHTML = place.geometry.location.lng();
     });
    }
    </script>
    
    • ฟังก์ชั่น processSVData() เป็นฟังก์ชั่นที่ใช้ในการนำค่าของ Street view มาแสดงผล
    <script>
    function processSVData(data, status) {
     if (status === 'OK') {
     
      marker = new google.maps.Marker({
     position: data.location.latLng,
     map: map,
     title: data.location.description
     });
     markers.push(marker);
     panorama.setPano(data.location.pano);
     panorama.setPov({
     heading: 270,
     pitch: 0
     });
     panorama.setVisible(true);
    
     marker.addListener('click', function() {
     
     var markerPanoID = data.location.pano;
     // Set the Pano to use the passed panoID.
     panorama.setPano(markerPanoID);
     panorama.setPov({
     heading: 270,
     pitch: 0
     });
     panorama.setVisible(true);
     });
     } else {
     console.error('ไม่พบข้อมูล Street view ตามสถานที่ดังกล่าว');
     }
     }
    </script>
    
    • ส่วนของการแสดงผล (ใน tag body)
    <body>
    
    <!--ส่วนของการแสดงรายละเอียดผลลัพธ์ที่ได้->
     <table style="width: 100%">
     <tr>
     <td>
    <!--ส่วนของ Element ที่ใช้ในการแสดงผล->
     <input id="searchInput" class="controls" type="text" placeholder="Enter a location">
    <div id="map" style="width: 60%;height:360px;float:left"></div>
    <div id="pano" style="width: 40%;height:360px; float:left"> </div><br />
     </td>
     
     </tr>
     <tr>
     <td>
     <div id="Div1" style="width: 100%;" >
     <ul id="geoData">
     <li>ที่อยู่: <span id="location"></span></li>
     <li>รหัสไปรษณีย์ : <span id="postal_code"></span></li>
     <li>ประเทศ: <span id="country"></span></li>
     <li>ละติจูด: <span id="lat"></span></li>
     <li>ลองจิจูด: <span id="lon"></span></li>
    </ul>
    </div>
    
     </td>
     </tr>
     
     </table>
     <!--ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผลที่กล่าวไว้ก่อนหน้านี้-> <script> /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่ และอื่นๆตามที่กล่าวไว้แล้วข้างต้น*****/ </script> <!--สิ้นสุดส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล-> </body>

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

    1. เมื่อเปิดหน้าจอขึ้นมา จะแสดงพิกัดที่จังหวัดกรุงเทพมหานครเป็นค่าตั้งต้น และฝั่งขวาเป็นภาพที่ดึงข้อมูลมาได้จากพิกัดดังกล่าวจากข้อมูล Street Views

    2. พิมพ์ค้นหาชื่อสถานที่ และเลือกสถานที่ที่ต้องการ

    3. เมื่อเลือกสถานที่เรียบร้อย จะมีการกำหนดพิกัดจุดตามชื่อสถานที่ที่เลือกไว้ และแสดงผลภาพจาก Street View รวมทั้งแสดงรายละเอียดในส่วนล่างของหน้าจอ ดังภาพ

           นอกจากการค้นหาพิกัดและข้อมูลภาพจาก Street View โดยใช้วิธีการพิมพ์ค้นหาแล้วนั้น ผู้ใช้ยังสามารถค้นหาพิกัดใหม่ได้จากการคลิกบนแผนที่ได้อีกด้วย ซึ่งจะแสดงผลลัพธ์ได้เช่นกัน ดังภาพ

           ผู้เขียนหวังเป็นอย่างยิ่งว่า บทความนี้จะช่วยเพิ่มประสิทธิภาพและเป็นอีกหนึ่งทางเลือกให้กับผู้พัฒนาได้หยิบยกวิธีการดึงค่าละติจูด-ลองจิจูดและการแสดงผลข้อมูลไปประยุกต์ใช้กับงานของแต่ละท่าน และอาจถือเป็นการเพิ่มลูกเล่นให้กับเว็บไซต์ของท่านให้มีความสามารถที่หลากหลายมากขึ้นเกี่ยวกับการใช้งานร่วมกับแผนที่ Google Maps หากผู้อ่านท่านใดมีข้อเสนอแนะหรือแนะนำวิธีเพิ่มเติมเกี่ยวกับเรื่องดังกล่าว ผู้เขียนยินดีเป็นอย่างยิ่งที่จะรับฟังและร่วมแบ่งปันความรู้ร่วมกันค่ะ หากบทความนี้มีส่วนผิดพลาดประการใด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วยค่ะ ^^

    แหล่งข้อมูลอ้างอิง :  

    https://www.tutorialspoint.com/google_maps/google_maps_symbols.htm

    http://www.codexworld.com/autocomplete-places-search-box-google-maps-javascript-api/

          https://developers.google.com/maps/documentation/javascript/examples/streetview-service

  • การดึงค่าละติจูดและลองจิจูดของสถานที่ด้วย Places search box บน Google Maps

           ก่อนจะพูดถึงเนื้อหาของบทความนี้ ผู้เขียนขอท้าวความไปถึงบทความก่อนหน้าที่เป็นเนื้อหาที่เกี่ยวข้องกับการดึงค่าละติจูด-ลองจิจูดของสถานที่ เพื่อมากำหนดจุดพิกัดบนแผนที่ หรือที่เรารู้จักกันดีในนามของ Google maps (ซึ่งสามารถหาอ่านได้จากลิงค์ ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C# (ภาคต่อ) และหากท่านต้องการศึกษาเกี่ยวกับวิธีการกำหนดพิกัดบนแผนที่เพิ่มเติมสามารถหาอ่านได้จากลิงค์ ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C# เช่นกัน) แต่หลังจากที่ผู้เขียนได้นำไปทดลองใช้งานการดึงค่าพิกัดที่ค้นหา พบว่าเกิดปัญหาในการค้นหาพิกัดของสถานที่ในบางกรณี คือ ไม่สามารถค้นหาพิกัดของบางสถานที่ที่ต้องการได้ และในบางครั้งผู้ใช้เลือกสถานที่ที่จะดึงค่าพิกัดมาใช้งานผิด เนื่องจากชื่อสถานที่อาจคล้ายกัน แต่ตั้งอยู่กันคนละประเทศ หรือทวีป โดยผู้ใช้อาจไม่เห็นภาพว่าสถานที่ดังกล่าวอยู่ส่วนใดของแผนที่ จึงทำให้พิกัดที่ได้มีความผิดพลาดหรือคลาดเคลื่อนได้ ผู้เขียนจึงได้ลองศึกษาเพิ่มเติม และปรับเปลี่ยนวิธีการ เพื่อให้การดึงค่าพิกัดเป็นไปได้ง่าย และอำนวยความสะดวกต่อผู้ใช้งานมากขึ้น รวมทั้งเพิ่มช่องทางในการค้นหาข้อมูลพิกัดได้มากขึ้นและมีความถูกต้องแม่นยำขึ้น

    ตัวอย่างภาพการทำงานของการดึงค่าพิกัดที่ผู้เขียนเคยเขียนไว้ก่อนหน้านี้

    แบบที่ 1 การเรียกใช้เซอร์วิสของ Google Geocoding API โดยการส่งพารามิเตอร์เป็นที่อยู่ของสถานที่ดังกล่าว

       

    แบบที่ 2 แบบใช้ place Autocomplete ซึ่งเป็น feature ของ Google Places API ที่จะช่วยในการค้นหาที่อยู่จากชื่อสถานที่ได้และประยุกต์เพิ่มเติมเพื่อดึงค่ามาแสดงเมื่อมีการเลือกรายการสถานที่นั้นๆ

         

           จากปัญหาดังกล่าวข้างต้น ผู้เขียนได้ปรับเปลี่ยนวิธีการในการดึงค่าละติจูด-ลองจิจูดจากชื่อสถานที่ที่ผู้ใช้พิมพ์ค้นหาไว้ โดยมีการนำ “Places search box” มาใส่ไว้ในแผนที่ที่เราต้องการแทน เพื่อให้ผู้ใช้สามารถมองเห็นสถานที่จริงที่เลือกได้จากแผนที่ ซึ่งสามารถตรวจสอบได้ว่าสถานที่ดังกล่าวเป็นสถานที่ที่ต้องการจะดึงค่าละติจูด-ลองจิจูดจริงหรือไม่อีกทางหนึ่งนั่นเอง โดยมีวิธีการดังนี้

    • ส่วนของสไตล์ชีทในการแสดงผล ขึ้นกับการตกแต่งของผู้พัฒนาแต่ละท่าน
    <!—ส่วนของ Style Sheets-->
    <style>
    html, body {
     height: 100%;
     margin: 0;
     padding: 0;
    }
    #map {
     width: 100%;
     height: 400px;
    }
    .controls {
     margin-top: 10px;
     border: 1px solid transparent;
     border-radius: 2px 0 0 2px;
     box-sizing: border-box;
     -moz-box-sizing: border-box;
     height: 32px;
     outline: none;
     box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    }
    #searchInput {
     background-color: #fff;
     font-family: Roboto;
     font-size: 15px;
     font-weight: 300;
     margin-left: 12px;
     padding: 0 11px 0 13px;
     text-overflow: ellipsis;
     width: 50%;
    }
    #searchInput:focus {
     border-color: #4d90fe;
    }
    
    </style>
    
    • ส่วนของการอ้างอิง libraries เพื่อใช้งาน Google API
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRbMoDPc_mTv3D3QPqe0Ar84nSvRhA8nk&libraries=places&callback=initMap" async defer></script>
    
    • ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล
    <script>
    /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่*****/
     function initMap() {
     
     /***** กำหนดรายละเอียดคุณสมบัติของแผนที่*****/
     var map = new google.maps.Map(document.getElementById('map'), {
     center: {lat: -33.8688, lng: 151.2195},
     zoom: 13
     });
    
     /***** กำหนดตำแหน่งที่ตั้งของ control ที่จะวางในแผนที่*****/
     var input = document.getElementById('searchInput');
     map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
    
     /***** เพิ่ม Feature ให้กับ textbox ให้สามารถพิมพ์ค้นหาสถานที่ได้*****/
     var autocomplete = new google.maps.places.Autocomplete(input);
     autocomplete.bindTo('bounds', map);
    
     var infowindow = new google.maps.InfoWindow();
     
     /***** กำหนดคุณสมบัติให้กับตัวพิกัดจุดหรือ marker *****/
     var marker = new google.maps.Marker({
     map: map,
     anchorPoint: new google.maps.Point(0, -29)
     });
    
     /***** ทำงานกับ event place_changed หรือเมื่อมีการเปลี่ยนแปลงค่าสถานที่ที่ค้นหา*****/
     autocomplete.addListener('place_changed', function() {
     infowindow.close();
     marker.setVisible(false);
     var place = autocomplete.getPlace();
     if (!place.geometry) {
     window.alert("ไม่ค้นพบพิกัดจากสถานที่ดังกล่าว");
     return;
     }
    
     /***** แสดงผลบนแผนที่เมื่อพบข้อมูลที่ต้องการค้นหา *****/
     if (place.geometry.viewport) {
     map.fitBounds(place.geometry.viewport);
     } else {
     map.setCenter(place.geometry.location);
     map.setZoom(17);
     }
     marker.setIcon(({
     url: place.icon,
     size: new google.maps.Size(71, 71),
     origin: new google.maps.Point(0, 0),
     anchor: new google.maps.Point(17, 34),
     scaledSize: new google.maps.Size(35, 35)
     }));
     marker.setPosition(place.geometry.location);
     marker.setVisible(true);
     
     /***** แสดงรายละเอียดผลลัพธ์การค้นหา *****/
     var address = '';
     if (place.address_components) {
     address = [
     (place.address_components[0] && place.address_components[0].short_name || ''),
     (place.address_components[1] && place.address_components[1].short_name || ''),
     (place.address_components[2] && place.address_components[2].short_name || '')
     ].join(' ');
     }
     /***** แสดงรายละเอียดผลลัพธ์การค้นหาเป็น popup โดยมีชื่อและสถานที่ดังกล่าว *****/
     infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
     infowindow.open(map, marker);
    
     /***** แสดงรายละเอียดผลลัพธ์การค้นหา ซึ่งประกอบด้วย ที่อยู่ รหัสไปรษณีย์ ประเทศ ละติจูดและลองจิจูด *****/
     for (var i = 0; i < place.address_components.length; i++) {
     if(place.address_components[i].types[0] == 'postal_code'){
     document.getElementById('postal_code').innerHTML = place.address_components[i].long_name;
     }
     if(place.address_components[i].types[0] == 'country'){
     document.getElementById('country').innerHTML = place.address_components[i].long_name;
     }
     }
     document.getElementById('location').innerHTML = place.formatted_address;
     document.getElementById('lat').innerHTML = place.geometry.location.lat();
     document.getElementById('lon').innerHTML = place.geometry.location.lng();
     });
    }
    </script>
    • ส่วนของการแสดงผล (ใน tag body)
    <body>
    <!--ส่วนของ Element ที่ใช้ในการแสดงผล-->
    <input id="searchInput" class="controls" type="text" placeholder="Enter a location">
    <div id="map"></div>
    <!--ส่วนของการแสดงรายละเอียดผลลัพธ์ที่ได้-->
    <ul id="geoData">
     <li>ที่อยู่: <span id="location"></span></li>
     <li>รหัสไปรษณีย์: <span id="postal_code"></span></li>
     <li>ประเทศ: <span id="country"></span></li>
     <li>ละติจูด: <span id="lat"></span></li>
     <li>ลองจิจูด: <span id="lon"></span></li>
    </ul>
    
    <!--ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผลที่กล่าวไว้ก่อนหน้านี้-->
                                                                
    <script>
    /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่ และอื่นๆตามที่กล่าวไว้แล้วข้างต้น*****/
    </script>
    <!--สิ้นสุดส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล->
     </body>

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

    1. เมื่อพิมพ์ชื่อสถานที่ เช่น มหาวิทยาลัยสงขลานครินทร์ จะมีรายการชื่อสถานที่ให้ผู้ใช้เลือก

    2. เมื่อเลือกชื่อสถานที่ที่ต้องการ เช่น มหาวิทยาลัยสงขลานครินทร์ จะมีการแสดงรายละเอียดของสถานที่ดังกล่าวดังภาพตามหมายเลข 1,2 และ 3 ตามลำดับ

           ผู้เขียนหวังเป็นอย่างยิ่งว่า บทความนี้จะช่วยแก้ปัญหาให้กับผู้ที่อาจจะกำลังเจอปัญหาในแบบเดียวกันกับผู้เขียนในการดึงค่าละติจูด-ลองจิจูดเพื่อนำไปกำหนดจุดพิกัดบนแผนที่อยู่ไม่มากก็น้อย หากผู้อ่านท่านใดมีข้อเสนอแนะหรือแนะนำวิธีเพิ่มเติมเกี่ยวกับเรื่องดังกล่าว ผู้เขียนยินดีเป็นอย่างยิ่งที่จะรับฟังและร่วมแบ่งปันความรู้ร่วมกันค่ะ หากบทความนี้มีส่วนผิดพลาดประการใด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วยค่ะ ^^

    แหล่งข้อมูลอ้างอิง :

    https://www.tutorialspoint.com/google_maps/google_maps_symbols.htm

    http://www.codexworld.com/autocomplete-places-search-box-google-maps-javascript-api/