MATIN MOLKARA
SERIES: JavaScript — PART 97 OF 108

97- آموزش جاوااسکریپت | پروژه عملی: قسمت 10 از 12- پیاده‌سازی Back، Delete و Clear All در اپلیکیشن مدیریت کالری

در این بخش، عملکرد دکمه Back برای خروج از حالت ویرایش، حذف یک آیتم از داده و رابط کاربری، و پاک‌کردن همه آیتم‌ها همراه با به‌روزرسانی مجموع کالری‌ها پیاده‌سازی می‌شود.

در این بخش، سه قابلیت مهم به اپلیکیشن مدیریت کالری اضافه می‌شود:

  • دکمه Back برای خروج از حالت ویرایش
  • دکمه Delete برای حذف آیتم انتخاب‌شده
  • دکمه Clear All برای حذف همه آیتم‌ها

هدف این است که علاوه بر حذف داده‌ها از ساختار اصلی برنامه، رابط کاربری نیز هم‌زمان به‌روزرسانی شود و مجموع کالری‌ها مقدار درست را نشان دهد.


پیاده‌سازی دکمه Back

برای دکمه Back نیاز به منطق پیچیده‌ای نداریم. چون از قبل در UIController متدی به نام clearEditState داریم، کافی است با کلیک روی این دکمه همان متد را اجرا کنیم.

ثبت رویداد دکمه Back

document
  .querySelector(UISelectors.backBtn)
  .addEventListener('click', UIController.clearEditState);

نتیجه

با کلیک روی دکمه Back:

  • فیلدهای فرم پاک می‌شوند
  • دکمه‌های مربوط به ویرایش مخفی می‌شوند
  • دکمه Add دوباره نمایش داده می‌شود

پیاده‌سازی حذف یک آیتم

در مرحله بعد، قابلیت حذف آیتم انتخاب‌شده را اضافه می‌کنیم. این حذف باید در سه بخش انجام شود:

  • حذف از ساختار داده
  • حذف از رابط کاربری
  • به‌روزرسانی مجموع کالری‌ها

ثبت رویداد دکمه Delete

ابتدا باید برای دکمه حذف، یک event listener ثبت کنیم.

document
  .querySelector(UISelectors.deleteBtn)
  .addEventListener('click', itemDeleteSubmit);

ساخت تابع itemDeleteSubmit

این تابع عملیات اصلی حذف را انجام می‌دهد. ابتدا آیتم جاری دریافت می‌شود، سپس از ساختار داده حذف می‌شود، بعد از رابط کاربری پاک می‌شود و در نهایت مجموع کالری‌ها و وضعیت فرم به‌روزرسانی می‌شوند.

const itemDeleteSubmit = function (e) {
  e.preventDefault();

  const currentItem = ItemController.getCurrentItem();

  ItemController.deleteItem(currentItem.id);
  UIController.deleteListItem(currentItem.id);

  const totalCalories = ItemController.getTotalCalories();
  UIController.showTotalCalories(totalCalories);

  UIController.clearEditState();
};

حذف آیتم از ساختار داده

برای حذف آیتم از آرایه items، ابتدا لیست شناسه‌ها را با map می‌گیریم، سپس اندیس آیتم موردنظر را پیدا کرده و با splice آن را حذف می‌کنیم.

متد deleteItem در ItemController

deleteItem: function (id) {
  const ids = data.items.map(function (item) {
    return item.id;
  });

  const index = ids.indexOf(id);

  if (index !== -1) {
    data.items.splice(index, 1);
  }
}

توضیح

در این روش:

  • با map فقط شناسه‌ها استخراج می‌شوند
  • با indexOf محل آیتم مشخص می‌شود
  • با splice همان آیتم از آرایه حذف می‌شود

حذف آیتم از رابط کاربری

بعد از حذف آیتم از داده‌ها، باید همان آیتم از لیست HTML نیز حذف شود.

متد deleteListItem در UIController

deleteListItem: function (id) {
  const itemID = `#item-${id}`;
  const item = document.querySelector(itemID);

  if (item) {
    item.remove();
  }
}

توضیح

در این متد:

  • شناسه DOM آیتم با الگوی item-{id} ساخته می‌شود
  • عنصر موردنظر از صفحه انتخاب می‌شود
  • در صورت وجود، از DOM حذف می‌شود

