You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/el/7-bank-project/2-forms
Lee Stott 2daab5271b
Update Quiz Link
3 weeks ago
..
README.md Update Quiz Link 3 weeks ago
assignment.md 🌐 Update translations via Co-op Translator 4 weeks ago

README.md

Δημιουργία Εφαρμογής Τραπεζικής Μέρος 2: Δημιουργία Φόρμας Σύνδεσης και Εγγραφής

Κουίζ πριν το μάθημα

Κουίζ πριν το μάθημα

Εισαγωγή

Σχεδόν σε όλες τις σύγχρονες διαδικτυακές εφαρμογές, μπορείτε να δημιουργήσετε έναν λογαριασμό για να έχετε τον δικό σας προσωπικό χώρο. Καθώς πολλοί χρήστες μπορούν να έχουν πρόσβαση σε μια εφαρμογή ταυτόχρονα, χρειάζεστε έναν μηχανισμό για να αποθηκεύετε τα προσωπικά δεδομένα κάθε χρήστη ξεχωριστά και να επιλέγετε ποια πληροφορία θα εμφανίζεται. Δεν θα καλύψουμε πώς να διαχειρίζεστε την ταυτότητα του χρήστη με ασφάλεια, καθώς είναι ένα εκτενές θέμα από μόνο του, αλλά θα διασφαλίσουμε ότι κάθε χρήστης θα μπορεί να δημιουργήσει έναν (ή περισσότερους) τραπεζικούς λογαριασμούς στην εφαρμογή μας.

Σε αυτό το μέρος, θα χρησιμοποιήσουμε φόρμες HTML για να προσθέσουμε σύνδεση και εγγραφή στην εφαρμογή μας. Θα δούμε πώς να στέλνουμε δεδομένα σε έναν διακομιστή API προγραμματιστικά και, τελικά, πώς να ορίσουμε βασικούς κανόνες επικύρωσης για τις εισόδους των χρηστών.

Προαπαιτούμενα

Πρέπει να έχετε ολοκληρώσει το μάθημα Πρότυπα HTML και δρομολόγηση της εφαρμογής. Επίσης, πρέπει να έχετε εγκαταστήσει το Node.js και να εκτελέσετε το API διακομιστή τοπικά, ώστε να μπορείτε να στέλνετε δεδομένα για τη δημιουργία λογαριασμών.

Σημείωση Θα χρειαστεί να έχετε δύο τερματικά ανοιχτά ταυτόχρονα, όπως αναφέρεται παρακάτω:

  1. Για την κύρια τραπεζική εφαρμογή που δημιουργήσαμε στο μάθημα Πρότυπα HTML και δρομολόγηση
  2. Για το API διακομιστή της τραπεζικής εφαρμογής που μόλις ρυθμίσαμε παραπάνω.

Πρέπει να έχετε και τους δύο διακομιστές σε λειτουργία για να προχωρήσετε με το υπόλοιπο μάθημα. Ακούνε σε διαφορετικές θύρες (θύρα 3000 και θύρα 5000), οπότε όλα θα λειτουργούν κανονικά.

Μπορείτε να ελέγξετε αν ο διακομιστής λειτουργεί σωστά εκτελώντας αυτήν την εντολή σε ένα τερματικό:

curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result

Φόρμα και στοιχεία ελέγχου

Το στοιχείο <form> περιλαμβάνει μια ενότητα ενός εγγράφου HTML όπου ο χρήστης μπορεί να εισάγει και να υποβάλει δεδομένα μέσω διαδραστικών στοιχείων ελέγχου. Υπάρχουν διάφορα στοιχεία διεπαφής χρήστη (UI) που μπορούν να χρησιμοποιηθούν μέσα σε μια φόρμα, με πιο συνηθισμένα τα στοιχεία <input> και <button>.

Υπάρχουν πολλοί διαφορετικοί τύποι του <input>. Για παράδειγμα, για να δημιουργήσετε ένα πεδίο όπου ο χρήστης μπορεί να εισάγει το όνομα χρήστη του, μπορείτε να χρησιμοποιήσετε:

<input id="username" name="username" type="text">

Η ιδιότητα name θα χρησιμοποιηθεί ως όνομα ιδιότητας όταν τα δεδομένα της φόρμας σταλούν. Η ιδιότητα id χρησιμοποιείται για να συσχετίσει μια <label> με το στοιχείο ελέγχου της φόρμας.

