# बैंकिङ एप निर्माण भाग २: लगइन र दर्ता फारम निर्माण गर्नुहोस् ## प्रि-लेक्चर क्विज [प्रि-लेक्चर क्विज](https://ff-quizzes.netlify.app/web/quiz/43) ### परिचय प्रायः सबै आधुनिक वेब एपहरूमा, तपाईंले आफ्नो निजी स्थान बनाउन खाता बनाउन सक्नुहुन्छ। धेरै प्रयोगकर्ताहरूले एकै समयमा वेब एप पहुँच गर्न सक्ने भएकाले, प्रत्येक प्रयोगकर्ताको व्यक्तिगत डेटा अलग-अलग भण्डारण गर्न र कुन जानकारी देखाउने छनौट गर्न मेकानिजम आवश्यक छ। हामी [प्रयोगकर्ता पहिचान सुरक्षित रूपमा](https://en.wikipedia.org/wiki/Authentication) कसरी व्यवस्थापन गर्ने भन्ने विषयलाई कभर गर्ने छैनौं किनकि यो आफैंमा एक विस्तृत विषय हो, तर हामी सुनिश्चित गर्नेछौं कि प्रत्येक प्रयोगकर्ताले हाम्रो एपमा एक (वा धेरै) बैंक खाता बनाउन सक्षम छ। यस भागमा हामी HTML फारमहरू प्रयोग गरेर हाम्रो वेब एपमा लगइन र दर्ता थप्नेछौं। हामी डेटा प्रोग्रामेटिक रूपमा सर्भर API मा कसरी पठाउने र अन्ततः प्रयोगकर्ता इनपुटहरूको लागि आधारभूत मान्यता नियमहरू कसरी परिभाषित गर्ने भन्ने देख्नेछौं। ### पूर्वापेक्षा तपाईंले यस पाठको लागि वेब एपको [HTML टेम्प्लेट र राउटिङ](../1-template-route/README.md) पूरा गरिसक्नुपर्छ। तपाईंले [Node.js](https://nodejs.org) स्थापना गर्न र [सर्भर API चलाउन](../api/README.md) स्थानीय रूपमा सेटअप गर्नुपर्छ ताकि तपाईं खाता बनाउन डेटा पठाउन सक्नुहुन्छ। **नोट गर्नुहोस्** तपाईंसँग एकै समयमा दुई टर्मिनलहरू चलिरहेको हुनेछ जस्तै तल सूचीबद्ध गरिएको छ। 1. मुख्य बैंक एपको लागि जुन हामीले [HTML टेम्प्लेट र राउटिङ](../1-template-route/README.md) पाठमा निर्माण गरेका थियौं। 2. [बैंक एप सर्भर API](../api/README.md) जुन हामीले माथि सेटअप गरेका थियौं। पाठको बाँकी भागमा अगाडि बढ्न तपाईंले दुई सर्भरहरू चलिरहेको हुनुपर्छ। तिनीहरू फरक पोर्टहरूमा (पोर्ट `3000` र पोर्ट `5000`) सुन्दैछन् त्यसैले सबै ठीकसँग काम गर्नुपर्छ। तपाईंले सर्भर ठीकसँग चलिरहेको छ कि छैन भनेर जाँच गर्न टर्मिनलमा यो कमाण्ड कार्यान्वयन गर्न सक्नुहुन्छ: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## फारम र नियन्त्रणहरू `
` तत्वले HTML दस्तावेजको एक खण्डलाई समेट्छ जहाँ प्रयोगकर्ताले अन्तरक्रियात्मक नियन्त्रणहरूसँग डेटा इनपुट र सबमिट गर्न सक्छ। फारमभित्र प्रयोग गर्न सकिने सबै प्रकारका प्रयोगकर्ता इन्टरफेस (UI) नियन्त्रणहरू छन्, सबैभन्दा सामान्य `` र `
``` `value` विशेषता प्रयोग गरेर हामीले दिएको इनपुटको लागि डिफल्ट मान परिभाषित गर्न सक्छौं। ध्यान दिनुहोस् कि `balance` को इनपुटमा `number` प्रकार छ। के यो अन्य इनपुटहरू भन्दा फरक देखिन्छ? यससँग अन्तरक्रिया गरेर प्रयास गर्नुहोस्। ✅ के तपाईं केवल किबोर्ड प्रयोग गरेर फारमहरू नेभिगेट र अन्तरक्रिया गर्न सक्नुहुन्छ? तपाईंले यो कसरी गर्नुहुन्छ? ## सर्भरमा डेटा सबमिट गर्नुहोस् अब हामीसँग कार्यात्मक UI छ, अर्को चरण भनेको डेटा सर्भरमा पठाउनु हो। हाम्रो हालको कोड प्रयोग गरेर छिटो परीक्षण गरौं: यदि तपाईंले *लगइन* वा *दर्ता* बटन क्लिक गर्नुभयो भने के हुन्छ? के तपाईंले आफ्नो ब्राउजरको URL सेक्सनमा परिवर्तन देख्नुभयो? ![दर्ता बटन क्लिक गरेपछि ब्राउजरको URL परिवर्तनको स्क्रिनशट](../../../../translated_images/click-register.e89a30bf0d4bc9ca867dc537c4cea679a7c26368bd790969082f524fed2355bc.ne.png) `
` को लागि डिफल्ट कार्य भनेको फारमलाई हालको सर्भर URL मा [GET विधि](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) प्रयोग गरेर सबमिट गर्नु हो, फारम डेटा URL मा सिधै थप्दै। तर यो विधिमा केही सीमाहरू छन्: - पठाइएको डेटा धेरै सीमित आकारको हुन्छ (लगभग 2000 अक्षर) - डेटा URL मा सिधै देखिन्छ (पासवर्डको लागि राम्रो होइन) - यो फाइल अपलोडहरूसँग काम गर्दैन त्यसैले तपाईंले यसलाई [POST विधि](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5) प्रयोग गर्न परिवर्तन गर्न सक्नुहुन्छ जसले फारम डेटा HTTP अनुरोधको शरीरमा सर्भरमा पठाउँछ, बिना कुनै सीमाहरू। > जबकि POST डेटा पठाउनको लागि सबैभन्दा सामान्य रूपमा प्रयोग गरिएको विधि हो, [केही विशेष परिदृश्यहरूमा](https://www.w3.org/2001/tag/doc/whenToUseGet.html) GET विधि प्रयोग गर्नु उपयुक्त हुन्छ, जस्तै खोज क्षेत्र कार्यान्वयन गर्दा। ### कार्य दर्ता फारममा `action` र `method` गुणहरू थप्नुहोस्: ```html ``` अब आफ्नो नामसँग नयाँ खाता दर्ता गर्न प्रयास गर्नुहोस्। *दर्ता* बटन क्लिक गरेपछि तपाईंले यस्तो देख्नुपर्छ: ![ब्राउजर विन्डो localhost:5000/api/accounts मा, प्रयोगकर्ता डेटा भएको JSON स्ट्रिङ देखाउँदै](../../../../translated_images/form-post.61de4ca1b964d91a9e338416e19f218504dd0af5f762fbebabfe7ae80edf885f.ne.png) यदि सबै ठीक छ भने, सर्भरले तपाईंको अनुरोधलाई [JSON](https://www.json.org/json-en.html) प्रतिक्रिया दिनेछ जसमा सिर्जना गरिएको खाता डेटा समावेश हुनेछ। ✅ उस्तै नामसँग फेरि दर्ता गर्न प्रयास गर्नुहोस्। के हुन्छ? ## पृष्ठ पुनःलोड नगरी डेटा सबमिट गर्नुहोस् जसरी तपाईंले सम्भवतः देख्नुभयो, हामीले प्रयोग गरेको विधिमा एउटा सानो समस्या छ: फारम सबमिट गर्दा, हामी हाम्रो एपबाट बाहिर जान्छौं र ब्राउजर सर्भर URL मा पुनःनिर्देशित हुन्छ। हामी हाम्रो वेब एपसँग सबै पृष्ठ पुनःलोडहरूबाट बच्न प्रयास गर्दैछौं, किनकि हामी [सिंगल-पेज एप्लिकेसन (SPA)](https://en.wikipedia.org/wiki/Single-page_application) बनाउँदैछौं। फारम डेटा सर्भरमा पृष्ठ पुनःलोड नगरी पठाउन, हामीले JavaScript कोड प्रयोग गर्नुपर्छ। `` तत्वको `action` गुणमा URL राख्नुको सट्टा, तपाईंले कुनै पनि JavaScript कोड `javascript:` स्ट्रिङको साथ प्रयोग गर्न सक्नुहुन्छ ताकि कस्टम कार्य प्रदर्शन गर्न सकियोस्। यसलाई प्रयोग गर्दा ब्राउजरले स्वचालित रूपमा गरिने केही कार्यहरू तपाईंले कार्यान्वयन गर्नुपर्नेछ: - फारम डेटा प्राप्त गर्नुहोस् - फारम डेटा उपयुक्त ढाँचामा रूपान्तरण र एन्कोड गर्नुहोस् - HTTP अनुरोध सिर्जना गर्नुहोस् र सर्भरमा पठाउनुहोस् ### कार्य दर्ता फारमको `action` लाई प्रतिस्थापन गर्नुहोस्: ```html ``` `app.js` खोल्नुहोस् र `register` नामक नयाँ फङ्सन थप्नुहोस्: ```js function register() { const registerForm = document.getElementById('registerForm'); const formData = new FormData(registerForm); const data = Object.fromEntries(formData); const jsonData = JSON.stringify(data); } ``` यहाँ हामीले फारम तत्वलाई `getElementById()` प्रयोग गरेर प्राप्त गर्छौं र [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) सहायक प्रयोग गरेर फारम नियन्त्रणहरूबाट मानहरूलाई कुञ्जी/मानको सेटको रूपमा निकाल्छौं। त्यसपछि हामीले डेटालाई [`Object.fromEntries()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries) प्रयोग गरेर नियमित वस्तुमा रूपान्तरण गर्छौं र अन्ततः डेटा [JSON](https://www.json.org/json-en.html) मा सिरियलाइज गर्छौं, वेबमा डेटा आदानप्रदान गर्न सामान्य रूपमा प्रयोग गरिने ढाँचा। अब डेटा सर्भरमा पठाउन तयार छ। `createAccount` नामक नयाँ फङ्सन सिर्जना गर्नुहोस्: ```js async function createAccount(account) { try { const response = await fetch('//localhost:5000/api/accounts', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: account }); return await response.json(); } catch (error) { return { error: error.message || 'Unknown error' }; } } ``` यो फङ्सनले के गर्दैछ? पहिलो कुरा, यहाँ `async` कीवर्डलाई ध्यान दिनुहोस्। यसको मतलब यो हो कि फङ्सनमा कोड समावेश छ जुन [**असिंक्रोनस रूपमा**](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/async_function) कार्यान्वयन हुनेछ। `await` कीवर्डको साथ प्रयोग गर्दा, यसले असिंक्रोनस कोड कार्यान्वयन गर्न पर्खन अनुमति दिन्छ - जस्तै यहाँ सर्भर प्रतिक्रिया पर्खनु - अघि जारी राख्न। यहाँ `async/await` प्रयोगको बारेमा छिटो भिडियो छ: [![प्रमिसहरू व्यवस्थापन गर्न Async र Await](https://img.youtube.com/vi/YwmlRkrxvkk/0.jpg)](https://youtube.com/watch?v=YwmlRkrxvkk "प्रमिसहरू व्यवस्थापन गर्न Async र Await") > 🎥 Async/await को बारेमा भिडियो हेर्न माथिको छवि क्लिक गर्नुहोस्। हामीले JSON डेटा सर्भरमा पठाउन `fetch()` API प्रयोग गर्छौं। यो विधिले २ प्यारामिटरहरू लिन्छ: - सर्भरको URL, त्यसैले हामी यहाँ `//localhost:5000/api/accounts` फिर्ता राख्छौं। - अनुरोधको सेटिङहरू। त्यहाँ हामीले विधिलाई `POST` मा सेट गर्छौं र अनुरोधको लागि `body` प्रदान गर्छौं। हामी JSON डेटा सर्भरमा पठाउँदैछौं, त्यसैले हामीले `Content-Type` हेडरलाई `application/json` मा सेट गर्न आवश्यक छ ताकि सर्भरले सामग्रीलाई कसरी व्याख्या गर्ने थाहा पाओस्। सर्भरले अनुरोधलाई JSON प्रतिक्रिया दिनेछ, त्यसैले हामीले JSON सामग्रीलाई पार्स गर्न र परिणामी वस्तु फिर्ता गर्न `await response.json()` प्रयोग गर्न सक्छौं। ध्यान दिनुहोस् कि यो विधि असिंक्रोनस छ, त्यसैले हामी यहाँ `await` कीवर्ड प्रयोग गर्छौं ताकि पार्सिङको क्रममा कुनै पनि त्रुटिहरू पनि समात्न सकियोस्। अब `register` फङ्सनमा `createAccount()` कल गर्न केही कोड थप्नुहोस्: ```js const result = await createAccount(jsonData); ``` किनभने हामी यहाँ `await` कीवर्ड प्रयोग गर्छौं, हामीले `register` फङ्सन अघि `async` कीवर्ड थप्न आवश्यक छ: ```js async function register() { ``` अन्ततः, परिणाम जाँच गर्न केही लगहरू थपौं। अन्तिम फङ्सन यस्तो देखिनुपर्छ: ```js async function register() { const registerForm = document.getElementById('registerForm'); const formData = new FormData(registerForm); const jsonData = JSON.stringify(Object.fromEntries(formData)); const result = await createAccount(jsonData); if (result.error) { return console.log('An error occurred:', result.error); } console.log('Account created!', result); } ``` यो अलि लामो थियो तर हामी त्यहाँ पुग्यौं! यदि तपाईंले आफ्नो [ब्राउजर डेभलपर टूलहरू](https://developer.mozilla.org/docs/Learn/Common_questions/What_are_browser_developer_tools) खोल्नुभयो, र नयाँ खाता दर्ता गर्न प्रयास गर्नुभयो भने, तपाईंले वेब पृष्ठमा कुनै परिवर्तन देख्नुहुने छैन तर कन्सोलमा सन्देश देखिनेछ जसले पुष्टि गर्दछ कि सबै काम गरिरहेको छ। ![ब्राउजर कन्सोलमा लग सन्देश देखाउँदै स्क्रिनशट](../../../../translated_images/browser-console.efaf0b51aaaf67782a29e1a0bb32cc063f189b18e894eb5926e02f1abe864ec2.ne.png) ✅ के तपाईं सोच्नुहुन्छ कि डेटा सर्भरमा सुरक्षित रूपमा पठाइएको छ? यदि कसैले अनुरोधलाई रोक्न सके भने के हुन्छ? [HTTPS](https://en.wikipedia.org/wiki/HTTPS) को बारेमा पढेर सुरक्षित डेटा सञ्चारको बारेमा थप जान्न सक्नुहुन्छ। ## डेटा मान्यता यदि तपाईंले पहिले प्रयोगकर्ता नाम सेट नगरी नयाँ खाता दर्ता गर्न प्रयास गर्नुभयो भने, तपाईंले देख्न सक्नुहुन्छ कि सर्भरले [400 (Bad Request)](https://developer.mozilla.org/docs/Web/HTTP/Status/400#:~:text=The%20HyperText%20Transfer%20Protocol%20(HTTP,%2C%20or%20deceptive%20request%20routing).) स्थिति कोडको साथ त्रुटि फिर्ता गर्दछ। सर्भरमा डेटा पठाउनु अघि यो सुनिश्चित गर्न राम्रो अभ्यास हो कि तपाईंले मान्य अनुरोध पठाउन सक्नुहुन्छ। HTML5 फारम नियन्त्रणहरूले विभिन्न विशेषताहरू प्रयोग गरेर निर्मित मान्यता प्रदान गर्दछ: - `required`: क्षेत्र भर्न आवश्यक छ अन्यथा फारम सबमिट गर्न सकिँदैन। - `minlength` र `maxlength`: पाठ क्षेत्रहरूमा अक्षरहरूको न्यूनतम र अधिकतम संख्या परिभाषित गर्दछ। - `min` र `max`: संख्यात्मक क्षेत्रको न्यूनतम र अधिकतम मान परिभाषित गर्दछ। - `type`: अपेक्षित डेटा प्रकार परिभाषित गर्दछ, जस्तै `number`, `email`, `file` वा [अन्य निर्मित प्रकारहरू](https://developer.mozilla.org/docs/Web/HTML/Element/input)। यस विशेषताले फारम नियन्त्रणको दृश्य रेंडरिङ परिवर्तन गर्न सक्छ। - `pattern`: [नियमित अभिव्यक्ति](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions) ढाँचा परिभाषित गर्न अनुमति दिन्छ ताकि प्रविष्ट गरिएको डेटा मान्य छ कि छैन परीक्षण गर्न सकियोस्। > टिप: तपाईंले आफ्नो फारम नियन्त्रणहरूको रूपलाई अनुकूलित गर्न सक्नुहुन्छ यदि तिनीहरू मान्य छन् वा छैनन् `:valid` र `:invalid` CSS pseudo-classes प्रयोग गरेर। ### कार्य नयाँ खाता सिर्जना गर्नका लागि दुई आवश्यक क्षेत्रहरू छन्, प्रयोगकर्ता नाम र मुद्रा, अन्य क्षेत्रहरू वैकल्पिक छन्। फारमको HTML अपडेट गर्नुहोस्, `required` गुण र क्षेत्रको लेबलमा पाठ प्रयोग गरेर: ```html ... ``` यद्यपि यो विशेष सर्भर कार्यान्वयनले क्षेत्रहरूको अधिकतम लम्बाइमा विशिष्ट सीमाहरू लागू गर्दैन, कुनै पनि प्रयोगकर्ता पाठ प्रविष्टिको लागि उचित सीमाहरू परिभाषित गर्नु सधैं राम्रो अभ्यास हो। पाठ क्षेत्रहरूमा `maxlength` गुण थप्नुहोस्: ```html ... ... ``` अब यदि तपाईं *Register* बटन थिच्नुहुन्छ र कुनै क्षेत्रले हामीले परिभाषित गरेको मान्यता नियमको सम्मान गर्दैन भने, तपाईंले यस्तो देख्न सक्नुहुन्छ: ![फारम सबमिट गर्न खोज्दा मान्यता त्रुटि देखाउने स्क्रिनशट](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.ne.png) यस प्रकारको मान्यता जुन कुनै पनि डाटा सर्भरमा पठाउनु अघि गरिन्छ, **client-side** मान्यता भनिन्छ। तर ध्यान दिनुहोस् कि सबै जाँचहरू बिना डाटा पठाएर गर्न सधैं सम्भव छैन। उदाहरणका लागि, हामी यहाँ जाँच गर्न सक्दैनौं कि समान प्रयोगकर्ता नामको साथ खाता पहिले नै छ कि छैन सर्भरमा अनुरोध पठाउनु बिना। सर्भरमा गरिने थप मान्यता **server-side** मान्यता भनिन्छ। सामान्यतया दुवै लागू गर्न आवश्यक हुन्छ, र client-side मान्यता प्रयोग गर्दा प्रयोगकर्तालाई तुरुन्त प्रतिक्रिया प्रदान गरेर प्रयोगकर्ता अनुभव सुधार हुन्छ, server-side मान्यता भने तपाईंले हेरफेर गर्ने प्रयोगकर्ता डाटा सुरक्षित र सही छ भन्ने सुनिश्चित गर्न महत्त्वपूर्ण छ। --- --- ## GitHub Copilot Agent Challenge 🚀 Agent मोड प्रयोग गरेर निम्न चुनौती पूरा गर्नुहोस्: **विवरण:** दर्ता फारमलाई व्यापक client-side मान्यता र प्रयोगकर्ता प्रतिक्रिया सहित सुधार गर्नुहोस्। यो चुनौतीले फारम मान्यता, त्रुटि ह्यान्डलिंग, र अन्तरक्रियात्मक प्रतिक्रियाको साथ प्रयोगकर्ता अनुभव सुधार गर्ने अभ्यास गर्न मद्दत गर्नेछ। **प्रेरणा:** दर्ता फारमको लागि पूर्ण मान्यता प्रणाली सिर्जना गर्नुहोस् जसमा समावेश छ: 1) प्रयोगकर्ताले टाइप गर्दा प्रत्येक क्षेत्रको लागि वास्तविक-समय मान्यता प्रतिक्रिया, 2) प्रत्येक इनपुट क्षेत्रको तल देखिने अनुकूल मान्यता सन्देशहरू, 3) पासवर्ड पुष्टि क्षेत्र मिल्ने मान्यता सहित, 4) दृश्य संकेतकहरू (जस्तै मान्य क्षेत्रहरूको लागि हरियो चेकमार्क र अमान्य क्षेत्रहरूको लागि रातो चेतावनीहरू), 5) सबै मान्यताहरू पास हुँदा मात्र सक्षम हुने सबमिट बटन। HTML5 मान्यता गुणहरू, CSS मान्यता अवस्थाहरूको लागि शैलीकरण गर्न, र अन्तरक्रियात्मक व्यवहारको लागि JavaScript प्रयोग गर्नुहोस्। ## 🚀 चुनौती HTML मा त्रुटि सन्देश देखाउनुहोस् यदि प्रयोगकर्ता पहिले नै छ भने। यहाँ केहि CSS शैलीहरू थपेपछि अन्तिम लगइन पृष्ठ कस्तो देखिन सक्छ भन्ने उदाहरण छ: ![CSS शैलीहरू थपेपछि लगइन पृष्ठको स्क्रिनशट](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.ne.png) ## पोस्ट-व्याख्यान क्विज [पोस्ट-व्याख्यान क्विज](https://ff-quizzes.netlify.app/web/quiz/44) ## समीक्षा र आत्म अध्ययन डेभलपरहरूले फारम निर्माण प्रयासहरूमा, विशेष गरी मान्यता रणनीतिहरूमा धेरै रचनात्मक भएका छन्। [CodePen](https://codepen.com) हेरेर विभिन्न फारम प्रवाहहरूको बारेमा जान्नुहोस्; के तपाईंले केही रोचक र प्रेरणादायक फारमहरू फेला पार्न सक्नुहुन्छ? ## असाइनमेन्ट [आफ्नो बैंक एपलाई शैली दिनुहोस्](assignment.md) --- **अस्वीकरण**: यो दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) प्रयोग गरेर अनुवाद गरिएको हो। हामी शुद्धताको लागि प्रयास गर्छौं, तर कृपया ध्यान दिनुहोस् कि स्वचालित अनुवादमा त्रुटिहरू वा अशुद्धताहरू हुन सक्छ। यसको मूल भाषा मा रहेको दस्तावेज़लाई आधिकारिक स्रोत मानिनुपर्छ। महत्वपूर्ण जानकारीको लागि, व्यावसायिक मानव अनुवाद सिफारिस गरिन्छ। यस अनुवादको प्रयोगबाट उत्पन्न हुने कुनै पनि गलतफहमी वा गलत व्याख्याको लागि हामी जिम्मेवार हुने छैनौं।