HTML forms are a mystery - html

I am taking a Vue.js course and I just learned about forms and managing them(the code is down below). I don't understand how does the tag work. It's value is determined by the option value and the selected text is the text of that specific option? Also, I am confused when it comes to checkboxes and Vue. Why do the checkboxes need different "value"s when you use v-model on that checkbox? Why would I want to create a checkbox group (inputs with the same value for the name attribute)? I don't really understand how v-model works with forms and I would love to. Thanks in advance for the person that's taking time to help me.
The Code
<template>
<form #submit.prevent="submitForm">
<div class="form-control">
<label for="user-name">Your Name</label>
<input id="user-name" name="user-name" type="text" v-model="userName" />
</div>
<div class="form-control">
<label for="age">Your Age (Years)</label>
<input id="age" name="age" type="number" v-model.number="userAge" />
</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>
{{ referrer }}
</div>
<div class="form-control">
<h2>What are you interested in?</h2>
<div>
<input id="interest-news" name="interest" value="news" type="checkbox" v-model="interests"/>
<label for="interest-news">News</label>
</div>
<div>
<input id="interest-tutorials" name="interest" value="tutorials" type="checkbox" v-model="interests"/>
<label for="interest-tutorials">Tutorials</label>
</div>
<div>
<input id="interest-nothing" name="interest" value="nothing" type="checkbox" v-model="interests"/>
<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" value="video" type="radio" v-model="how"/>
<label for="how-video">Video Courses</label>
</div>
<div>
<input id="how-blogs" name="how" value="blogs" type="radio" v-model="how"/>
<label for="how-blogs">Blogs</label>
</div>
<div>
<input id="how-other" name="how" value="other" type="radio" v-model="how"/>
<label for="how-other">Other</label>
</div>
</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>
<div class="form-control">
<select></select>
</div>
</form>
</template>
<script>
export default {
data() {
return {
userName: "",
userAge: null,
referrer: "newspaper",
interests: [],
how: null,
confirm: false
};
},
methods: {
submitForm() {
// console.log("Username: " + this.userName);
// this.userName = "";
// console.log("User age: ");
// console.log(this.userAge);
// console.log(31);
// this.userAge = null;
// console.log("Referrer: " + this.referrer);
// this.referrer = "wom";
// console.log("Checkboxes: ");
// console.log(this.interests);
console.log("Radio Buttons");
console.log(this.how);
this.interests = [];
this.how = null;
// console.log('Confirm? ');
// console.log(this.confirm);
// this.confirm = false;
},
},
};
</script>