Ρίξτε μια ματιά στη λίστα με όλους τους τύπους <input> και άλλα στοιχεία ελέγχου φόρμας για να πάρετε μια ιδέα για όλα τα εγγενή στοιχεία UI που μπορείτε να χρησιμοποιήσετε κατά την κατασκευή της διεπαφής σας.

Σημειώστε ότι το <input> είναι ένα κενό στοιχείο στο οποίο δεν πρέπει να προσθέσετε αντίστοιχη ετικέτα κλεισίματος. Μπορείτε, ωστόσο, να χρησιμοποιήσετε τη μορφή αυτοκλεισίματος <input/>, αλλά δεν είναι απαραίτητο.

Το στοιχείο <button> μέσα σε μια φόρμα είναι λίγο ιδιαίτερο. Αν δεν ορίσετε την ιδιότητα type, θα υποβάλει αυτόματα τα δεδομένα της φόρμας στον διακομιστή όταν πατηθεί. Εδώ είναι οι δυνατές τιμές για την ιδιότητα type:

  • submit: Η προεπιλογή μέσα σε μια <form>, το κουμπί ενεργοποιεί την ενέργεια υποβολής της φόρμας.
  • reset: Το κουμπί επαναφέρει όλα τα στοιχεία ελέγχου της φόρμας στις αρχικές τους τιμές.
  • button: Δεν εκχωρεί καμία προεπιλεγμένη συμπεριφορά όταν πατηθεί το κουμπί. Μπορείτε στη συνέχεια να εκχωρήσετε προσαρμοσμένες ενέργειες χρησιμοποιώντας JavaScript.

Εργασία

Ας ξεκινήσουμε προσθέτοντας μια φόρμα στο πρότυπο login. Θα χρειαστούμε ένα πεδίο για το όνομα χρήστη και ένα κουμπί Σύνδεσης.

<template id="login">
  <h1>Bank App</h1>
  <section>
    <h2>Login</h2>
    <form id="loginForm">
      <label for="username">Username</label>
      <input id="username" name="user" type="text">
      <button>Login</button>
    </form>
  </section>
</template>

Αν παρατηρήσετε προσεκτικά, θα δείτε ότι προσθέσαμε επίσης ένα στοιχείο <label> εδώ. Τα στοιχεία <label> χρησιμοποιούνται για να προσθέσουν ένα όνομα στα στοιχεία ελέγχου UI, όπως το πεδίο ονόματος χρήστη. Οι ετικέτες είναι σημαντικές για την αναγνωσιμότητα των φορμών σας, αλλά προσφέρουν και πρόσθετα οφέλη:

  • Με τη συσχέτιση μιας ετικέτας με ένα στοιχείο ελέγχου φόρμας, βοηθάτε τους χρήστες που χρησιμοποιούν τεχνολογίες υποβοήθησης (όπως αναγνώστες οθόνης) να κατανοήσουν ποια δεδομένα πρέπει να παρέχουν.
  • Μπορείτε να κάνετε κλικ στην ετικέτα για να εστιάσετε απευθείας στο συσχετισμένο πεδίο, διευκολύνοντας την πρόσβαση σε συσκευές με οθόνη αφής.

Η προσβασιμότητα στον ιστό είναι ένα πολύ σημαντικό θέμα που συχνά παραβλέπεται. Χάρη στα σημασιολογικά στοιχεία HTML, δεν είναι δύσκολο να δημιουργήσετε προσβάσιμο περιεχόμενο αν τα χρησιμοποιήσετε σωστά. Μπορείτε να διαβάσετε περισσότερα για την προσβασιμότητα για να αποφύγετε κοινά λάθη και να γίνετε υπεύθυνος προγραμματιστής.

Τώρα θα προσθέσουμε μια δεύτερη φόρμα για την εγγραφή, ακριβώς κάτω από την προηγούμενη:

<hr/>
<h2>Register</h2>
<form id="registerForm">
  <label for="user">Username</label>
  <input id="user" name="user" type="text">
  <label for="currency">Currency</label>
  <input id="currency" name="currency" type="text" value="$">
  <label for="description">Description</label>
  <input id="description" name="description" type="text">
  <label for="balance">Current balance</label>
  <input id="balance" name="balance" type="number" value="0">
  <button>Register</button>
</form>

Χρησιμοποιώντας την ιδιότητα value, μπορούμε να ορίσουμε μια προεπιλεγμένη τιμή για ένα συγκεκριμένο πεδίο εισόδου. Παρατηρήστε επίσης ότι το πεδίο εισόδου για το balance έχει τον τύπο number. Φαίνεται διαφορετικό από τα άλλα πεδία; Δοκιμάστε να αλληλεπιδράσετε μαζί του.

