# बैंकिङ एप निर्माण भाग २: लगइन र रजिस्ट्रेशन फारम बनाउने ## प्रि-लेक्चर क्विज [प्रि-लेक्चर क्विज](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 प्रतिक्रिया दिनेछ जसमा सिर्जना गरिएको खाता डेटा समावेश हुनेछ। ✅ उही नाम प्रयोग गरेर फेरि रजिस्टर गर्न प्रयास गर्नुहोस्। के हुन्छ? ## पेज रिफ्रेस नगरी डेटा सबमिट गर्ने जसरी तपाईंले नोट गर्नुभयो, हामीले प्रयोग गरेको विधिमा एउटा सानो समस्या छ: फारम सबमिट गर्दा, हामी हाम्रो एपबाट बाहिर जान्छौं र ब्राउजर सर्भर 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` कीवर्डको साथ प्रयोग गर्दा, यसले असिंक्रोनस कोड कार्यान्वयनको लागि पर्खन अनुमति दिन्छ - जस्तै यहाँ सर्भर प्रतिक्रिया पर्खन - अघि बढ्नु अघि। `fetch()` API प्रयोग गरेर हामी JSON डेटा सर्भरमा पठाउँछौं। यो मेथडले दुई प्यारामिटरहरू लिन्छ: - सर्भरको URL, त्यसैले हामी यहाँ `//localhost:5000/api/accounts` फिर्ता राख्छौं। - अनुरोधको सेटिङहरू। यहीँ हामी मेथडलाई `POST` मा सेट गर्छौं र अनुरोधको लागि `body` प्रदान गर्छौं। चूँकि हामी JSON डेटा सर्भरमा पठाउँदैछौं, हामीले `Content-Type` हेडरलाई `application/json` मा सेट गर्नुपर्छ ताकि सर्भरले सामग्रीलाई कसरी व्याख्या गर्ने थाहा पाओस्। चूँकि सर्भरले अनुरोधलाई JSON प्रतिक्रिया दिनेछ, हामी `await response.json()` प्रयोग गरेर 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).) स्टाटस कोडको साथ त्रुटि फिर्ता गर्छ। सर्भरमा डेटा पठाउनु अघि [फारम डेटा मान्यता](https://developer.mozilla.org/docs/Learn/Forms/Form_validation) गर्नु राम्रो अभ्यास हो ताकि तपाईंले मान्य अनुरोध पठाउन सकियोस्। 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 प्रयोग गरेर। ### कार्य नयाँ खाता बनाउनका लागि दुई अनिवार्य फिल्डहरू आवश्यक छन्: प्रयोगकर्ता नाम (username) र मुद्रा (currency)। अन्य फिल्डहरू वैकल्पिक छन्। फारमको HTML अपडेट गर्नुहोस्, `required` एट्रिब्युट र फिल्डको लेबलमा पाठ प्रयोग गरेर यसरी: ```html ... ``` यद्यपि यो विशेष सर्भर कार्यान्वयनले फिल्डहरूको अधिकतम लम्बाइमा कुनै निश्चित सीमा लागू गर्दैन, कुनै पनि प्रयोगकर्ता पाठ प्रविष्टिका लागि उपयुक्त सीमा परिभाषित गर्नु सधैं राम्रो अभ्यास हो। पाठ फिल्डहरूमा `maxlength` एट्रिब्युट थप्नुहोस्: ```html ... ... ``` अब यदि तपाईं *Register* बटन थिच्नुहुन्छ र कुनै फिल्डले हामीले परिभाषित गरेको मान्यता नियमको पालना गर्दैन भने, तपाईंले यस प्रकारको त्रुटि देख्नुहुनेछ: ![फारम सबमिट गर्न खोज्दा देखिने मान्यता त्रुटि](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.ne.png) यसरी कुनै पनि डाटा सर्भरमा पठाउनु अघि गरिने मान्यतालाई **क्लाइन्ट-साइड** मान्यता भनिन्छ। तर ध्यान दिनुहोस् कि सबै जाँचहरू डाटा पठाउनु बिना सम्भव छैन। उदाहरणका लागि, यहाँ हामी जाँच गर्न सक्दैनौं कि उही प्रयोगकर्ता नाम भएको खाता पहिले नै छ कि छैन, सर्भरमा अनुरोध पठाउनु बिना। सर्भरमा गरिने थप मान्यतालाई **सर्भर-साइड** मान्यता भनिन्छ। सामान्यतया दुवै कार्यान्वयन गर्न आवश्यक हुन्छ। क्लाइन्ट-साइड मान्यताले प्रयोगकर्तालाई तुरुन्त प्रतिक्रिया दिएर प्रयोगकर्ता अनुभव सुधार गर्छ, तर सर्भर-साइड मान्यता महत्त्वपूर्ण छ ताकि तपाईंले ह्यान्डल गर्ने प्रयोगकर्ता डाटा सही र सुरक्षित होस्। --- ## 🚀 चुनौती यदि प्रयोगकर्ता पहिले नै छ भने 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) प्रयोग गरेर अनुवाद गरिएको छ। हामी शुद्धताको लागि प्रयास गर्छौं, तर कृपया ध्यान दिनुहोस् कि स्वचालित अनुवादमा त्रुटिहरू वा अशुद्धताहरू हुन सक्छ। यसको मूल भाषा मा रहेको मूल दस्तावेज़लाई आधिकारिक स्रोत मानिनुपर्छ। महत्वपूर्ण जानकारीको लागि, व्यावसायिक मानव अनुवाद सिफारिस गरिन्छ। यस अनुवादको प्रयोगबाट उत्पन्न हुने कुनै पनि गलतफहमी वा गलत व्याख्याको लागि हामी जिम्मेवार हुने छैनौं।