Đáp án bài tập Javascript cơ bản Ajax – Hiển thị công việc

Đây là đáp án của Bài tập 2: Thiết kế một trang tìm kiếm việc làm.

Giao diện gồm trang chủ có tìm kiếm và phần hiển thị các công việc (index.html) tương ứng, với mỗi công việc khi đi vào chi tiết sẽ thấy các kĩ năng (skill.html) tương ứng, ứng với mỗi kĩ năng thì có nhiều công việc phù hợp (job.html).

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="index.js"> </script>
    <style> 
    a{
        text-decoration: none
    }    
    </style>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
    <div class="spinner-border text-dark" role="status">
        <span class="sr-only">Loading...</span>
      </div>
    <!-- <form> -->
        <table>
            <tr>
                <td>
                Tìm kiếm: <input id="jobTitle" type="text" name="jobTitle" placeholder="nhập vào để tìm kiếm"><br>
                        <button id="searchButton">Search</button>
            </td>
            </tr>
        </table>
     <!-- </form> -->
    <h1></h1>
    <table id= "jobs" ></table>
</body>
</html>
var params = new URLSearchParams(window.location.search);
console.log(params.get("jobTitle"));
var jobTitle = params.get("jobTitle");

console.log(window.location.search);
$(document).ready(function() {
    // if (jobTitle) {
    //     showData(
    //         `http://api.dataatwork.org/v1/jobs/autocomplete?contains=${jobTitle}`
    //     );
    // } else {
    //     showData("http://api.dataatwork.org/v1/jobs");
    // }
    showData("http://api.dataatwork.org/v1/jobs");
    $("#searchButton").click(function() {
        var title = $("#jobTitle").val();
        if (title) {
            showData(
                `http://api.dataatwork.org/v1/jobs/autocomplete?contains=${title}`
            );
        } else {
            showData("http://api.dataatwork.org/v1/jobs");
        }
    });
});

function showData(url) {
    $(".spinner-border").show();
    $.getJSON(url, function(jobs) {
        let vieclam = "";
        vieclam += `<tr>
    <td class="text-dark">Title </td>
    <td class="text-dark">UUID</td>
    </tr>`;
        jobs.forEach(job => {
            const { title, uuid, normalized_job_title } = job;
            if (title) {
                // console.log("title :", title);
                vieclam += `<tr><td><a href="job.html?id=${uuid}">${title}</a></td><td class="text-danger">${uuid}</td></tr>`;
            } else {
                vieclam += `<tr><td><a href="job.html?id=${uuid}">${normalized_job_title}</a></td><td class="text-danger">${uuid}</td></tr>`;
            }
        });
        $("#jobs").html(vieclam);
        $("h1").html(`Có ${jobs.length} công việc `);
    }).done(function() {
        console.log("second success");
        $(".spinner-border").hide();
    });
}

skill.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="skill.js"> </script>
    <title>Skill</title>
</head>
<body>
        <h1></h1>
        <table id="jobs" ></table>
</body>

</html>
var params = new URLSearchParams(window.location.search);
$(document).ready(function() {
    $.getJSON(
        `http://api.dataatwork.org/v1/skills/${params.get("id")}/related_jobs`,
        function(data) {
            let jobTr = "";
            data.jobs.forEach(job => {
                const { job_uuid, job_title } = job;
                jobTr += `<tr><td><a href="job.html?id=${job_uuid}">${job_title}</a></td><td>${job_title}</td></tr>`;
            });
            $("#jobs").html(jobTr);
            $("h1").html(`Có ${data.jobs.length} job`);
        }
    );
});

job.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="job.js"> </script>
    <title>Job</title>
</head>
<body>
        <h1></h1>
        <table id="skills" ></table>
</body>

</html>
var params = new URLSearchParams(window.location.search);
$(document).ready(function() {
    $.getJSON(
        `http://api.dataatwork.org/v1/jobs/${params.get("id")}/related_skills`,
        function(data) {
            let skillTr = "";
            data.skills.forEach(skill => {
                const {
                    skill_uuid,
                    skill_name,
                    skill_type,
                    description
                } = skill;
                skillTr += `<tr><td><a href="skill.html?id=${skill_uuid}">${skill_name}</a></td><td>${description}</td></tr>`;
            });
            $("#skills").html(skillTr);
            $("h1").html(`Có ${data.skills.length} skill`);
        }
    );
});

Bài tập Javascript cơ bản: Ajax – phần 2