Μπορείτε να περιηγηθείτε και να αλληλεπιδράσετε με τις φόρμες χρησιμοποιώντας μόνο το πληκτρολόγιο; Πώς θα το κάνατε αυτό;

Υποβολή δεδομένων στον διακομιστή

Τώρα που έχουμε μια λειτουργική διεπαφή χρήστη, το επόμενο βήμα είναι να στείλουμε τα δεδομένα στον διακομιστή. Ας κάνουμε μια γρήγορη δοκιμή χρησιμοποιώντας τον τρέχοντα κώδικα: τι συμβαίνει αν κάνετε κλικ στο κουμπί Σύνδεση ή Εγγραφή;

Παρατηρήσατε την αλλαγή στη διεύθυνση URL του προγράμματος περιήγησης;

Στιγμιότυπο οθόνης της αλλαγής URL του προγράμματος περιήγησης μετά το κλικ στο κουμπί Εγγραφή

Η προεπιλεγμένη ενέργεια για μια <form> είναι να υποβάλει τη φόρμα στη διεύθυνση URL του τρέχοντος διακομιστή χρησιμοποιώντας τη μέθοδο GET, προσθέτοντας τα δεδομένα της φόρμας απευθείας στη διεύθυνση URL. Ωστόσο, αυτή η μέθοδος έχει ορισμένα μειονεκτήματα:

  • Τα δεδομένα που αποστέλλονται είναι πολύ περιορισμένα σε μέγεθος (περίπου 2000 χαρακτήρες).
  • Τα δεδομένα είναι άμεσα ορατά στη διεύθυνση URL (όχι ιδανικό για κωδικούς πρόσβασης).
  • Δεν λειτουργεί με μεταφορτώσεις αρχείων.

Γι' αυτό μπορείτε να την αλλάξετε ώστε να χρησιμοποιεί τη μέθοδο POST, η οποία στέλνει τα δεδομένα της φόρμας στον διακομιστή στο σώμα του αιτήματος HTTP, χωρίς κανέναν από τους προηγούμενους περιορισμούς.

Ενώ η POST είναι η πιο συχνά χρησιμοποιούμενη μέθοδος για την αποστολή δεδομένων, σε ορισμένα συγκεκριμένα σενάρια είναι προτιμότερο να χρησιμοποιείται η μέθοδος GET, όπως για την υλοποίηση ενός πεδίου αναζήτησης.

Εργασία

Προσθέστε τις ιδιότητες action και method στη φόρμα εγγραφής:

<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">

Τώρα δοκιμάστε να εγγραφείτε με το όνομά σας. Μετά το κλικ στο κουμπί Εγγραφή, θα πρέπει να δείτε κάτι σαν αυτό:

Παράθυρο προγράμματος περιήγησης στη διεύθυνση localhost:5000/api/accounts, που εμφανίζει μια συμβολοσειρά JSON με δεδομένα χρήστη

Αν όλα πάνε καλά, ο διακομιστής θα απαντήσει στο αίτημά σας με μια JSON απόκριση που περιέχει τα δεδομένα του λογαριασμού που δημιουργήθηκε.

Δοκιμάστε να εγγραφείτε ξανά με το ίδιο όνομα. Τι συμβαίνει;

Υποβολή δεδομένων χωρίς ανανέωση της σελίδας

Όπως πιθανώς παρατηρήσατε, υπάρχει ένα μικρό πρόβλημα με την προσέγγιση που μόλις χρησιμοποιήσαμε: όταν υποβάλλουμε τη φόρμα, βγαίνουμε από την εφαρμογή μας και το πρόγραμμα περιήγησης ανακατευθύνεται στη διεύθυνση URL του διακομιστή. Προσπαθούμε να αποφύγουμε όλες τις ανανεώσεις σελίδων στην εφαρμογή μας, καθώς δημιουργούμε μια Εφαρμογή Μίας Σελίδας (SPA).

Για να στείλουμε τα δεδομένα της φόρμας στον διακομιστή χωρίς να αναγκάσουμε την ανανέωση της σελίδας, πρέπει να χρησιμοποιήσουμε κώδικα JavaScript. Αντί να βάζετε μια διεύθυνση URL στην ιδιότητα action ενός στοιχείου <form>, μπορείτε να χρησιμοποιήσετε οποιονδήποτε κώδικα JavaScript που ξεκινά με τη συμβολοσειρά javascript: για να εκτελέσετε μια προσαρμοσμένη ενέργεια. Χρησιμοποιώντας αυτό, σημαίνει επίσης ότι θα πρέπει να υλοποιήσετε ορισμένες εργασίες που προηγουμένως γίνονταν αυτόματα από το πρόγραμμα περιήγησης:

  • Ανάκτηση των δεδομένων της φόρμας.
  • Μετατροπή και κωδικοποίηση των δεδομένων της φόρμας σε κατάλληλη μορφή.
  • Δημιουργία του αιτήματος HTTP και αποστολή του στον διακομιστή.

