# बँकिंग अ‍ॅप तयार करा भाग 2: लॉगिन आणि नोंदणी फॉर्म तयार करा ## व्याख्यानपूर्व प्रश्नमंजुषा [व्याख्यानपूर्व प्रश्नमंजुषा](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.mr.png) `
` साठी डीफॉल्ट क्रिया म्हणजे [GET पद्धत](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3) वापरून फॉर्म सध्याच्या सर्व्हर URL वर सबमिट करणे, फॉर्म डेटा थेट 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.mr.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 वापरतो. ही पद्धत 2 पॅरामीटर्स घेते: - सर्व्हरचा 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.mr.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/ > टिप: तुम्ही तुमच्या फॉर्म कंट्रोल्सचा लूक कस्टमाइझ करू शकता, ते वैध आहेत की नाही यावर आधारित, `:valid` आणि `:invalid` CSS प्सूडो-क्लासेस वापरून. ### कार्य नवीन खाते तयार करण्यासाठी दोन फील्ड्स आवश्यक आहेत, युजरनेम आणि चलन, इतर फील्ड्स ऐच्छिक आहेत. फॉर्मच्या HTML मध्ये सुधारणा करा, `required` अॅट्रिब्युट आणि फील्डच्या लेबलमध्ये मजकूर वापरून: ```html ... ``` जरी या विशिष्ट सर्व्हर अंमलबजावणीमध्ये फील्ड्सच्या कमाल लांबीवर विशिष्ट मर्यादा लागू केल्या जात नाहीत, तरीही कोणत्याही युजर टेक्स्ट एंट्रीसाठी वाजवी मर्यादा निश्चित करणे नेहमीच चांगली प्रथा आहे. टेक्स्ट फील्ड्समध्ये `maxlength` अॅट्रिब्युट जोडा: ```html ... ... ``` आता जर तुम्ही *Register* बटण दाबले आणि एखाद्या फील्डने आपण परिभाषित केलेल्या व्हॅलिडेशन नियमांचे पालन केले नाही, तर तुम्हाला असे काहीतरी दिसेल: ![फॉर्म सबमिट करण्याचा प्रयत्न करताना व्हॅलिडेशन एरर दाखवणारा स्क्रीनशॉट](../../../../translated_images/validation-error.8bd23e98d416c22f80076d04829a4bb718e0e550fd622862ef59008ccf0d5dce.mr.png) डेटा सर्व्हरवर पाठवण्यापूर्वी केलेली अशी व्हॅलिडेशन **क्लायंट-साइड** व्हॅलिडेशन म्हणून ओळखली जाते. पण लक्षात ठेवा की सर्व तपासण्या डेटा पाठवल्याशिवाय करणे नेहमी शक्य नसते. उदाहरणार्थ, आम्ही येथे तपासू शकत नाही की याच युजरनेमसह खाते आधीच अस्तित्वात आहे की नाही, सर्व्हरला विनंती पाठवल्याशिवाय. सर्व्हरवर केलेली अतिरिक्त व्हॅलिडेशन **सर्व्हर-साइड** व्हॅलिडेशन म्हणून ओळखली जाते. सामान्यतः दोन्ही अंमलात आणणे आवश्यक असते, आणि क्लायंट-साइड व्हॅलिडेशन वापरल्याने युजरला त्वरित फीडबॅक देऊन युजर अनुभव सुधारतो, तर सर्व्हर-साइड व्हॅलिडेशन हे सुनिश्चित करण्यासाठी महत्त्वाचे आहे की तुम्ही हाताळत असलेला युजर डेटा योग्य आणि सुरक्षित आहे. --- --- ## GitHub Copilot Agent Challenge 🚀 Agent मोड वापरून खालील आव्हान पूर्ण करा: **वर्णन:** नोंदणी फॉर्ममध्ये व्यापक क्लायंट-साइड व्हॅलिडेशन आणि युजर फीडबॅकसह सुधारणा करा. हे आव्हान तुम्हाला फॉर्म व्हॅलिडेशन, एरर हँडलिंग, आणि इंटरॅक्टिव फीडबॅकसह युजर अनुभव सुधारण्याचा सराव करण्यास मदत करेल. **प्रॉम्प्ट:** नोंदणी फॉर्मसाठी संपूर्ण फॉर्म व्हॅलिडेशन सिस्टम तयार करा ज्यामध्ये समाविष्ट आहे: 1) युजर टाइप करत असताना प्रत्येक फील्डसाठी रिअल-टाइम व्हॅलिडेशन फीडबॅक, 2) प्रत्येक इनपुट फील्डखाली कस्टम व्हॅलिडेशन संदेश, 3) पासवर्ड पुष्टीकरण फील्डसह जुळणारे व्हॅलिडेशन, 4) व्हिज्युअल इंडिकेटर्स (जसे की वैध फील्डसाठी हिरवे चेकमार्क आणि अवैध फील्डसाठी लाल चेतावणी), 5) सर्व व्हॅलिडेशन पास झाल्यावरच सक्षम होणारे सबमिट बटण. HTML5 व्हॅलिडेशन अॅट्रिब्युट्स, CSS स्टाइलिंगसाठी, आणि इंटरॅक्टिव बिहेवियरसाठी JavaScript वापरा. ## 🚀 आव्हान जर युजर आधीच अस्तित्वात असेल तर HTML मध्ये एरर संदेश दाखवा. अंतिम लॉगिन पृष्ठ कसे दिसू शकते याचे उदाहरण येथे आहे, थोडे CSS स्टाइलिंग केल्यानंतर: ![CSS स्टाइल्स जोडल्यावर लॉगिन पृष्ठाचा स्क्रीनशॉट](../../../../translated_images/result.96ef01f607bf856aa9789078633e94a4f7664d912f235efce2657299becca483.mr.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) वापरून भाषांतरित करण्यात आला आहे. आम्ही अचूकतेसाठी प्रयत्नशील असलो तरी कृपया लक्षात ठेवा की स्वयंचलित भाषांतरे त्रुटी किंवा अचूकतेच्या अभावाने युक्त असू शकतात. मूळ भाषेतील दस्तऐवज हा अधिकृत स्रोत मानला जावा. महत्त्वाच्या माहितीसाठी व्यावसायिक मानवी भाषांतराची शिफारस केली जाते. या भाषांतराचा वापर करून उद्भवलेल्या कोणत्याही गैरसमज किंवा चुकीच्या अर्थासाठी आम्ही जबाबदार राहणार नाही.