Lần trước chúng ta đã đi vào phần 1 cơ bản nhất để viết ajax bằng jQuery
Lần này chúng ta sẽ kết hợp giữa việc lấy data bằng ajax cùng với việc thiết kế giao diện.
API data mà chúng ta sẽ lấy dữ liệu là API về thông tin xoay quanh pokemon: https://pokeapi.co/docs/v2.html/.
Giao diện sẽ thiết kế theo trang sau: https://www.pokemon.com/us/pokedex/

thiết kế pokedex, pokemon

Một số API cần thiết để lấy data

1. API dùng để hiển thị danh sách các Pokemon.

Ví dụ lấy 12 pokemons sẽ dùng API sau: https://pokeapi.co/api/v2/pokemon?limit=12.
Dữ liệu trả về như sau

{
  "count": 964,
  "next": "https://pokeapi.co/api/v2/pokemon?offset=12&limit=12",
  "previous": null,
  "results": [
    { "name": "bulbasaur", "url": "https://pokeapi.co/api/v2/pokemon/1/" },
    { "name": "ivysaur", "url": "https://pokeapi.co/api/v2/pokemon/2/" },
    { "name": "venusaur", "url": "https://pokeapi.co/api/v2/pokemon/3/" },
    { "name": "charmander", "url": "https://pokeapi.co/api/v2/pokemon/4/" },
    { "name": "charmeleon", "url": "https://pokeapi.co/api/v2/pokemon/5/" },
    { "name": "charizard", "url": "https://pokeapi.co/api/v2/pokemon/6/" },
    { "name": "squirtle", "url": "https://pokeapi.co/api/v2/pokemon/7/" },
    { "name": "wartortle", "url": "https://pokeapi.co/api/v2/pokemon/8/" },
    { "name": "blastoise", "url": "https://pokeapi.co/api/v2/pokemon/9/" },
    { "name": "caterpie", "url": "https://pokeapi.co/api/v2/pokemon/10/" },
    { "name": "metapod", "url": "https://pokeapi.co/api/v2/pokemon/11/" },
    { "name": "butterfree", "url": "https://pokeapi.co/api/v2/pokemon/12/" }
  ]
}
  • Từ json của từng pokemon, ta lấy ra id của pokemon ở cuối url.
    Vd, với json sau, pokemon bulbasaur có id là 1.
{ "name": "bulbasaur", "url": "https://pokeapi.co/api/v2/pokemon/1/" }
  • Url ảnh của 1 pokemon dựa trên id tương ứng, ví dụ với id = 1 url ảnh của pokemon sẽ là:
    https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png

2. API dùng để lấy thông tin chi tiết của 1 Pokemon.

Ví dụ API thông tin của pokemon có id=12 sẽ là: https://pokeapi.co/api/v2/pokemon/12/ , dữ liệu trả về chi tiết được mô tả ở địa chỉ https://pokeapi.co/docs/v2.html/#pokemon,

Hiển thị thông tin chi tiết của pokemon theo một trong các trang sau, ví dụ hiển thị chi tiết của pokemon bulbasaur có id=1

Xem đáp án tại đây

Javascript cơ bản: jQuery selectors

Khi dùng thư viện jQuery để tương tác với DOM của HTML thì quan trọng nhất là làm sao lấy được DOM.
Các hàm để lấy element của html bao gồm các hàm sau của document

document.getElementById()
document.getElementsByClassName()
document.getElementsByName()
document.getElementsByTagName()
document.querySelector()
document.querySelectorAll()

Bằng jQuery selectors, chúng ta có thể lấy element như các hàm querySelector hay querySelectorAll.

jQuery theo Id của element (trả về object)
jQuery theo tên element (trả về mảng object)

Một số link tham khảo:

HTML CSS cơ bản

Một số tutorial về HTML và CSS cơ bản nhất cần nắm bắt khi thiết kế giao diện website.
Cấu trúc layout (giao diện) web cơ bản gồm có các phần như header, footer, content và sidebar

HTML


Cấu trúc element trong HTML

CSS

Cấu trúc style CSS

Tiếng Việt

Đáp án bài tập Javascript cơ bản Ajax – Thời tiết của thành phố

Đáp án của Bài tập Javascript cơ bản: JSON Ajax.
Trong phần này chủ yếu là lấy dữ liệu từ API server, dùng hàm jQuery.getJSON để khỏi phải mất công parse sang object khi lấy dữ liệu từ server so với hàm jQuery.get, còn nếu không bạn hãy dùng jQuery.ajax rồi thêm rong request gửi đi: dataType: "json"