Εργασία

Αντικαταστήστε την ιδιότητα action της φόρμας εγγραφής με:

<form id="registerForm" action="javascript:register()">

Ανοίξτε το app.js και προσθέστε μια νέα συνάρτηση με όνομα register:

function register() {
  const registerForm = document.getElementById('registerForm');
  const formData = new FormData(registerForm);
  const data = Object.fromEntries(formData);
  const jsonData = JSON.stringify(data);
}

Εδώ ανακτούμε το στοιχείο της φόρμας χρησιμοποιώντας το getElementById() και χρησιμοποιούμε τον βοηθό FormData για να εξάγουμε τις τιμές από τα στοιχεία ελέγχου της φόρμας ως ένα σύνολο ζευγών κλειδιού/τιμής. Στη συνέχεια, μετατρέπουμε τα δεδομένα σε ένα κανονικό αντικείμενο χρησιμοποιώντας το Object.fromEntries() και τελικά τα σειριοποιούμε σε JSON, μια μορφή που χρησιμοποιείται συνήθως για την ανταλλαγή δεδομένων στον ιστό.

Τα δεδομένα είναι τώρα έτοιμα να σταλούν στον διακομιστή. Δημιουργήστε μια νέα συνάρτηση με όνομα createAccount:

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 εδώ. Αυτό σημαίνει ότι η συνάρτηση περιέχει κώδικα που θα εκτελεστεί ασύγχρονα. Όταν χρησιμοποιείται μαζί με τη λέξη-κλειδί await, επιτρέπει την αναμονή για την εκτέλεση ασύγχρονου κώδικα - όπως η αναμονή για την απόκριση του διακομιστή εδώ - πριν συνεχίσει.

Ακολουθεί ένα σύντομο βίντεο για τη χρήση του async/await:

Async και Await για τη διαχείριση υποσχέσεων

🎥 Κάντε κλικ στην εικόνα παραπάνω για ένα βίντεο σχετικά με το async/await.

Χρησιμοποιούμε το API fetch() για να στείλουμε δεδομένα JSON στον διακομιστή. Αυτή η μέθοδος παίρνει 2 παραμέτρους:

  • Τη διεύθυνση URL του διακομιστή, οπότε βάζουμε ξανά το //localhost:5000/api/accounts εδώ.
  • Τις ρυθμίσεις του αιτήματος. Εκεί ορίζουμε τη μέθοδο σε POST και παρέχουμε το body για το αίτημα. Καθώς στέλνουμε δεδομένα JSON στον διακομιστή, πρέπει επίσης να ορίσουμε την κεφαλίδα Content-Type σε application/json, ώστε ο διακομιστής να γνωρίζει πώς να ερμηνεύσει το περιεχόμενο.

Καθώς ο διακομιστής θα απαντήσει στο αίτημα με JSON, μπορούμε να χρησιμοποιήσουμε το await response.json() για να αναλύσουμε το περιεχόμενο JSON και να επιστρέψουμε το αποτέλεσμα ως αντικείμενο. Σημειώστε ότι αυτή η μέθοδος είναι ασύγχρονη, οπότε χρησιμοποιούμε τη λέξη-κλειδί await εδώ πριν επιστρέψουμε, για να διασφαλίσουμε ότι τυχόν σφάλματα κατά την ανάλυση θα πιαστούν επίσης.

Τώρα προσθέστε λίγο κώδικα στη συνάρτηση register για να καλέσετε το createAccount():

const result = await createAccount(jsonData);

Επειδή χρησιμοποιούμε τη λέξη-κλειδί await εδώ, πρέπει να προσθέσουμε τη λέξη-κλειδί async πριν από τη συνάρτηση register:

async function register() {

Τέλος, ας προσθέσουμε μερικά logs για να ελέγξουμε το αποτέλεσμα. Η τελική συνάρτηση θα πρέπει να μοιάζει με αυτή:

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);
}

