29 KiB
ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ১: ওয়েব অ্যাপে HTML টেমপ্লেট এবং রুটস
প্রাক-লেকচার কুইজ
ভূমিকা
ব্রাউজারে জাভাস্ক্রিপ্ট আসার পর থেকে, ওয়েবসাইটগুলো আগের চেয়ে অনেক বেশি ইন্টারঅ্যাকটিভ এবং জটিল হয়ে উঠেছে। এখন ওয়েব প্রযুক্তি ব্যবহার করে এমন অ্যাপ্লিকেশন তৈরি করা হয় যা সরাসরি ব্রাউজারে চলে, যাকে আমরা ওয়েব অ্যাপ্লিকেশন বলি। যেহেতু ওয়েব অ্যাপগুলো অত্যন্ত ইন্টারঅ্যাকটিভ, ব্যবহারকারীরা প্রতিবার কোনো অ্যাকশন সম্পন্ন করার জন্য পুরো পেজ রিলোডের জন্য অপেক্ষা করতে চায় না। এজন্য জাভাস্ক্রিপ্ট ব্যবহার করে DOM এর মাধ্যমে সরাসরি HTML আপডেট করা হয়, যা ব্যবহারকারীদের জন্য আরও মসৃণ অভিজ্ঞতা প্রদান করে।
এই পাঠে, আমরা একটি ব্যাংক ওয়েব অ্যাপ তৈরির ভিত্তি স্থাপন করব, যেখানে HTML টেমপ্লেট ব্যবহার করে একাধিক স্ক্রিন তৈরি করা হবে যা পুরো HTML পেজ রিলোড না করেই প্রদর্শিত এবং আপডেট করা যাবে।
পূর্বশর্ত
এই পাঠে আমরা যে ওয়েব অ্যাপ তৈরি করব তা পরীক্ষা করার জন্য আপনার একটি লোকাল ওয়েব সার্ভার প্রয়োজন। যদি আপনার কাছে না থাকে, তাহলে আপনি Node.js ইনস্টল করতে পারেন এবং আপনার প্রজেক্ট ফোল্ডার থেকে npx lite-server
কমান্ডটি ব্যবহার করতে পারেন। এটি একটি লোকাল ওয়েব সার্ভার তৈরি করবে এবং আপনার অ্যাপটি ব্রাউজারে খুলবে।
প্রস্তুতি
আপনার কম্পিউটারে bank
নামে একটি ফোল্ডার তৈরি করুন এবং এর মধ্যে index.html
নামে একটি ফাইল রাখুন। আমরা এই HTML বয়লারপ্লেট থেকে শুরু করব:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bank App</title>
</head>
<body>
<!-- This is where you'll work -->
</body>
</html>
HTML টেমপ্লেট
যদি আপনি একটি ওয়েব পেজের জন্য একাধিক স্ক্রিন তৈরি করতে চান, তাহলে একটি সমাধান হতে পারে প্রতিটি স্ক্রিনের জন্য একটি HTML ফাইল তৈরি করা। তবে, এই সমাধান কিছু অসুবিধা নিয়ে আসে:
- স্ক্রিন পরিবর্তনের সময় পুরো HTML রিলোড করতে হয়, যা ধীর হতে পারে।
- বিভিন্ন স্ক্রিনের মধ্যে ডেটা শেয়ার করা কঠিন।
আরেকটি পদ্ধতি হলো একটি মাত্র HTML ফাইল রাখা এবং <template>
এলিমেন্ট ব্যবহার করে একাধিক HTML টেমপ্লেট সংজ্ঞায়িত করা। একটি টেমপ্লেট হলো পুনঃব্যবহারযোগ্য HTML ব্লক যা ব্রাউজারে প্রদর্শিত হয় না এবং রানটাইমে জাভাস্ক্রিপ্ট ব্যবহার করে ইনস্ট্যান্সিয়েট করতে হয়।
কাজ
আমরা একটি ব্যাংক অ্যাপ তৈরি করব যার দুটি স্ক্রিন থাকবে: লগইন পেজ এবং ড্যাশবোর্ড। প্রথমে, HTML বডিতে একটি প্লেসহোল্ডার এলিমেন্ট যোগ করুন যা আমাদের অ্যাপের বিভিন্ন স্ক্রিন ইনস্ট্যান্সিয়েট করতে ব্যবহার করা হবে:
<div id="app">Loading...</div>
আমরা এটিকে একটি id
দিয়েছি যাতে এটি পরে জাভাস্ক্রিপ্ট দিয়ে সহজে খুঁজে পাওয়া যায়।
টিপ: যেহেতু এই এলিমেন্টের কন্টেন্ট প্রতিস্থাপিত হবে, আমরা এখানে একটি লোডিং মেসেজ বা ইন্ডিকেটর রাখতে পারি যা অ্যাপ লোড হওয়ার সময় দেখানো হবে।
এরপর, লগইন পেজের জন্য HTML টেমপ্লেটটি নিচে যোগ করুন। আপাতত আমরা সেখানে একটি শিরোনাম এবং একটি সেকশন রাখব যাতে একটি লিঙ্ক থাকবে যা আমরা নেভিগেশনের জন্য ব্যবহার করব।
<template id="login">
<h1>Bank App</h1>
<section>
<a href="/dashboard">Login</a>
</section>
</template>
এরপর আমরা ড্যাশবোর্ড পেজের জন্য আরেকটি HTML টেমপ্লেট যোগ করব। এই পেজে বিভিন্ন সেকশন থাকবে:
- একটি হেডার যেখানে শিরোনাম এবং লগআউট লিঙ্ক থাকবে
- ব্যাংক অ্যাকাউন্টের বর্তমান ব্যালেন্স
- একটি টেবিলে প্রদর্শিত লেনদেনের তালিকা
<template id="dashboard">
<header>
<h1>Bank App</h1>
<a href="/login">Logout</a>
</header>
<section>
Balance: 100$
</section>
<section>
<h2>Transactions</h2>
<table>
<thead>
<tr>
<th>Date</th>
<th>Object</th>
<th>Amount</th>
</tr>
</thead>
<tbody></tbody>
</table>
</section>
</template>
টিপ: HTML টেমপ্লেট তৈরি করার সময়, যদি আপনি দেখতে চান এটি কেমন দেখাবে, তাহলে
<template>
এবং</template>
লাইনগুলোকে<!-- -->
দিয়ে কমেন্ট আউট করতে পারেন।
✅ আপনি কেন মনে করেন আমরা টেমপ্লেটগুলিতে id
অ্যাট্রিবিউট ব্যবহার করি? আমরা কি এর পরিবর্তে ক্লাস ব্যবহার করতে পারতাম?
জাভাস্ক্রিপ্ট দিয়ে টেমপ্লেট প্রদর্শন
যদি আপনি আপনার বর্তমান HTML ফাইলটি ব্রাউজারে চেষ্টা করেন, তাহলে দেখবেন এটি Loading...
দেখিয়ে আটকে আছে। এর কারণ হলো আমাদের কিছু জাভাস্ক্রিপ্ট কোড যোগ করতে হবে টেমপ্লেট ইনস্ট্যান্সিয়েট এবং প্রদর্শন করার জন্য।
টেমপ্লেট ইনস্ট্যান্সিয়েট সাধারণত ৩টি ধাপে করা হয়:
- DOM-এ টেমপ্লেট এলিমেন্টটি খুঁজে বের করা, উদাহরণস্বরূপ
document.getElementById
ব্যবহার করে। - টেমপ্লেট এলিমেন্টটি ক্লোন করা,
cloneNode
ব্যবহার করে। - এটি একটি দৃশ্যমান এলিমেন্টের অধীনে DOM-এ সংযুক্ত করা, উদাহরণস্বরূপ
appendChild
ব্যবহার করে।
✅ আমরা কেন টেমপ্লেট ক্লোন করার প্রয়োজন হয় DOM-এ সংযুক্ত করার আগে? যদি আমরা এই ধাপটি বাদ দিই তাহলে কী হতে পারে?
কাজ
আপনার প্রজেক্ট ফোল্ডারে app.js
নামে একটি নতুন ফাইল তৈরি করুন এবং এটি আপনার HTML এর <head>
সেকশনে ইমপোর্ট করুন:
<script src="app.js" defer></script>
এখন app.js
-এ, আমরা একটি নতুন ফাংশন updateRoute
তৈরি করব:
function updateRoute(templateId) {
const template = document.getElementById(templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
এখানে আমরা ঠিক উপরে বর্ণিত ৩টি ধাপ অনুসরণ করেছি। আমরা templateId
এর টেমপ্লেট ইনস্ট্যান্সিয়েট করেছি এবং এর ক্লোন করা কন্টেন্ট আমাদের অ্যাপের প্লেসহোল্ডারে রেখেছি। লক্ষ্য করুন যে আমরা cloneNode(true)
ব্যবহার করেছি পুরো সাবট্রি কপি করার জন্য।
এখন এই ফাংশনটি একটি টেমপ্লেট দিয়ে কল করুন এবং ফলাফল দেখুন।
updateRoute('login');
✅ এই কোডের উদ্দেশ্য কী app.innerHTML = '';
? এটি ছাড়া কী ঘটে?
রুট তৈরি করা
যখন একটি ওয়েব অ্যাপের কথা বলা হয়, তখন রাউটিং বলতে বোঝায় URL-কে নির্দিষ্ট স্ক্রিনের সাথে ম্যাপ করা যা প্রদর্শিত হওয়া উচিত। একাধিক HTML ফাইল সহ একটি ওয়েবসাইটে, এটি স্বয়ংক্রিয়ভাবে ঘটে কারণ ফাইল পাথগুলো URL-এ প্রতিফলিত হয়। উদাহরণস্বরূপ, আপনার প্রজেক্ট ফোল্ডারে এই ফাইলগুলো থাকলে:
mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html
যদি আপনি mywebsite
কে রুট হিসেবে একটি ওয়েব সার্ভার তৈরি করেন, তাহলে URL ম্যাপিং হবে:
https://site.com --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
তবে, আমাদের ওয়েব অ্যাপের জন্য আমরা একটি মাত্র HTML ফাইল ব্যবহার করছি যাতে সব স্ক্রিন রয়েছে, তাই এই ডিফল্ট আচরণ আমাদের সাহায্য করবে না। আমাদের এই ম্যাপটি ম্যানুয়ালি তৈরি করতে হবে এবং জাভাস্ক্রিপ্ট ব্যবহার করে প্রদর্শিত টেমপ্লেট আপডেট করতে হবে।
কাজ
আমরা একটি সাধারণ অবজেক্ট ব্যবহার করব একটি ম্যাপ বাস্তবায়ন করতে যা URL পাথ এবং আমাদের টেমপ্লেটগুলোর মধ্যে সম্পর্ক স্থাপন করবে। এই অবজেক্টটি আপনার app.js
ফাইলের শীর্ষে যোগ করুন:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard' },
};
এখন updateRoute
ফাংশনটি একটু পরিবর্তন করি। সরাসরি templateId
আর্গুমেন্ট হিসেবে পাস করার পরিবর্তে, আমরা প্রথমে বর্তমান URL দেখব এবং তারপর আমাদের ম্যাপ ব্যবহার করে সংশ্লিষ্ট টেমপ্লেট ID মানটি পাব। আমরা window.location.pathname
ব্যবহার করতে পারি URL থেকে শুধুমাত্র পাথ সেকশনটি পেতে।
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
const template = document.getElementById(route.templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
এখানে আমরা ঘোষিত রুটগুলোকে সংশ্লিষ্ট টেমপ্লেটের সাথে ম্যাপ করেছি। এটি সঠিকভাবে কাজ করছে কিনা তা পরীক্ষা করতে ব্রাউজারে ম্যানুয়ালি URL পরিবর্তন করুন।
✅ যদি আপনি URL-এ একটি অজানা পাথ প্রবেশ করেন তাহলে কী ঘটে? আমরা কীভাবে এটি সমাধান করতে পারি?
নেভিগেশন যোগ করা
আমাদের অ্যাপের পরবর্তী ধাপ হলো পেজগুলোর মধ্যে নেভিগেশনের সম্ভাবনা যোগ করা, যাতে ম্যানুয়ালি URL পরিবর্তন করতে না হয়। এটি দুটি বিষয় জড়িত:
- বর্তমান URL আপডেট করা
- নতুন URL এর উপর ভিত্তি করে প্রদর্শিত টেমপ্লেট আপডেট করা
আমরা ইতিমধ্যে updateRoute
ফাংশনের মাধ্যমে দ্বিতীয় অংশটি সম্পন্ন করেছি, তাই আমাদের বর্তমান URL আপডেট করার উপায় বের করতে হবে।
আমাদের জাভাস্ক্রিপ্ট ব্যবহার করতে হবে এবং বিশেষ করে history.pushState
ব্যবহার করতে হবে যা URL আপডেট করতে এবং ব্রাউজিং হিস্টরিতে একটি নতুন এন্ট্রি তৈরি করতে দেয়, HTML রিলোড না করেই।
নোট: HTML অ্যাঙ্কর এলিমেন্ট
<a href>
নিজে থেকেই বিভিন্ন URL-এ হাইপারলিঙ্ক তৈরি করতে ব্যবহার করা যেতে পারে, তবে এটি ডিফল্টভাবে ব্রাউজারকে HTML রিলোড করতে বাধ্য করবে। কাস্টম জাভাস্ক্রিপ্ট দিয়ে রাউটিং পরিচালনা করার সময় এই আচরণটি প্রতিরোধ করা প্রয়োজন, ক্লিক ইভেন্টেpreventDefault()
ফাংশন ব্যবহার করে।
কাজ
আমাদের অ্যাপে নেভিগেট করার জন্য একটি নতুন ফাংশন তৈরি করুন:
function navigate(path) {
window.history.pushState({}, path, path);
updateRoute();
}
এই মেথডটি প্রথমে প্রদত্ত পাথের উপর ভিত্তি করে বর্তমান URL আপডেট করে, তারপর টেমপ্লেট আপডেট করে। window.location.origin
প্রপার্টি URL রুট রিটার্ন করে, যা আমাদের একটি প্রদত্ত পাথ থেকে একটি সম্পূর্ণ URL পুনর্গঠন করতে দেয়।
এখন যেহেতু আমাদের এই ফাংশনটি আছে, আমরা যদি কোনো পাথ কোনো সংজ্ঞায়িত রুটের সাথে মেলে না তাহলে যে সমস্যাটি হয় তা সমাধান করতে পারি। আমরা updateRoute
ফাংশনটি পরিবর্তন করব এবং কোনো ম্যাচ না পেলে বিদ্যমান রুটগুলোর একটিতে ফিরে যাব।
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
if (!route) {
return navigate('/login');
}
...
যদি কোনো রুট খুঁজে না পাওয়া যায়, আমরা এখন login
পেজে রিডাইরেক্ট করব।
এখন একটি ফাংশন তৈরি করুন যা একটি লিঙ্ক ক্লিক করার সময় URL পায় এবং ব্রাউজারের ডিফল্ট লিঙ্ক আচরণ প্রতিরোধ করে:
function onLinkClick(event) {
event.preventDefault();
navigate(event.target.href);
}
আমাদের নেভিগেশন সিস্টেম সম্পূর্ণ করতে আমাদের HTML এর লগইন এবং লগআউট লিঙ্কগুলোর সাথে বাইন্ডিং যোগ করুন:
<a href="/dashboard" onclick="onLinkClick(event)">Login</a>
...
<a href="/login" onclick="onLinkClick(event)">Logout</a>
উপরের event
অবজেক্টটি click
ইভেন্টটি ক্যাপচার করে এবং আমাদের onLinkClick
ফাংশনে পাস করে।
onclick
অ্যাট্রিবিউট ব্যবহার করে click
ইভেন্টটি জাভাস্ক্রিপ্ট কোডের সাথে বাইন্ড করুন, এখানে navigate()
ফাংশন কল।
এই লিঙ্কগুলোতে ক্লিক করে দেখুন, এখন আপনি আপনার অ্যাপের বিভিন্ন স্ক্রিনের মধ্যে নেভিগেট করতে সক্ষম হবেন।
✅ history.pushState
মেথডটি HTML5 স্ট্যান্ডার্ডের অংশ এবং সব আধুনিক ব্রাউজারে ইমপ্লিমেন্ট করা হয়েছে। যদি আপনি পুরোনো ব্রাউজারের জন্য একটি ওয়েব অ্যাপ তৈরি করেন, তাহলে এই API এর পরিবর্তে একটি কৌশল ব্যবহার করতে পারেন: পাথের আগে একটি হ্যাশ (#
) ব্যবহার করে আপনি এমন রাউটিং বাস্তবায়ন করতে পারেন যা সাধারণ অ্যাঙ্কর নেভিগেশনের সাথে কাজ করে এবং পেজ রিলোড করে না, কারণ এর উদ্দেশ্য ছিল একটি পেজের মধ্যে অভ্যন্তরীণ লিঙ্ক তৈরি করা।
ব্রাউজারের ব্যাক এবং ফরোয়ার্ড বোতাম পরিচালনা করা
history.pushState
ব্যবহার করে ব্রাউজারের নেভিগেশন হিস্টরিতে নতুন এন্ট্রি তৈরি হয়। আপনি ব্রাউজারের ব্যাক বোতাম ধরে রাখলে এটি এমন কিছু দেখাবে:
যদি আপনি কয়েকবার ব্যাক বোতামে ক্লিক করেন, তাহলে দেখবেন বর্তমান URL পরিবর্তিত হচ্ছে এবং হিস্টরি আপডেট হচ্ছে, কিন্তু একই টেমপ্লেট প্রদর্শিত হচ্ছে।
এর কারণ হলো অ্যাপ্লিকেশনটি জানে না যে প্রতিবার হিস্টরি পরিবর্তিত হলে আমাদের updateRoute()
কল করতে হবে। যদি আপনি history.pushState
ডকুমেন্টেশন দেখেন, তাহলে দেখতে পাবেন যে যদি স্টেট পরিবর্তিত হয় - অর্থাৎ আমরা একটি ভিন্ন URL-এ চলে যাই - তাহলে popstate
ইভেন্ট ট্রিগার হয়। আমরা এটি ব্যবহার করে সমস্যাটি সমাধান করব।
কাজ
যখন ব্রাউজারের হিস্টরি পরিবর্তিত হয় তখন প্রদর্শিত টেমপ্লেট আপডেট নিশ্চিত করতে, আমরা একটি নতুন ফাংশন সংযুক্ত করব যা updateRoute()
কল করে। আমরা এটি app.js
ফাইলের নিচে করব:
window.onpopstate = () => updateRoute();
updateRoute();
নোট: আমরা এখানে আমাদের
popstate
ইভেন্ট হ্যান্ডলার ঘোষণা করার জন্য অ্যারো ফাংশন ব্যবহার করেছি সংক্ষিপ্ততার জন্য, তবে একটি সাধারণ ফাংশনও একইভাবে কাজ করবে।
অ্যারো ফাংশনের উপর একটি রিফ্রেশার ভিডিও:
🎥 উপরের ছবিতে ক্লিক করুন অ্যারো ফাংশনের ভিডিও দেখার জন্য।
এখন ব্রাউজারের ব্যাক এবং ফরোয়ার্ড বোতাম ব্যবহার করে দেখুন, এবং নিশ্চিত করুন যে এইবার প্রদর্শিত রুট সঠিকভাবে আপডেট হচ্ছে।
🚀 চ্যালেঞ্জ
এই অ্যাপের জন্য ক্রেডিট দেখানোর জন্য একটি তৃতীয় পেজের জন্য একটি নতুন টেমপ্লেট এবং রুট যোগ করুন।
পোস্ট-লেকচার কুইজ
পর্যালোচনা ও স্ব-অধ্যয়ন
রাউটিং হলো ওয়েব ডেভেলপমেন্টের একটি আশ্চর্যজনকভাবে জটিল অংশ, বিশেষ করে যখন ওয়েব পেজ রিফ্রেশ আচরণ থেকে সিঙ্গেল পেজ অ্যাপ্লিকেশন পেজ রিফ্রেশে চলে যায়। Azure Static Web App সার্ভিস কীভাবে রাউটিং পরিচালনা করে সে সম্পর্কে একটু পড়ুন। আপনি কি ব্যাখ্যা করতে পারবেন কেন এই ডকুমেন্টে বর্ণিত কিছু সিদ্ধান্ত প্রয়োজনীয়?
অ্যাসাইনমেন্ট
অস্বীকৃতি:
এই নথিটি AI অনুবাদ পরিষেবা Co-op Translator ব্যবহার করে অনুবাদ করা হয়েছে। আমরা যথাসাধ্য সঠিকতা নিশ্চিত করার চেষ্টা করি, তবে অনুগ্রহ করে মনে রাখবেন যে স্বয়ংক্রিয় অনুবাদে ত্রুটি বা অসঙ্গতি থাকতে পারে। মূল ভাষায় থাকা নথিটিকে প্রামাণিক উৎস হিসেবে বিবেচনা করা উচিত। গুরুত্বপূর্ণ তথ্যের জন্য, পেশাদার মানব অনুবাদ সুপারিশ করা হয়। এই অনুবাদ ব্যবহারের ফলে কোনো ভুল বোঝাবুঝি বা ভুল ব্যাখ্যা হলে আমরা তার জন্য দায়বদ্ধ নই।