Dalam aplikasi berbasis web server ESP8266, kita sering ingin menampilkan data dinamis pada halaman HTML. Salah satu komponen penting adalah select box (dropdown) yang dapat terisi otomatis dari data JSON.
Disini kita akan menampilkan 2 buah selectbox yang akan disi dengan data JSON. Selectbox pertama berisi nama-namapprovinsi dan selectbox kedua akan berisi nama-nama kabupaten berdasarkan nama provinsi yang dipilih.
Tampilan akhir akan menampilkan provisi, kabupaten, timezone, latitude dan longitude dari sebuah kabupaten yang dipilih
Alat dan Bahan
- ESP8266 (NodeMCU atau Wemos D1 Mini)
- Arduino IDE
- Koneksi WiFi lokal
- Browser (Chrome, Firefox, dll)
Tujuan Akhir
ESP8266 menyajikan halaman HTML yang memiliki selectbox berisi nama-nama provinsi dan kabupaten, dan data opsi-nya diambil secara dinamis dari server ESP melalui request JSON (AJAX). Tidak perlu refresh halaman!Struktur Folder Proyek
Dalam folder latlong terdapat sebuah file latlong.ino dan folder "data". Dalam folder "data" terdapat semua file JSON yang diperlukan.
Data JSON berisi nama-nama provinsi:
- isiselect.json
{
"provinsi": [
{
"name": "ACEH",
"file": "ACEH.json"
},
{
"name": "BALI",
"file": "BALI.json"
},
...
Data JSON berisi nama-nama kabupaten:- SUMATERA_UTARA.json
- SUMATERA_SELATAN.json
- SUMATERA_BARAT.json
- SULAWESI_UTARA.json
- SULAWESI_TENGGARA.json
- SULAWESI_TENGAH.json
- SULAWESI_SELATAN.json
- SULAWESI_BARAT.json
- RIAU.json
- PAPUA_BARAT.json
- PAPUA.json
- NUSA_TENGGARA_TIMUR.json
- NUSA_TENGGARA_BARAT.json
- MALUKU_UTARA.json
- MALUKU.json
- LAMPUNG.json
- KEPULAUAN_RIAU.json
- KEPULAUAN_BANGKA_BELITUNG.json
- KALIMANTAN_UTARA.json
- KALIMANTAN_TIMUR.json
- KALIMANTAN_TENGAH.json
- KALIMANTAN_SELATAN.json
- KALIMANTAN_BARAT.json
- JAWA_TIMUR.json
- JAWA_TENGAH.json
- JAWA_BARAT.json
- JAMBI.json
- GORONTALO.json
- DI_YOGYAKARTA.json
- BENGKULU.json
- BANTEN.json
- BALI.json
- ACEH.json
- DKI_JAKARTA.json
{ "kabupaten":
[
{
"kab": "KAB. KEPULAUAN SERIBU",
"lok": "7,-5.5985, 106.55271"
},
{
"kab": "KOTA JAKARTA BARAT",
"lok": "7,-6.1676, 106.7673"
},
.....
Kode ESP8266 (Web Server + JSON)
/*
* Sumber data JSON indonesia : https://github.com/yusufsyaifudin/wilayah-indonesia
*
*/
#include
#include
#include
#include "FS.h"
String isiselect = "";
// ==== WIFI ====
const char* ssid = "ACCESS POINT";
const char* password = "00000000";
IPAddress local_ip(192, 168, 4, 5);
IPAddress gateway(192, 168, 4, 1);
IPAddress netmask(255, 255, 255, 0);
ESP8266WebServer server(80);
void setup() {
Serial.begin(9600);
SPIFFS.begin();
load_config();
// ==============
// ==== WIFI ====
// ==============
WiFi.softAPdisconnect(true);
WiFi.disconnect();
delay(1000);
Serial.println("Wifi ACCESS POINT");
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip, gateway, netmask);
WiFi.softAP(ssid, password); //Connect to your WiFi router
Serial.println("");
server.on("/", []() {
server.send(200, "text/html", isiHTML());
});
server.on("/getkab", []() {
String provinsi_nama = server.arg("provinsi");
Serial.println(provinsi_nama);
File kabFile = SPIFFS.open("/" + provinsi_nama, "r");
// DynamicJsonDocument kabDoc(3072);
DynamicJsonDocument kabDoc(4096);
DeserializationError error = deserializeJson(kabDoc, kabFile);
if (error) {
server.send(500, "text/plain", "Kesalahan baca file kabupaten");
return;
}
String jsonResponse = "{\"kabupaten\":[";
JsonArray kabList = kabDoc["kabupaten"];
for (int i = 0; i < kabList.size(); i++) {
JsonObject kab = kabList[i];
jsonResponse += "{";
jsonResponse += "\"kab\":\"" + String(kab["kab"].as()) + "\",";
jsonResponse += "\"lok\":\"" + String(kab["lok"]) + "\"";
jsonResponse += "}";
if (i < kabList.size() - 1) jsonResponse += ",";
}
jsonResponse += "]}";
server.send(200, "application/json", jsonResponse);
});
// ================
// ==== SERVER ====
// ================
server.begin();
Serial.println("HTTP server started");
}
void loop() {
// put your main code here, to run repeatedly:
server.handleClient();
}
void load_config() {
File configFilejson = SPIFFS.open("/isiselect.json", "r");
if (!configFilejson) {
Serial.println("Failed to open config file");
Serial.println("Sistem restart...");
ESP.restart();
}
size_t size = configFilejson.size();
std::unique_ptr buf(new char[size]);
configFilejson.readBytes(buf.get(), size);
// DynamicJsonDocument doc(192);
// StaticJsonDocument<2048> doc;
DynamicJsonDocument doc(3072);
DeserializationError error = deserializeJson(doc, buf.get());
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject provinsi_item : doc["provinsi"].as()) {
const char* provinsi_item_nama = provinsi_item["name"];
const char* provinsi_item_file = provinsi_item["file"];
isiselect = isiselect + "";
}
}
String isiHTML() {
String HTML = "<!DOCTYPE HTML><html>";
HTML += "<head>\n";
HTML += "<meta name='viewport' content='width=device-width, initial-scale=1'>\n";
HTML += "<title>Pilih Provinsi & Kabupaten</title>\n";
HTML += "<style>\n";
HTML += "html { font-family: Helvetica; display: inline-block; margin: 0px auto; }\n";
HTML += "input[type=text], select {\n";
HTML += " padding: 8px 20px;\n";
HTML += " margin: 8px 0;\n";
HTML += " display: inline-block;\n";
HTML += " border: 1px solid #ccc;\n";
HTML += " border-radius: 4px;\n";
HTML += " box-sizing: border-box;\n";
HTML += " font-size: 20px; \n";
HTML += "}\n";
HTML += "</style>\n";
HTML += "<script>\n";
HTML += "let latitude = \"\";\n";
HTML += "let longitude = \"\";\n";
HTML += "let timezone = \"\";\n";
HTML += "function loadKabupaten() {\n";
HTML += " var provinsiSelect = document.getElementById('select_provinsi');\n";
HTML += " var selectedProvinsi = provinsiSelect.value;\n";
HTML += " var kabupatenSelect = document.getElementById('select_kabupaten');\n";
HTML += " var p_ket = document.getElementById('p_ket');\n";
HTML += " kabupatenSelect.innerHTML = '';\n";
HTML += " if (selectedProvinsi) {\n";
HTML += " fetch('/getkab?provinsi=' + encodeURIComponent(selectedProvinsi))\n";
HTML += " .then(response => response.json())\n";
HTML += " .then(data => {\n";
HTML += " data.kabupaten.forEach(kab => {\n";
HTML += " let opt = document.createElement('option');\n";
HTML += " opt.value = JSON.stringify(kab);\n";
HTML += " opt.text = kab.kab;\n";
HTML += " kabupatenSelect.add(opt);\n";
HTML += " });\n";
HTML += " p_ket.innerHTML = 'Anda memilih Provinsi: <b>' + formatProvinsi(selectedProvinsi) + '</b>';\n";
HTML += " });\n";
HTML += " } else {\n";
HTML += " p_ket.textContent = 'Silakan pilih provinsi.';\n";
HTML += " }\n";
HTML += "}\n";
HTML += "function valKabupaten() {\n";
HTML += " var kabSelect = document.getElementById('select_kabupaten');\n";
HTML += " var selectedKab = JSON.parse(kabSelect.value);\n";
HTML += " splitLatLng(selectedKab.lok);\n";
HTML += " document.getElementById('p_ket_kab').innerHTML =\n";
HTML += " 'Anda memilih Kabupaten: <b>' + selectedKab.kab + '</b><br>' + \n";
HTML += " 'Timezone : <b>' + timezone + '</b>, Latitude : <b>' + latitude + '</b>, Longitude : <b>' + longitude + '</b>';\n";
HTML += "}\n";
HTML += "function formatProvinsi(filename) {\n";
HTML += " let nama = filename.replace(\".json\", \"\");\n";
HTML += " return nama.replace(/_/g, \" \");\n";
HTML += "}\n";
HTML += "function splitLatLng(input) {\n";
HTML += " const parts = input.split(',');\n";
HTML += " timezone = parts[0].trim();\n";
HTML += " latitude = parts[1].trim();\n";
HTML += " longitude = parts[2].trim();\n";
HTML += "}\n";
HTML += "</script>\n";
HTML += "</head>\n";
HTML += "<body>\n";
HTML += "<h2>Pilih Provinsi dan Kabupaten</h2>\n";
HTML += "<label for=\"select_provinsi\">Pilih Provinsi:</label><br>\n";
HTML += "<select id=\"select_provinsi\" onclick=\"loadKabupaten()\">\n";
HTML += isiselect;
HTML += "</select><br><br>\n";
HTML += "<label for=\"select_kabupaten\">Pilih Kabupaten:</label><br>\n";
HTML += "<select id=\"select_kabupaten\" onclick=\"valKabupaten()\"></select><br><br>\n";
HTML += "<p id=\"p_ket\"></p>\n";
HTML += "<p id=\"p_ket_kab\"></p>\n";
HTML += "</body>\n";
HTML += "</html>\n";
return HTML;
}
2048>
Penjelasan Kode
- server.on("/") menyajikan halaman HTML dengan Selectbox pertama berisi nama-nama provinsi
- server.on("/getkab") menyajikan data JSON berupa daftar nama-nama kabupaten
Uji Coba
- Upload kode ke ESP8266
- Jalankan ESP8266
- Buka browser ke IP ESP8266 (misal 192.168.4.5)
- Lihat dropdown selectbox pertama kan terisi nama-nama provinsi dan dengan memilih provinsi akan mengisi selectbox kedua dengan nama-nama kabupaten.
- Dengan memilih nama kabupaten akan otomatis menampilkan timezone, latitude dan longitude.
Download Project di Github.
Selamat mencoba...!
EmoticonEmoticon
Note: Only a member of this blog may post a comment.