v-model is syntactical sugar for :value and #change
Instead of <input v-model="name">, you could use
<input :value="name" #update:model-value="v => name=v"> which would have the same result.
Here is an example that perhaps belabors it a bit.
const app = Vue.createApp({
data() {
return {
name: ""
}
}
})
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
#input="$emit('update:modelValue', $event.target.value)"
>
`
})
app.mount("#app")
<script src="https://unpkg.com/vue#next/dist/vue.global.prod.js"></script>
<div id="app">
<custom-input :value="name" #update:model-value="v => name=v"></custom-input><br />
<custom-input v-model="name"></custom-input><br />
<input :value="name" #update:model-value="v => name=v"><br />
<input v-model="name"><br />
Name: {{name}}
</div>
More info in v3 docs here

Related

How to get the text of selected option instead of value

Here's the body of my html:
<form class="p-3">
<div class="form-group">
<label>Full Name</label>
<input id="inputName" type="text" oninput="Update(this.value, 'namec')"
class="form-control"
placeholder="Robert">
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Contact Number</label>
<input id="inputNumber" type="text" oninput="Update(this.value,
'numberc')" class="form-control"
placeholder="09*********">
</div>
<div class="form-group col-md-6">
<label>Email Address</label>
<input id="inputEmail" type="email" oninput="Update(this.value, 'emailc')"
class="form-control"
placeholder="email#gmail.com">
</div>
</div>
<div class="form-group">
<label>Full Address</label>
<input type="text" class="form-control" placeholder="1234 Main St"
oninput="Update(this.value, 'addressc')">
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Mode of Payment</label>
<select id="inputMOP" class="form-control" oninput="Update(this.value, 'mopc')">
<option selected>Select Payment</option>
<option>GCash</option>
<option>Bank Payment</option>
<option>Cash On Delivery</option>
</select>
</div>
<div class="form-group col-md-6">
<label>Shipping Option</label>
<select id="inputMOD" class="form-control" oninput="Update(this.value,
'modc')">
<option selected>Select Delivery</option>
<option>Standard Delivery</option>
<option>J&T Express</option>
<option>Ninjavan Express</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-8">
<label>Item Name</label>
<select id="inputItem" class="itemInput form-control"
oninput="Update(this.value, 'itemc')">
<option selected>Select Item</option>
<option value="155.00">Hygienix Alcohol 1L</option>
<option value="180.00">Protect Plus Alcohol 1 Gal</option>
<option value="215.00">Guardian Alcohol 1 Gal</option>
</select>
</div>
<div class="form-group col-md-4">
<label>Quantity</label>
<input id="inputQuantity" type="text" oninput="Update(this.value,
'quantityc')"
class="itemQuantity form-control" placeholder="0"><br>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3">
<h6 class="mt-2">Total Price: ₱ </h6>
</div>
<div class="form-group col-md-3">
<input id="itemPrice" type="text" oninput="Update(this.value, 'pricec')"
class="form-control" placeholder="0" readonly>
</div>
<div class="form-group col-md-6">
<button id="placeOrder" class="btn btn-primary btn-block float-
right">Place Order</button>
</div>
</div>
</form>
Jquery to calculate the total price:
<script>
$(document).ready(function () {
$('select.itemInput').on('change', function () {
$('.itemQuantity').text($('#inputQuantity').val(0));
$('.itemQuantity').on('change', function () {
$('#itemPrice').val(
$('#inputItem').val() * $('#inputQuantity').val() + ".00"
);
});
});
});
</script>
Variable declaration to add to the database:
var cName = $('#inputName').val();
var cNumber = $('#inputNumber').val();
var cEmail = $('#inputEmail').val();
var cAddress = $('#inputAddress').val();
var cMop = $('#inputMop').val();
var cMod = $('#inputMod').val();
var cItem = $('#inputItem').find(":selected").text();
var cQuantity = $('#inputQuantity').val();
var cPrice = $('#itemPrice').val();
The problem is that I cant get the text of the selected option from the #inputItem. It only gets the value from the option. Another thing, I can't also get the total price which is under the ID of #itemPrice.
How can I get the text instead of value of #inputItem? Also, the value of #itemPrice?
EDIT:
Finally solved it!! But I have a new problem, I cant add data with a "#gmail.com" but it works when it does not have it. How can I do add data with "#email.com"?
Use the following script for the desired results. Also if you don't have any function to call onChange, kindly remove those from your input fields, from html. They will keep on throwing errors in console.
$(document).ready(function () {
$('.itemInput').on('change', function () {
// tempItemName stores the selected item name
var tempItemName = $('.itemInput option:selected').text();
totalPriceCalc();
});
$('.itemQuantity').on('change', function(){
totalPriceCalc();
});
function totalPriceCalc () {
var tempInputQty = $('#inputQuantity').val();
var tempItemPrice = $('#inputItem option:selected').val();
var tempTotalCost = (tempInputQty * tempItemPrice) + '.00';
$('#itemPrice').val(tempTotalCost);
}
});

How to change input filed border color into red. When fields are empty

Here I have written a code for validating form input fields in Vue. And it is working fine when input fields are empty the form is not navigating to the next step. My issue is that while the field is empty, and the user tries to navigate to the next step, the input field border color should change in red. If one field is empty and the user is trying to navigate another step, the navigation should prevent, and the empty fields' border should be displayed in red.
<div id="vk_app">
<form>
<div v-if="step === 1">
<h1>Step One</h1>
<p>
<legend for="name">Your Name:</legend>
<input id="name" name="name" v-model="name">
<input id="name" name="name" v-model="age">
</p>
<button #click.prevent="next()">Next</button>
</div>
<div v-if="step === 2">
<template>
<input id="name" name="name" v-model="address">
<input id="name" name="name" v-model="h_no">
<input id="name" name="name" v-model="mobile">
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="next()">Next</button>
</template>
</div>
<div v-if="step === 3">
<template>
<input id="name" name="name" v-model="subject">
<input id="name" name="name" v-model="occupation">
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="next()">Next</button>
</template>
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="submit()">Save</button>
</div>
</form>
</div>
vue.js
const app = new Vue({
el:'#vk_app',
data() {
return {
step:1,
name:null,
age:null,
city:null,
state:null,
}
},
methods:{
prev() {
if(this.checkForm()) {
this.step--;
}
},
next() {
if(this.checkForm()) {
this.step++;
}
},
checkForm: function (e) {
if (this.name && this.age) {
return true;
}
this.errors = [];
if (!this.name) {
this.errors.push('Name required.');
}
if (!this.age) {
this.errors.push('Age required.');
}
e.preventDefault();
}
}
});
Here is my answer for your code example, it will work when you click on next button.
Updated HTML and Inputs:
<div id="vk_app">
<form>
<div v-if="step === 1">
<h1>Step One</h1>
<legend for="name">Your Name:</legend>
<input id="name" :class="errorField.name ? 'error-input' : ''" name="name" v-model="name" />
<input id="name" :class="errorField.age ? 'error-input' : ''" name="name" v-model="age" />
<button #click.prevent="next()">Next</button>
</div>
<div v-if="step === 2">
<template>
<input id="name" name="name" :class="errorField.address ? 'error-input' : ''" v-model="address" />
<input id="name" name="name" :class="errorField.h_no ? 'error-input' : ''" v-model="h_no" />
<input id="name" name="name" :class="errorField.mobile ? 'error-input' : ''" v-model="mobile" />
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="next()">Next</button>
</template>
</div>
<div v-if="step === 3">
<template>
<input id="name" name="name" v-model="subject">
<input id="name" name="name" v-model="occupation">
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="next()">Next</button>
</template>
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="submit()">Save</button>
</div>
</form>
</div>
Vue Functions and Data Update:
data() {
return {
errorField: { name: false, age: false, city: false, state: false },
step:1,
name:null,
age:null,
city:null,
state:null,
}
},
methods:{
prev() {
if(this.checkForm()) {
this.step--;
}
},
next() {
if(this.checkForm()) {
this.step++;
}
},
checkForm: function (e) {
if (this.name && this.age) {
return true;
}
this.errors = [];
if (!this.name) {
this.errorField.name = true
this.errors.push('Name required.');
}
if (!this.age) {
this.errorField.age = true
this.errors.push('Age required.');
}
}
}
Since this feature(red border on invalid input) is required more often, we can use dynamic classes :
in style section define a class
.input--error{
border-color:red;
}
and in template section add
:class="{'input--error':!name}"
to input tag making it look like :
<input id="name" name="name" v-model="name" :class="{'input--error':!name}"/>
The whole code would look something like this:
<template>
<div>
<!-- Using dynamic classes -->
<input id="name" name="name" v-model="name" :class="{'input--error':!name}"/>
<input id="name" name="name" v-model="age" :class="{'input--error':!age}"/>
</div>
</template>
<script>
export default {
data(){
return{
name:null,
age:null
}
}
}
</script>
<style scoped>
.input--error{
border-color:red;
}
</style>
We could also add this directly in style attribute in input tag:
<input id="name" name="name" v-model="mobile" :style="!mobile ? 'border-color:red':''">
This would overcrowd the code unnecessarily.
We have a blur event.
When blur event fired, if the input box was empty (or whatever you want), add a class such as "red" to the input box.
<input id="name" name="name" v-model="name" #blur="validation($event.target)">
const validation = el => {
if (!el.value) {
// this is a very simple examples. I don't recommend using jQuery.
$(el).addClass('red');
}
};
Add.
You can use the method on Next() method.
<input id="name" name="name" v-model="name" ref="name">
const next = () => {
const inputName = this.$refs.name; // this if for just Vue2.
if (!inputName.value) {
$(inputName).addClass('red');
}
};

trying to display first and second form at second step

Here I have written a code for multistep form and every thing is working fine here. But here while we are at first step and if we click on next button then next step form will display so here I want to show first step form along with next step form. That means while we click next button from first step then next step should be with first form and second form
<div id="app">
<form>
<div v-if="step === 1">
<h1>Step One</h1>
<p>
<legend for="name">Your Name:</legend>
<input id="name" name="name" v-model="registration.name">
</p>
<p>
<legend for="email">Your Email:</legend>
<input id="email" name="email" type="email" v-model="registration.email">
</p>
<button #click.prevent="next()">Next</button>
</div>
<div v-if="step === 2">
<h1>Step Two</h1>
<p>
<legend for="street">Your Street:</legend>
<input id="street" name="street" v-model="registration.street">
</p>
<p>
<legend for="city">Your City:</legend>
<input id="city" name="city" v-model="registration.city">
</p>
<p>
<legend for="state">Your State:</legend>
<input id="state" name="state" v-model="registration.state">
</p>
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="next()">Next</button>
</div>
<div v-if="step === 3">
<h1>Step Three</h1>
<p>
<legend for="numtickets">Number of Tickets:</legend>
<input id="numtickets" name="numtickets" type="number" v-model="registration.numtickets">
</p>
<p>
<legend for="shirtsize">Shirt Size:</legend>
<select id="shirtsize" name="shirtsize" v-model="registration.shirtsize">
<option value="S">Small</option>
<option value="M">Medium</option>
<option value="L">Large</option>
<option value="XL">X-Large</option>
</select>
</p>
<button #click.prevent="prev()">Previous</button>
<button #click.prevent="submit()">Save</button>
</div>
</form>
vue.js
const app = new Vue({
el:'#app',
data() {
return {
step:1,
registration:{
name:null,
email:null,
street:null,
city:null,
state:null,
numtickets:0,
shirtsize:'XL'
}
}
},
methods:{
prev() {
this.step--;
},
next() {
this.step++;
},
submit() {
alert('Submit to blah and show blah and etc.');
}
}
});
Since step is incremented on each next() call, you could change the conditional rendering to render when the step is at least some index:
<div v-if="step >= 1">...</div>
<div v-if="step >= 2">...</div>
<div v-if="step >= 3">...</div>
demo

how can I fix my inputs which are out of range?

I wanted to fix my html/bootstrap style,but at the moment when I clicked the event all my imputs are out of range as picture number 1 at the moment when I get some input wrong . however I want to fix my inputs and when I click my event and get error from jquery stay on the same place as the picture 2
html
<form id="new_product">
<div class="form-group">
<label for="description">Name: </label>
<input type="text" class="form-control" id="description" name="description" title="product description" required>
</div>
<div class="form-group form-inline">
<div class="form-group">
<div class="col-md-5">
<label for="cost_price">Cost Price: </label>
<input type="text" class="form-control" id="cost_price" name="cost_price" title="cost_price" required>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<label for="selling_price">Selling price: </label>
<input type="text" class="form-control" id="selling_price" name="selling_price" title="selling_price" required>
</div>
</div>
</div>
<div class="form-group form-inline">
<div class="form-group">
<div class="col-md-5">
<label for="wprice">Wholeprice: </label>
<input type="text" class="form-control" id="wprice" name="wprice" title="wprice" required>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<label for="min_stock">Min stock: </label>
<input type="text" class="form-control" id="min_stock" name="min_stock" title="min_stock" required>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<label for="stock">Stock: </label>
<input type="text" class="form-control" id="stock" name="stock" title="stock" required>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<label for="max_stock">Max stock: </label>
<input type="text" class="form-control" id="max_stock" name="max_stock" title="max_stock" required>
</div>
</div>
</div>
</form>
form_view
form_view2
jquery validation
$('#add').on('click',function(){
$("#description").mask("(999) 999-9999");
$("#new_product").validate();
BootstrapDialog.show({
type: BootstrapDialog.TYPE_PRIMARY,
message: function(dialog) {
var $message = $('<div></div>');
var pageToLoad = dialog.getData('pageToLoad');
$message.load(pageToLoad);
return $message;
},
data: {
'pageToLoad': URL_GET_VIEW_PRODUCT
},
closable: false,
buttons:[{
id: 'btn-ok',
cssClass: 'btn-primary',
icon: 'glyphicon glyphicon-send',
label: ' Save',
action: function (e) {
var description = $('#description').val();
var cost_price = $('#cost_price').val();
var selling_price = $('#selling_price').val();
var wprice = $('#wprice').val();
var min_stock = $('#min_stock').val();
var stock = $('#stock').val();
var max_stock = $('#max_stock').val();
if($("#new_product").valid()){
$.ajax({
url: URL_GET_ADD_PRODUCT,
type: 'POST',
data: {description: description, cost_price: cost_price, selling_price: selling_price, wprice: wprice, min_stock: min_stock, stock: stock, max_stock: max_stock}
}).done(function (data) {
console.log(data);
if (data.msg == 'successfully added') {
$('#new_product')[0].reset();
table.ajax.reload();
}else if(data.min_stock == 'el stock no puede ser mayor al min'){
BootstrapDialog.show({
type: BootstrapDialog.TYPE_WARNING,
message: 'el stock no puede ser mayor al min'
});
}
});
return false;
}
}
},{
id: 'btn-cancel',
cssClass: 'btn-danger',
icon: 'glyphicon glyphicon-remove',
label: ' Cancel',
action: function (e) {
e.close();
}
}]
});
});

How to show some input text only when filter is selected in HTML?

I have a HTML like this:
<div class="search">
<input type="text" id="search_text" name="search_text" placeholder="Search by Name ...">
<select>
<option>Filter</option>
<option>By date</option>
<option>By size</option>
</select>
From: <input type="date" id="start_date" name="start_date">
To: <input type="date" id="end_date" name="end_date">
Size:<input type="text" id="size" name="size" placeholder="size">
<input type="submit" onclick="return search()" value="Search">
</div>
I want to show From: and To: only when By date is selected in filter and I want to show "Size" only when By size is selected in filter.
OK, I made an exception and did the coding for you!
Here's a jQuery solution:
Working example: http://jsfiddle.net/khRjq/
<div class="search">
<input type="text" id="search_text" name="search_text" placeholder="Search by Name ...">
<select id="selectmode">
<option value="">Filter...</option>
<option value="date">By date</option>
<option value="size">By size</option>
</select>
<div class="bydateinputs" style="display: none">
From: <input type="date" id="start_date" name="start_date">
To: <input type="date" id="end_date" name="end_date">
</div>
<div class="bysizeinputs" style="display: none">
Size:<input type="text" id="size" name="size" placeholder="size">
</div>
<input type="submit" onclick="return search()" value="Search">
</div>
JS:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
$(function(){
$('#selectmode').change(function()
{
if ($(this).val() == 'date')
{
$('.bydateinputs').show();
$('.bysizeinputs').hide();
}
if ($(this).val() == 'size')
{
$('.bydateinputs').hide();
$('.bysizeinputs').show();
}
});
});
</script>
First, put them into a div.
Filter
By date
By size
From:
To:
Size:
Then use jquery to handle select change event
$("select").change(function() {
if($(this).text == "By date")
{
$("div.size").hide();
$("div.from").show();
$("div.to").show();
}
else if($(this).text == "By size")
{
$("div.size").show();
$("div.from").hide();
$("div.to").hide();
}
else
{
$("div.size").hide();
$("div.from").hide();
$("div.to").hide();
}
});
If you don't want to include jQuery, you can follow this fiddle :
HTML :
<div class="search" id="searchDiv">
<input type="text" id="search_text" name="search_text" placeholder="Search by Name ..."/>
<select onchange="changeSearchType(this)">
<option value="">Filter</option>
<option value="dateinput">By date</option>
<option value="sizeinput">By size</option>
</select>
<div id="dateinput" style="display:none;">
From: <input type="date" id="start_date" name="start_date"/>
To: <input type="date" id="end_date" name="end_date"/>
</div>
<div id="sizeinput" style="display:none;">
Size:<input type="text" id="size" name="size" placeholder="size"/>
</div>
<input type="submit" onclick="return search()" value="Search">
</div>
JavaScript :
function changeSearchType(el){
var e = el.value,
divs = document.getElementById("searchDiv").getElementsByTagName('div');
for(var i = 0, l = divs.length; i < l ; i++){
divs[i].style.display = 'none';
}
if(e != '') document.getElementById(e).style.display = 'block';
}