Ήταν λίγο μακρύ, αλλά τα καταφέραμε! Αν ανοίξετε τα εργαλεία προγραμματιστή του προγράμματος περιήγησης και δοκιμάσετε να εγγραφείτε σε

Συμβουλή: μπορείτε να προσαρμόσετε την εμφάνιση των στοιχείων ελέγχου της φόρμας σας ανάλογα με το αν είναι έγκυρα ή όχι, χρησιμοποιώντας τις ψευδο-κλάσεις CSS :valid και :invalid.

Εργασία

Υπάρχουν 2 απαιτούμενα πεδία για τη δημιουργία ενός έγκυρου νέου λογαριασμού, το όνομα χρήστη και το νόμισμα, ενώ τα υπόλοιπα πεδία είναι προαιρετικά. Ενημερώστε το HTML της φόρμας, χρησιμοποιώντας τόσο το χαρακτηριστικό required όσο και το κείμενο στην ετικέτα του πεδίου ώστε να:

<label for="user">Username (required)</label>
<input id="user" name="user" type="text" required>
...
<label for="currency">Currency (required)</label>
<input id="currency" name="currency" type="text" value="$" required>

Αν και αυτή η συγκεκριμένη υλοποίηση του διακομιστή δεν επιβάλλει συγκεκριμένα όρια στο μέγιστο μήκος των πεδίων, είναι πάντα καλή πρακτική να ορίζονται λογικά όρια για οποιαδήποτε εισαγωγή κειμένου από τον χρήστη.

Προσθέστε ένα χαρακτηριστικό maxlength στα πεδία κειμένου:

<input id="user" name="user" type="text" maxlength="20" required>
...
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
...
<input id="description" name="description" type="text" maxlength="100">

Τώρα, αν πατήσετε το κουμπί Εγγραφή και κάποιο πεδίο δεν πληροί έναν από τους κανόνες επικύρωσης που ορίσαμε, θα πρέπει να δείτε κάτι σαν αυτό:

Στιγμιότυπο οθόνης που δείχνει το σφάλμα επικύρωσης όταν προσπαθείτε να υποβάλετε τη φόρμα

Η επικύρωση όπως αυτή που πραγματοποιείται πριν σταλούν δεδομένα στον διακομιστή ονομάζεται επικύρωση από την πλευρά του πελάτη (client-side validation). Αλλά σημειώστε ότι δεν είναι πάντα δυνατό να πραγματοποιηθούν όλοι οι έλεγχοι χωρίς την αποστολή δεδομένων. Για παράδειγμα, δεν μπορούμε να ελέγξουμε εδώ αν υπάρχει ήδη λογαριασμός με το ίδιο όνομα χρήστη χωρίς να στείλουμε ένα αίτημα στον διακομιστή. Πρόσθετη επικύρωση που πραγματοποιείται στον διακομιστή ονομάζεται επικύρωση από την πλευρά του διακομιστή (server-side validation).

Συνήθως, και οι δύο τύποι επικύρωσης πρέπει να υλοποιούνται. Ενώ η χρήση επικύρωσης από την πλευρά του πελάτη βελτιώνει την εμπειρία του χρήστη παρέχοντας άμεση ανατροφοδότηση, η επικύρωση από την πλευρά του διακομιστή είναι κρίσιμη για να διασφαλιστεί ότι τα δεδομένα του χρήστη που επεξεργάζεστε είναι έγκυρα και ασφαλή.


🚀 Πρόκληση

Εμφανίστε ένα μήνυμα σφάλματος στο HTML αν ο χρήστης υπάρχει ήδη.

Ακολουθεί ένα παράδειγμα για το πώς μπορεί να μοιάζει η τελική σελίδα σύνδεσης μετά από λίγη μορφοποίηση:

Στιγμιότυπο οθόνης της σελίδας σύνδεσης μετά την προσθήκη στυλ CSS

Κουίζ μετά το μάθημα

Κουίζ μετά το μάθημα

Ανασκόπηση & Αυτομελέτη

Οι προγραμματιστές έχουν γίνει πολύ δημιουργικοί στις προσπάθειές τους για τη δημιουργία φορμών, ειδικά όσον αφορά τις στρατηγικές επικύρωσης. Μάθετε για διαφορετικές ροές φορμών κοιτάζοντας το CodePen. Μπορείτε να βρείτε κάποιες ενδιαφέρουσες και εμπνευσμένες φόρμες;

Εργασία

Διαμορφώστε την εφαρμογή της τράπεζάς σας


Αποποίηση ευθύνης:
Αυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης Co-op Translator. Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτοματοποιημένες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.