Bài tập 1

Hiển thị thông tin thời tiết của một thành phố (London)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="baitap-json-column.js"> </script>
    <style>
        table, th, td {
            border: 1px solid black;
            border-collapse: collapse;
        }
        th, td {
            padding: 15px;
        }
    </style>
</head>
<body>
    <div id="table" ></div>
</body>
</html>
$.getJSON(
    "https://raw.githubusercontent.com/hitanan/html5-Audio-Player/master/weather.json",
    function(data) {
        let weather = data.consolidated_weather;
        let table = "<table>";
        let headerTd = "";
        let maxTd = "";
        let minTd = "";
        let img = "";
        for (var i = 0; i < weather.length; i++) {
            console.log(weather[i]);
            headerTd += `<td>${weather[i].applicable_date}</td>`;
            maxTd += `<td>${weather[i].max_temp.toFixed(2)}</td>`;
            minTd += `<td>${weather[i].min_temp.toFixed(2)}</td>`;
            img += `<td>
            <img src="https://www.metaweather.com/static/img/weather/ico/${
                weather[i].weather_state_abbr
            }.ico">
           
            <div>${weather[i].weather_state_name}</div>
          </td>`;
        }
        table += `<tr>
        <td>Thoi Gian</td>
        ${headerTd}
        </tr>`;

        table += `<tr>
        <td>Thoi Tiet</td>
        ${img}
        </tr>`;
        table += `<tr>
        <td>Nhiet Do Cao Nhat</td>
        ${maxTd}
        </tr>`;
        table += `<tr>
        <td>Nhiet Do Thap Nhat</td>
        ${minTd}
        </tr>`;

        table += `</table>`;

        $("#table").html(table);
    }
);
$.getJSON(
    "https://raw.githubusercontent.com/hitanan/html5-Audio-Player/master/weather.json",
    function(data) {
        let weather = data.consolidated_weather;
        let table = "<table>";
        let day = "";
        table += `<tr>
        <td>Thoi Gian</td>
        <td>Thoi Tiet</td>
        <td>Nhiet Do Cao Nhat</td>
        <td>Nhiet Do Thap Nhat</td>
        </tr>`;
        for (var i = 0; i < weather.length; i++) {
            day = "";
            console.log(weather[i]);
            day += `<td>${weather[i].applicable_date}</td>`;
            day += `<td>${weather[i].max_temp.toFixed(2)}</td>`;
            day += `<td>${weather[i].min_temp.toFixed(2)}</td>`;
            day += `<td>
            <img src="https://www.metaweather.com/static/img/weather/ico/${
                weather[i].weather_state_abbr
            }.ico">
           
            <div>${weather[i].weather_state_name}</div>
          </td>`;
            table += `<tr>${day}</tr>`;
        }
        table += `</table>`;

        $("#table").html(table);
    }
);

Bài tập Javascript cơ bản: JSON Ajax

Trong tài tập này chúng ta sẽ lấy dữ liệu từ server API thông qua ajax bằng thư viện jQuery, sau đó hiển thị dữ liệu của thành phố lên HTML.

Bài tập 1 : Hiển thị thông tin thời tiết của thành phố

Hiển thị thông tin thời tiết của thành phố London. Phần hình ảnh của thời tiết ( Snow,sunny,..) được hiển thị tương ứng với dữ liệu “weather state abbreviation” trả về trong json, Url để sử dụng trong html tag hiển thị hình ảnh <img> như sau:

`https://www.metaweather.com/static/img/weather/${weather_state_abbr}.svg`

Ví dụ, trong dữ liệu trả về và url hình ảnh tương ứng như sau:

var json = { "weather_state_name":"Heavy Cloud","weather_state_abbr":"hc"}
// => url  hình ảnh: https://www.metaweather.com/static/img/weather/hc.svg

1. JSON API thông tin thành phố và 5 day forecast (London):
https://www.metaweather.com/api/location/44418/
2. JSON API cho hiển thị thời tiết 1 ngày của một thành phố (London hôm nay 27/5/2019):
https://www.metaweather.com/api/location/44418/2019/5/27/

Một ví dụ của hiển thị nội dung html như sau:

Ví dụ hiển thị dữ liệu 8 ngày tới