به‌روزرسانی مجموع کالری‌ها بعد از حذف

بعد از حذف یک آیتم، مقدار مجموع کالری‌ها باید دوباره محاسبه و در رابط کاربری نمایش داده شود.

const totalCalories = ItemController.getTotalCalories();
UIController.showTotalCalories(totalCalories);

خروج از حالت ویرایش بعد از حذف

پس از حذف آیتم، بهتر است فرم از حالت ویرایش خارج شود تا کاربر دوباره بتواند آیتم جدید اضافه کند.

UIController.clearEditState();

پیاده‌سازی دکمه Clear All

در این بخش می‌خواهیم با کلیک روی دکمه Clear All، همه آیتم‌ها از داده‌ها و رابط کاربری حذف شوند.


افزودن selector دکمه Clear All

ابتدا باید selector مربوط به این دکمه را در UISelectors اضافه کنیم.

const UISelectors = {
  itemList: '#item-list',
  listItems: '#item-list li',
  addBtn: '.add-btn',
  updateBtn: '.update-btn',
  deleteBtn: '.delete-btn',
  backBtn: '.back-btn',
  clearBtn: '.clear-btn',
  itemNameInput: '#item-name',
  itemCaloriesInput: '#item-calories',
  totalCalories: '.total-calories'
};

ثبت رویداد دکمه Clear All

حالا event listener مربوط به پاک‌کردن همه آیتم‌ها را ثبت می‌کنیم.

document
  .querySelector(UISelectors.clearBtn)
  .addEventListener('click', clearAllItemsClick);

ساخت تابع clearAllItemsClick

این تابع همه آیتم‌ها را از داده‌ها حذف می‌کند، آیتم‌های موجود در رابط کاربری را پاک می‌کند، مجموع کالری‌ها را به‌روزرسانی می‌کند و در صورت نیاز لیست را مخفی می‌سازد.

const clearAllItemsClick = function () {
  ItemController.clearAllItems();
  UIController.removeItems();

  const totalCalories = ItemController.getTotalCalories();
  UIController.showTotalCalories(totalCalories);

  UIController.hideList();
};

حذف همه آیتم‌ها از ساختار داده

در ItemController، حذف همه آیتم‌ها بسیار ساده است. کافی است آرایه items را خالی کنیم.

clearAllItems: function () {
  data.items = [];
}

حذف همه آیتم‌ها از رابط کاربری

در UIController، ابتدا همه آیتم‌های لیست گرفته می‌شوند، سپس NodeList به آرایه تبدیل می‌شود و در نهایت هر آیتم از DOM حذف می‌گردد.

removeItems: function () {
  let listItems = document.querySelectorAll(UISelectors.listItems);

  listItems = Array.from(listItems);

  listItems.forEach(function (item) {
    item.remove();
  });
}

مخفی‌کردن لیست بعد از پاک‌سازی کامل

اگر همه آیتم‌ها حذف شوند، بهتر است خود لیست نیز مخفی شود تا خط یا فضای خالی در صفحه باقی نماند.

UIController.hideList();

نمونه‌ای از متد hideList:

hideList: function () {
  document.querySelector(UISelectors.itemList).style.display = 'none';
}

نسخه نهایی رویدادها در App Controller

در نهایت، بخش event listenerها به شکل زیر کامل‌تر می‌شود:

const loadEventListeners = function () {
  document
    .querySelector(UISelectors.backBtn)
    .addEventListener('click', UIController.clearEditState);

  document
    .querySelector(UISelectors.deleteBtn)
    .addEventListener('click', itemDeleteSubmit);

  document
    .querySelector(UISelectors.clearBtn)
    .addEventListener('click', clearAllItemsClick);
};

نسخه نهایی توابع این بخش

const itemDeleteSubmit = function (e) {
  e.preventDefault();

  const currentItem = ItemController.getCurrentItem();

  ItemController.deleteItem(currentItem.id);
  UIController.deleteListItem(currentItem.id);

  const totalCalories = ItemController.getTotalCalories();
  UIController.showTotalCalories(totalCalories);

  UIController.clearEditState();
};

const clearAllItemsClick = function () {
  ItemController.clearAllItems();
  UIController.removeItems();

  const totalCalories = ItemController.getTotalCalories();
  UIController.showTotalCalories(totalCalories);

  UIController.hideList();
};

