برنامه هواشناسی: وارد کردن اطلاعات در UI و مدیریت Modal

Meteorological Program: Data entry in UI and Modal Management

20 مرداد 1399
برنامه ی هواشناسی: وارد کردن اطلاعات در UI و مدیریت Modal

تا این قسمت از کار توانسته ایم درخواست خود را به API ارسال کرده و پاسخ دریافتی را در کنسول مرورگر نمایش دهیم. برای انجام این کار ابتدا کد مربوط به log کردن نتیجه در کنسول مرورگر را کامنت می کنیم تا دیگر نتیجه در این قسمت نمایش داده نشود. به جای آن می خواهم از کلاس ui متدی به نام paint را صدا بزنم که کار وارد کردن داده ها در UI را انجام دهد اما هنوز نه کلاس UI داریم و نه متدی به نام paint بنابراین به فایل Ui.js بروید تا کار را شروع کنیم.

من درون این فایل، کلاسی به نام UI تعریف می کنم که درون constructor خود، خصوصیت های بسیار زیادی را تعریف می کند چرا که ما عناصر بسیار زیادی را در گزارش های آب و هوایی داریم:

class UI {
  constructor() {
    this.location = document.getElementById('w-location');
    this.desc = document.getElementById('w-desc');
    this.string = document.getElementById('w-string');
    this.details = document.getElementById('w-details');
    this.icon = document.getElementById('w-icon');
    this.humidity = document.getElementById('w-humidity');
    this.feelsLike = document.getElementById('w-feels-like');
    this.dewpoint= document.getElementById('w-dewpoint');
    this.wind = document.getElementById('w-wind');
  }
}

خصوصیات تعریف شده در کد بالا به ترتیب به شرح زیر هستند:

  • محل مورد گزارش (شهر)
  • توضیحات گزارش (خلاصه ای از وضعیت آب و هوایی)
  • دمای هوا
  • جزئیات گزارش
  • آیکون نمایش دهنده وضعیت هوا (تصویر ابر و باران و ...)
  • رطوبت هوا
  • درجه feelsLike (درجه ای که اکثر انسان ها حس می کنند نه درجه ای که واقعا هست. مثلا ممکن است هوا واقعا 10 درجه باشد اما شما و دوستانتان حس کنید 20 درجه است)
  • نقطه شبنم (دمایی است که هوا باید تا آن نقطه سرد شود تا با بخار آب اشباع شود. در دمای پایین‌تر از این دما، بخشی از آب موجود در هوا تقطیر خواهد شد تا دوباره به حالت تعادل برسد)
  • اطلاعات مربوط به باد

در مرحله بعد باید متدی در این کلاس تعریف کنیم که تمام این خصوصیات (که عناصر HTML هستند) را گرفته و اطلاعات مربوطه را در آن ها وارد کند. این متد، همان متد paint خواهد بود:

class UI {
  constructor() {
    this.location = document.getElementById('w-location');
    this.desc = document.getElementById('w-desc');
    this.string = document.getElementById('w-string');
    this.details = document.getElementById('w-details');
    this.icon = document.getElementById('w-icon');
    this.humidity = document.getElementById('w-humidity');
    this.feelsLike = document.getElementById('w-feels-like');
    this.dewpoint= document.getElementById('w-dewpoint');
    this.wind = document.getElementById('w-wind');
  }

  paint(weather) {
    this.location.textContent = weather.display_location.full;
    this.desc.textContent = weather.weather;
    this.string.textContent = weather.temperature_string;
    this.icon.setAttribute('src', weather.icon_url);
    this.humidity.textContent = `Relative Humidity: ${weather.relative_humidity}`;
    this.feelsLike.textContent = `Feels Like: ${weather.feelslike_string}`;
    this.dewpoint.textContent = `DewPoint: ${weather.dewpoint_string}`;
    this.wind.textContent = `Wind: ${weather.wind_string}`;
  }
}

شاید با خودتان بگویید که چطور می دانی محل مورد نظر (شهر) از شیء display_location.full به دست می آید. پاسخ این سوال همان چیزی است که قبلا گفته ام، ساختار هر API خاص است و شما باید پاسخ دریافتی از API را بررسی کرده تا بدانید هر اطلاعاتی در کدام قسمت از پاسخ قرار دارد. مثلا من این کار را در جلسه قبل انجام دادم (پاسخ دریافتی در کنسول مرورگر بود و به سادگی بررسی می شد). تنها نکته جالب در کد بالا نحوه تعیین icon است. برای تعیین منبع (src) یک تصویر باید از setAttribute (از متدهای خود جاوا اسکریپت) استفاده کنیم تا خصوصیت src را برایش تعریف کنیم. برای مقادیر انتهایی نیز یک یا دو کلمه توضیح قرار داده ام و سپس مقدار را نمایش داده ام تا کاربر بداند هر عدد مربوط به چه چیزی است.

حالا به app.js رفته و به صورت زیر از کلاس UI استفاده می کنیم:

// Init weather object
const weather = new Weather('Boston', 'MA');
// Init UI
const ui = new UI();

// Get weather on DOM load
document.addEventListener('DOMContentLoaded', getWeather);

function getWeather(){
  weather.getWeather()
    .then(results => {
      ui.paint(results);
    })
    .catch(err => console.log(err));
}

این کار عملیات پیچیده ای ندارد و فقط یک نمونه سازی و سپس استفاده از handle آن برای صدا زدن متد paint است.

مرحله بعد مدیریت modal است. از آنجایی که بوت استرپ از جی کوئری استفاده می کند ما برای بستن modal باید از جی کوئری استفاده کنیم. به فایل app.js بروید و event-listener زیر را به آن اضافه کنید:

// Get weather on DOM load
document.addEventListener('DOMContentLoaded', getWeather);

// Change location event
document.getElementById('w-change-btn').addEventListener('click', (e) => {
  const city = document.getElementById('city').value;
  const state = document.getElementById('state').value;

  // Change location
  weather.changeLocation(city, state);

  // Get and display weather
  getWeather();

  // Close modal
  $('#locModal').modal('hide');
});

دکمه ای که id اش برابر با w-change-btn است همان دکمه ذخیره شهر جدید در modal ما است (دکمه Save Changes). درون این event-listener مقادیر شهر و ایالت که توسط کاربر وارد می شوند را ذخیره کرده ایم تا با استفاده از متد Change Location محل را تغییر دهیم. سپس getWeather را صدا می زنیم تا اطلاعات محل جدید را از API بگیریم و سپس با یک دستور ساده جی کوئری modal را می بندیم. اگر دوست ندارید از جی کوئری استفاده کنید می توانید از جاوا اسکریپت ساده برای بستن modal استفاده نمایید. می توانید این کد را در مرورگر خود تست کنید.

در مرحله بعد وارد فایل Storage.js می شویم تا یک کلاس مخصوص local storage ایجاد کنیم. چرا؟ به دلیل اینکه اگر کاربر شهر مورد نظرش را از بوستون (حالت پیش فرض) به شهر دیگری تغییر داده و سپس صفحه را refresh کند، دوباره اطلاعات بوستون نمایش داده می شود. ما می خواهیم شهر کاربر را درون local storage ذخیره کنیم تا با refresh شدن صفحه شهر کاربر تغییر نکند:

class Storage {
  constructor() {
    this.city;
    this.state;
    this.defaultCity = 'Tampa';
    this.defaultState = 'FL';
  }

  getLocationData() {
    if(localStorage.getItem('city') === null) {
      this.city = this.defaultCity;
    } else {
      this.city = localStorage.getItem('city');
    }

    if(localStorage.getItem('state') === null) {
      this.state = this.defaultState;
    } else {
      this.state = localStorage.getItem('state');
    }

    return {
      city: this.city,
      state: this.state
    }
  }

  setLocationData(city, state) {
    localStorage.setItem('city', city);
    localStorage.setItem('state', state);
  }
}

از آنجایی که چندین بار در طول این دوره آموزشی با local storage کار کرده ایم فکر نمی کنم نیاز به توضیح دوباره آن باشد (اگر سوالی دارید می توانید در بخش کامنت ها مطرح کنید). منطق کد ها نیز بسیار ساده است. من شهر پیش فرض را Tampa در ایالت فلوریدا انتخاب کرده ام. متد getLocationData از روی local storage مقادیر را می خواند و اگر چیزی در آن نبود از شهر پیش فرض استفاده می کند. در صورتی که شهری نیز ذخیره شده بود همان شهر را بر می گرداند. توجه کنید که در نهایت یک شیء حاوی city و state برگردانده ایم. متد setLocationData نیز شهر و ایالت را در local storage ثبت می کند.

حالا به فایل app.js برمی گردیم و در همان ابتدا local storage را می خوانیم (با نمونه سازی از کلاس Storage):

// Init storage
const storage = new Storage();
// Get stored location data
const weatherLocation = storage.getLocationData();
// Init weather object
const weather = new Weather(weatherLocation.city, weatherLocation.state);
// Init UI
const ui = new UI();

همچنین همانطور که می بینید دیگر مقادیر را به صورت دستی (شهر بوستون) تنظیم نکرده ایم و همان مقدار موجود در local storage را به کلاس Weather پاس می دهیم. نهایتا باید هنگام کلیک روی دکمه save changes درون modal، شهر را نیز گرفته و در local storage ذخیره کنیم:

// Change location event
document.getElementById('w-change-btn').addEventListener('click', (e) => {
  const city = document.getElementById('city').value;
  const state = document.getElementById('state').value;

  // Change location
  weather.changeLocation(city, state);

  // Set location in LS
  storage.setLocationData(city, state);

  // Get and display weather
  getWeather();

  // Close modal
  $('#locModal').modal('hide');
});

به شما تبریک می گویم، پروژه خود را با موفقیت به اتمام رساندید. (دانلود سورس کد این پروژه)

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری پروژه‌های مدرن جاوا اسکریپت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.