Linh tham khảo của API và tài liệu về các element table, image trong html

Bài tập 2: Thiết kế một trang tìm kiếm việc làm

Bài tập 3


Một số bài tập khác: Thiết kế một trang tìm kiếm việc làm giao diện như trang web sau:
https://jobs.github.com/positions?description=python&location=new+york
Api document chi tiết tại đây:
https://jobs.github.com/api
Trang web chi tiết các bài viết, các bài comment,… của user
https://jsonplaceholder.typicode.com/

Javascript cơ bản: callback

Callback là thuật ngữ dùng để chỉ phương pháp truyền 1 function lúc gọi hàm.
Chúng ta sẽ đi làm bài tập A giao công việc xử lý văn phòng cho B, C, D.

Mã html file index.htmlbaitap-callback.js như sau

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    <script src="baitap-callback.js"></script>
    <!-- <link ref="stylesheet" href="style.css" /> -->

    <style>
      #startWord {
        color: red;
      }
      .startExcelClass {
        color: blue;
      }
    </style>
    <title>Javascript cơ bản</title>
  </head>
  <body>
    <div id="startWord">Start Word</div>
    <div class="startExcelClass">Start Excel</div>
    <div class="startExcelClass">Start Excel 2</div>

    <div id="startPowerPoint">Start Powerpoint</div>
  </body>
</html>
// - A send request to B
// - A continue to do sth
// - whenerver has a result for A, B callback to A.
// - A get the callback result

function metA(office, callback) {
  console.log(`A send request to  ${callback.name.replace("met", "")}`);
  callback(office);
  // console.log(`A continue to do with ${result} result`);
}

metB = office => {
  console.log(`B get ${office} request from A`);
  setTimeout(() => {
    console.log(`B delivery ${office} result to A`);
  }, 10000);

  return "B";
};
metC = office => {
  console.log(`C get ${office} request from A`);
  setTimeout(() => {
    console.log(`C delivery ${office} result to A`);
  }, 5000);

  return "C";
};
metD = office => {
  console.log(`D get ${office} request from A`);
  setTimeout(() => {
    console.log(`D delivery ${office} result to A`);
  }, 20000);

  return "D";
};

// metA("word", metB);
// metA("excel", metC);
// metA("powerpoint", metD);

// khi page load DOM body
document.addEventListener("DOMContentLoaded", function() {
  //gan su kien click
  var button = document.querySelector("#startWord");
  button.addEventListener("click", function() {
    metA("word", metB);
  });
  button = document.querySelector(".startExcelClass");
  button.addEventListener("click", function() {
    metA("excel", metC);
  });
});

// A $( document ).ready() block.
$(document).ready(function() {
  $("#startPowerPoint").click(function() {
    metA("powerpoint", metD);
  });
});

Call back in http request

Javascript cơ bản: JSON

Ứng dụng Javascript gửi request tương tác với API server, thì dữ liệu được đóng gói và format theo chuẩn để Client và Server có thể hiểu nhau. XML và JSON là các định dạng phổ biến được dùng cho việc này.

Tương tác giữa Client và Server thông qua JSON


JSON là viết tắt của json, định dạng hoàn toàn tương tự với khai báo object trong Javascript.

[
    {"city": "Paris", "unit":"C"}
]

Client gửi một GET và POST request đến server bằng Javascript và nhận response như sau:

var request = new XMLHttpRequest();
request.open('GET', '/service/weather', true);

request.onload = function () {
    // begin accessing JSON data here
    var data = JSON.parse(this.response);
 
    for (var i = 0; i < data.length; i++) {
        console.log('Temperature:' + data[i].low + ' - ' + data[i].high);
    }
}
 
request.send();

Viết bằng jQuery

$.ajax({
  url: "/service/weather",
  method: "GET",
  success: function(data) {
    for (var i = 0; i < data.length; i++) {
      console.log("Temperature:" + data[i].low + " - " + data[i].high);
    }
  }
});
$.get("/service/weather", function(data) {
  for (var i = 0; i < data.length; i++) {
    console.log("Temperature:" + data[i].low + " - " + data[i].high);
  }
});

Ví dụ Server trả về response theo JSON format

[{"low": "16", "high": "32"}]
// Ví dụ request theo phương thức POST
var request = new XMLHttpRequest();
var data = [{"city": "Paris", "unit":"C"}];
request.open('POST', '/service/weather', true);
 