کد نهایی این بخش

const ItemController = (function () {
  const data = {
    items: [],
    currentItem: null,
    totalCalories: 0
  };

  return {
    getCurrentItem: function () {
      return data.currentItem;
    },

    deleteItem: function (id) {
      const ids = data.items.map(function (item) {
        return item.id;
      });

      const index = ids.indexOf(id);

      if (index !== -1) {
        data.items.splice(index, 1);
      }
    },

    clearAllItems: function () {
      data.items = [];
    },

    getTotalCalories: function () {
      let total = 0;

      data.items.forEach(function (item) {
        total += item.calories;
      });

      data.totalCalories = total;
      return data.totalCalories;
    }
  };
})();

const UIController = (function () {
  const UISelectors = {
    itemList: '#item-list',
    listItems: '#item-list li',
    addBtn: '.add-btn',
    updateBtn: '.update-btn',
    deleteBtn: '.delete-btn',
    backBtn: '.back-btn',
    clearBtn: '.clear-btn',
    itemNameInput: '#item-name',
    itemCaloriesInput: '#item-calories',
    totalCalories: '.total-calories'
  };

  return {
    showTotalCalories: function (totalCalories) {
      document.querySelector(UISelectors.totalCalories).textContent = totalCalories;
    },

    clearEditState: function () {
      document.querySelector(UISelectors.itemNameInput).value = '';
      document.querySelector(UISelectors.itemCaloriesInput).value = '';
      document.querySelector(UISelectors.updateBtn).style.display = 'none';
      document.querySelector(UISelectors.deleteBtn).style.display = 'none';
      document.querySelector(UISelectors.backBtn).style.display = 'none';
      document.querySelector(UISelectors.addBtn).style.display = 'inline';
    },

    deleteListItem: function (id) {
      const itemID = `#item-${id}`;
      const item = document.querySelector(itemID);

      if (item) {
        item.remove();
      }
    },

    removeItems: function () {
      let listItems = document.querySelectorAll(UISelectors.listItems);

      listItems = Array.from(listItems);

      listItems.forEach(function (item) {
        item.remove();
      });
    },

    hideList: function () {
      document.querySelector(UISelectors.itemList).style.display = 'none';
    },

    getSelectors: function () {
      return UISelectors;
    }
  };
})();

const App = (function (ItemController, UIController) {
  const UISelectors = UIController.getSelectors();

  const loadEventListeners = function () {
    document
      .querySelector(UISelectors.backBtn)
      .addEventListener('click', UIController.clearEditState);

    document
      .querySelector(UISelectors.deleteBtn)
      .addEventListener('click', itemDeleteSubmit);

    document
      .querySelector(UISelectors.clearBtn)
      .addEventListener('click', clearAllItemsClick);
  };

  const itemDeleteSubmit = function (e) {
    e.preventDefault();

    const currentItem = ItemController.getCurrentItem();

    ItemController.deleteItem(currentItem.id);
    UIController.deleteListItem(currentItem.id);

    const totalCalories = ItemController.getTotalCalories();
    UIController.showTotalCalories(totalCalories);

    UIController.clearEditState();
  };

  const clearAllItemsClick = function () {
    ItemController.clearAllItems();
    UIController.removeItems();

    const totalCalories = ItemController.getTotalCalories();
    UIController.showTotalCalories(totalCalories);

    UIController.hideList();
  };

  return {
    init: function () {
      loadEventListeners();
    }
  };
})(ItemController, UIController);

App.init();

جمع‌بندی

در این بخش، مدیریت حذف در اپلیکیشن کامل‌تر شد. اکنون کاربر می‌تواند:

  • با دکمه Back از حالت ویرایش خارج شود
  • یک آیتم مشخص را حذف کند
  • همه آیتم‌ها را یک‌جا پاک کند
  • مجموع کالری‌ها را بعد از هر تغییر به‌صورت درست ببیند

در بخش بعدی، می‌توان داده‌ها را در localStorage ذخیره کرد تا با رفرش صفحه اطلاعات از بین نروند.

// 0 comments
#جاوااسکریپت#JavaScript#Delete Item#Clear All#Back Button#DOM#CRUD#UI Controller#Item Controller#Local Storage

نظرات (0)

نظر خود را بنویسید