From b4849707f7cd990a76061f4fa4bf71b66cae0f76 Mon Sep 17 00:00:00 2001
From: Cristiano Magro <cristiano.magro@vola.it>
Date: Wed, 08 Jan 2025 13:01:02 +0100
Subject: [PATCH] v-model on Custom Components

---
 11 - Forms/xno-forms-01-starting-setup/src/components/TheForm.vue |  196 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 196 insertions(+), 0 deletions(-)

diff --git a/11 - Forms/xno-forms-01-starting-setup/src/components/TheForm.vue b/11 - Forms/xno-forms-01-starting-setup/src/components/TheForm.vue
new file mode 100644
index 0000000..1e80ce5
--- /dev/null
+++ b/11 - Forms/xno-forms-01-starting-setup/src/components/TheForm.vue
@@ -0,0 +1,196 @@
+<template>
+  <form @submit.prevent="submitForm">
+    <div class="form-control" :class="{ invalid: usernameValidity === 'invalid' }">
+      <label for="user-name">Your Name</label>
+      <input id="user-name" name="user-name" type="text" v-model.trim="userName" @blur="validateInput" />
+      <p v-if="usernameValidity === 'invalid'">please enter a valid name</p>
+    </div>
+    <div class="form-control">
+      <label for="age">Your Age (Years)</label>
+      <input id="age" name="age" type="number" v-model="userAge" ref="inputAge" />
+    </div>
+    <div class="form-control">
+      <label for="referrer">How did you hear about us?</label>
+      <select id="referrer" name="referrer" v-model="referrer">
+        <option value="google">Google</option>
+        <option value="wom">Word of mouth</option>
+        <option value="newspaper">Newspaper</option>
+      </select>
+    </div>
+    <div class="form-control">
+      <h2>What are you interested in?</h2>
+      <div>
+        <input id="interest-news" name="interest" type="checkbox" value="news" v-model="interest" />
+        <label for="interest-news">News</label>
+      </div>
+      <div>
+        <input id="interest-tutorials" name="interest" type="checkbox" value="tutorials" v-model="interest" />
+        <label for="interest-tutorials">Tutorials</label>
+      </div>
+      <div>
+        <input id="interest-nothing" name="interest" type="checkbox" value="nothing" v-model="interest" />
+        <label for="interest-nothing">Nothing</label>
+      </div>
+    </div>
+    <div class="form-control">
+      <h2>How do you learn?</h2>
+      <div>
+        <input id="how-video" name="how" type="radio" value="video" v-model="how" />
+        <label for="how-video">Video Courses</label>
+      </div>
+      <div>
+        <input id="how-blogs" name="how" type="radio" value="blogs" v-model="how" />
+        <label for="how-blogs">Blogs</label>
+      </div>
+      <div>
+        <input id="how-other" name="how" type="radio" value="other" v-model="how" />
+        <label for="how-other">Other</label>
+      </div>
+    </div>
+
+    <div class="form-control">
+      <rating-control v-model="rating"></rating-control>
+    </div>
+
+    <div class="form-control">
+      <input type="checkbox" id="confirm-terms" name="confirm-terms" v-model="confirm">
+      <label for="confirm-terms">Agree to terms of use?</label>
+    </div>
+    <div>
+      <button>Save Data</button>
+    </div>
+  </form>
+</template>
+
+<script>
+import RatingControl from './RatingControl.vue';
+
+export default {
+  components: {
+    RatingControl,
+  },
+  data() {
+    return {
+      userName: '',
+      userAge: null,
+      referrer: 'wom',
+      interest: [],
+      how: null,
+      confirm: false,
+      usernameValidity: 'pending',
+      rating: null,
+    }
+  },
+  methods: {
+    submitForm() {
+      console.log('Username: ' + this.userName);
+      this.userName = '';
+      console.log('User age: ');
+      console.log(this.userAge); //number
+      console.log(this.$refs.inputAge.value);  //string
+      console.log(18);
+      this.userAge = null;
+
+      console.log('referrer: ' + this.referrer);
+      this.referrer = 'wom';
+
+      console.log('Checkbox: ');
+      console.log(this.interest);
+      console.log('- Radio buttons: ');
+      console.log(this.how);
+      this.interest = [];
+      this.how = null;
+
+      console.log('- Confirm:');
+      console.log(this.confirm);
+      this.confirm = false;
+
+      console.log('- Rating:');
+      console.log(this.rating);
+      this.rating = null;
+
+    },
+    validateInput() {
+      if (this.userName === '') {
+        this.usernameValidity = 'invalid';
+      } else {
+        this.usernameValidity = 'valid';
+      }
+    },
+  }
+
+}
+</script>
+
+<style scoped>
+form {
+  margin: 2rem auto;
+  max-width: 40rem;
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
+  padding: 2rem;
+  background-color: #ffffff;
+}
+
+.form-control {
+  margin: 0.5rem 0;
+}
+
+.form-control.invalid input {
+  border-color: red;
+}
+
+.form-control.invalid label {
+  color: red;
+}
+
+
+label {
+  font-weight: bold;
+}
+
+h2 {
+  font-size: 1rem;
+  margin: 0.5rem 0;
+}
+
+input,
+select {
+  display: block;
+  width: 100%;
+  font: inherit;
+  margin-top: 0.5rem;
+}
+
+select {
+  width: auto;
+}
+
+input[type='checkbox'],
+input[type='radio'] {
+  display: inline-block;
+  width: auto;
+  margin-right: 1rem;
+}
+
+input[type='checkbox']+label,
+input[type='radio']+label {
+  font-weight: normal;
+}
+
+button {
+  font: inherit;
+  border: 1px solid #0076bb;
+  background-color: #0076bb;
+  color: white;
+  cursor: pointer;
+  padding: 0.75rem 2rem;
+  border-radius: 30px;
+}
+
+button:hover,
+button:active {
+  border-color: #002350;
+  background-color: #002350;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0