request.onload = function () {
    // begin accessing JSON data here
    var data = JSON.parse(this.response);
 
    for (var i = 0; i < data.length; i++) {
        console.log('Temperature:' + data[i].low + ' - ' + data[i].high);
    }
}
 
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.send(data);

Một số trang web về JSON và free API no Auth cho người mới học

Javascript cơ bản: kiểu dữ liệu Map, Set

Trong JavaScript, Map là một loại object cho phép lưu trữ dữ liệu theo kiểu key-value, giống với object, tuy nhiên key trong map không chỉ là kiểu string mà key có thể là object

Kiến thức chung về Javascript

Bài tập Javascript cơ bản: Class

Bài tập 1

Giả sử có class 1 điểm (point) trong tọa độ,
Viết hàm “khoangCach” có đầu vào là 2 điểm, hàm trả về khoảng cách giữa hai điểm đó. khai báo hai điểm có tọa độ bất kỳ.

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

function khoangCach(p1, p2) {
  return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
}
let A = new Point(2, 4);
console.log("Tung độ A =", A.x);
console.log("Hoành độ A =", A.y);
let B = new Point(3, 2);
console.log("Tung độ B =", B.x);
console.log("Hoành độ B =", B.y);

let kc = khoangCach(A, B);
console.log("khoang cach:", kc);

Bài tập 2

Một của hàng bán trái cây (Fruit) quản lý sản phẩm theo id (mã sản phẩm), tên giá (theo kg), Thông tin trong kho như sau:

class Fruit {
  constructor(id, ten, gia) {
    this.id = id;
    this.ten = ten;
    this.gia = gia;
  }
}

var kho = [
  new Fruit(0, "Táo", 20000),
  new Fruit(1, "Mận", 10000),
  new Fruit(2, "Vải", 30000),
  new Fruit(3, "Ổi", 10000),
  new Fruit(3, "Ổi", 5000),
  new Fruit(4, "Nho", 720000),
  new Fruit(5, "Dâu", 20000),
  new Fruit(6, "Đu đủ", 40000),
  new Fruit(7, "Xoài", 30000),
  new Fruit(8, "Dừa", 30000)
];
var khoAZ = kho.sort(function(a, b) {
  if (a.ten < b.ten) {
    return -1;
  } else if (a.ten == b.ten) {
    return 0;
  } else {
    return 1;
  }
});

console.log(khoAZ);

var khoReMac = kho.sort((a, b) => {
  return a.gia - b.gia;
});
console.log(khoReMac);

var khoReMacAZ = kho.sort(function(a, b) {
  if (a.ten === b.ten) {
    return a.gia - b.gia;
  }
  return a.ten > b.ten ? 1 : -1;
});
console.log(khoReMacAZ);

let FR = ReNhat(kho);
function ReNhat(A) {
  let min = A[0];
  let max = A[0];
  for (let i = 1; i < A.length; i++) {
    if (A[i].gia > max.gia) {
      max = A[i];
    }
    if (A[i].gia < min.gia) {
      min = A[i];
    }
  }
  console.log("Đắt nhất: ", max.ten + max.gia);
  console.log("Rẻ nhất: ", min.ten + min.gia);
}
  • Viết chương trình in ra thông tin 2 loại trái cây rẻ nhất và mắc nhất trong kho
  • In ra danh sách trái cây kèm theo giá theo thứ tự từ A – Z trong kho
  • In ra danh sách trái cây kèm theo giá theo thứ tự rẻ đến mắc trong kho

Bài tập 3 (tiếp bài tập 2)

một order từ khách hàng khi mua trái cây bao gồm danh sách các cặp id (mã sản phẩm) và số kg .
Ví dụ: let order = {0:1, 1: 0.5} => mua “Táo” 1 kg, “Mận” 0.5 kg
hãy tính giá của order dưới dây là bao nhiêu ?

var order = {
  0: 1,
  1: 0.5,
  3: 1,
  4: 2,
  6: 0.5,
  7: 3
};

let sum = 0;
for (const id in order) {
  const element = order[id];
  // console.log(element);
  let sanPham = kho.find(function(a) {
    return a.id == id;
  });
  let gia = element * sanPham.gia;
  sum += gia;
  console.log(`${sanPham.ten} kg: ${element} tien: ${gia}`);
}
console.log("Tong don hang", sum);

Bài tập này có thể dùng vòng lặp for .. in để duyệt từng key của đối tượng “order”, Tham khảo ở link sau