Scroll to div when input has been completed - javascript

I have a form with three steps and want to
achieve an effect that when the user completes each step, the next step scrolls up into view.
How can I achieve this? I am using VUEJS 2.5.2. I have removed some HTML to keep it cleaner and clearer.
Can anyone help with a solution?
My code so far is:
<template>
<div id="app">
<form action="" method="post">
<div id="step1" v-show="quote.location === 'home'">
<select v-model="brand">
<option value="" selected disabled hidden>Select brand</option>
<option v-for="(car, index) in cars">{{ index }}</option>
</select>
<select v-model="model">
<option value="" selected disabled hidden>Select model</option>
<option v-for="option in cars[brand]" :value="option.prize">{{ option.prize }}</option>
</select>
</div><!--/step1-->
<div id="step2" v-show="brand && model != ''">
<h2><span class="text">Do you need an installer?</span></h2>
<div class="location">
<div class="selection">
<input type="radio" id="yesInstaller" name="yesInstaller" value="Yes" v-model="quote.installer">
<label for="yesInstaller">Yes</label>
</div>
<div class="selection">
<input type="radio" id="noInstaller" name="noInstaller" value="No" v-model="quote.installer">
<label for="noInstaller">No</label>
</div>
</div>
</div><!--/step2-->
<div id="step3" v-show="quote.installer != ''">
<h2><span class="text">Right on! Here’s an overview of your selection.</span></h2>
</div><!--/step2-->
</form>
</template>
<script>
export default {
name: 'Quote',
data () {
return {
totalSteps: 4,
currentStep: 1,
show: true,
brand: '',
model: '',
cars: {
'BMW': [ { size:'1', prize:'BMW i3' }, { size:'2',prize:'BMW i8' }, { size:'3',prize:'BMW 740e' } ],
'AUDI': [ { size:'1', prize:'Audi A3 E-Tron' },{ size:'2', prize:'Audi Q7 E-Tron' } ],
'Chevrolet': [ { size: '1', prize:'Chevrolet Bolt'}, {size:'1', prize:'Chevrolet Volt' } ],
'Fiat': [ { size: '1', prize:'Fiat 500e'}]
}
}
}
}
</script>

Related

handle checkbox to update its value in edit operation in functional component

I am working on checkbox where if we checkbox is checked then a dropdown should be displayed. I have tried it but neither its value is not getting updated nor dropdown is shown/hidden when checkbox is checked/unchecked.
I have tried below:
const [recursive, setRecursive] = useState(false);
const [recursiveType, setRecursiveType] = useState("");
const [formState, setFormState] = useState({
title: "",
trainingDesc: "",
category: "",
trainingOn:"",
recursive:false,
recursiveType:""
});
const addTraining = (e) => {
e.preventDefault();
if (!editMode) {
const trainingObj = {
id: uuid(),
title: formState.title,
trainingDesc: formState.trainingDesc,
category: formState.category,
trainingOn: trainingDate,
recursive: (formState.recursive) ? 1 : 0,
recursiveType: recursiveType,
dateTime: new Date().getTime()
}
dispatchRedux(createTraining(trainingObj));
}
else {
dispatchRedux(updateTraining(formState, id));
}
navigate('/trainings');
}
Checkbox code:
<form onSubmit={addTraining}>
--------------------
--------------------
<label htmlFor="recursive">Recursive</label>
<input type="checkbox" name="recursive" id="recursive" checked={formState.recursive} onChange={()=>setRecursive(recursive=>!recursive)} />
{ (formState.recursive) &&
<div className="col-4 form-group" style={{marginLeft:'-16px'}}>
<label htmlFor="recursiveType">Recursive Type</label>
<select name="recursiveType" onChange={(e)=>setRecursiveType(e.target.value)} value={formState.recursiveType} className="form-control" id="category" required>
<option value="">Select</option>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
</select>
</div> }
</form>
My problem here is when I click on checkbox and then checkbox is checked/unchecked then dropdown is not getting shown/hidden. Any help would be appreciated.Thanks.
you need to change your code with this one :
<input type="checkbox" name="recursive" id="recursive" checked={formState.recursive}
onClick={()=>setFormState({...formState, recursive:!formState.recursive})} />
{formState.recursive && <div className="col-4 form-group" style={{marginLeft:'-16px'}}>
<label htmlFor="recursiveType">Recursive Type</label>
<select name="recursiveType" onChange={(e)=>setRecursiveType(e.target.value)} value={formState.recursiveType} className="form-control" id="category" required>
<option value="">Select</option>
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
</select>
</div> }
Works for me :)
Have a nice day!

How to automatically select the first option in a dropdown menu in Vue 3

I have 2 dropdown menus, the second one changes values depending on the selection of the first dropdown.
All I want to do is set the first value of the second dropdown to be selected by default no matter what the option in the first dropdown is.
At the moment, the default selection of the second dropdown is always empty.
I tried fetching the values from types and loading them via v-for on the option tag and setting :selected="index===0" but it didn't work either.
Demo: https://codesandbox.io/s/relaxed-flower-2hjox1?file=/src/App.vue
The Template
<div class="col-md-6">
<label for="type" class="form-label">Type</label>
<select id="type" class="form-select" v-model="form.type">
<option value="en-US" selected>English (US)</option>
<option value="en-GB">English (British)</option>
</select>
</div>
<div class="col-md-6">
<label for="selected" class="form-label">Option 2</label>
<div v-if="form.type === 'en-GB'">
<select id="selected" name="selected" class="form-select" v-model="form.selected">
<option value="Arsenal">Arsenal</option>
<option value="Chelsea">Chelsea</option>
<option value="Liverpool">Liverpool</option>
</select>
</div>
<div v-else-if="form.type === 'en-US'">
<select id="selected" name="selected" class="form-select" v-model="form.selected">
<option value="Lakers">Lakers</option>
<option value="Bulls">Bulls</option>
<option value="Mavericks">Mavericks</option>
</select>
</div>
</div>
Javascript
export default {
name: "App",
data() {
return {
form: {
type: 'en-GB',
selected: ''
},
types: {
american: ['Lakers', 'Bulls', 'Mavericks'],
british: ['Arsenal', 'Liverpool', 'Chelsea']
}
}
},
};
const app = Vue.createApp({
data() {
return {
form: {
type: "en-GB",
selected: "",
},
types: {
american: ["Lakers", "Bulls", "Mavericks"],
british: ["Arsenal", "Liverpool", "Chelsea"],
},
};
},
watch: {
'form.type': {
handler() {
this.form.selected = this.form.type === "en-GB" ? this.types.british[0] : this.types.american[0]
},
immediate: true
}
}
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<div class="col-md-6">
<label for="type" class="form-label">Type</label>
<select id="type" class="form-select" v-model="form.type">
<option value="en-US" selected>English (US)</option>
<option value="en-GB">English (British)</option>
</select>
</div>
<div class="col-md-6">
<label for="selected" class="form-label">Option 2</label>
<div v-if="form.type === 'en-GB'">
<select
id="selected"
name="selected"
class="form-select"
v-model="form.selected"
>
<option value="Arsenal">Arsenal</option>
<option value="Chelsea">Chelsea</option>
<option value="Liverpool">Liverpool</option>
</select>
</div>
<div v-else-if="form.type === 'en-US'">
<select
id="selected"
name="selected"
class="form-select"
v-model="form.selected"
>
<option value="Lakers">Lakers</option>
<option value="Bulls">Bulls</option>
<option value="Mavericks">Mavericks</option>
</select>
</div>
</div>
</div>
You can create watcher and set default values for second select:
watch: {
'form.type': {
handler() {
this.form.selected = this.form.type === "en-GB" ? this.types.british[0] : this.types.american[0]
},
immediate: true
}
}
All I want to do is set the first value of the second dropdown to be
selected by default no matter what the option in the first dropdown
is.
Add a watcher, which watches form.type, then pick the first item from types
Note, I've changed american key to the key your using for type, then you can loop over the options, if you don't have that in place you'll need mapping object anyway typeMap: {'en-US': 'american', 'en-GB': 'british' } ... types[typeMap[form.type]]
new Vue({
el: '#app',
data() {
return {
form: {
type: 'en-GB',
selected: ''
},
types: {
'en-US': ['Lakers', 'Bulls', 'Mavericks'],
'en-GB': ['Arsenal', 'Liverpool', 'Chelsea']
}
}
},
watch: {
'form.type' () {
this.form.selected = this.types[this.form.type][0]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>
<div id="app">
<div class="col-md-6">
<label for="type" class="form-label">Type</label>
<select id="type" class="form-select" v-model="form.type">
<option value="en-US" selected>English (US)</option>
<option value="en-GB">English (British)</option>
</select>
</div>
<div class="col-md-6">
<label for="selected" class="form-label">Option 2</label>
<select id="selected" name="selected" class="form-select" v-model="form.selected">
<option v-for="name in types[form.type]">{{ name }}</option>
</select>
</div>
</div>

Adding select fields dynamically and validation in VueJS

I am adding select fields using VueJS & it's working fine, but I want to add validation.
If the user selects 8mm in the first select then 8mm will disabled in other select tags.
Here is HTML & Vue JS code
<div class="form-group" v-for="(input,k) in inputs" :key="k">
<select v-model="input.thickness" name="thickness-`${k}`" class="basicRate block w-full p-3 mt-2 text-gray-700 bg-gray-200 appearance-none focus:outline-none focus:bg-gray-300 focus:shadow-inner" required>
<option disabled selected value> -- Select thickness -- </option>
<option value="8">8mm</option>
<option value="10">10mm</option>
<option value="12">12mm</option>
<option value="16">16mm</option>
<option value="20">20mm</option>
<option value="25">25mm</option>
</select>
<input type="text" class="form-control" v-model="input.qty">
<span>
<i class="fas fa-minus-circle" #click="remove(k)" v-show="k || ( !k && inputs.length > 1)"></i>
<i class="fas fa-plus-circle" #click="add(k)" v-show="k == inputs.length-1"></i>
</span>
</div>
var app = new Vue({
el: "#app",
data: {
inputs: [
{
thickness:'',
qty: ''
}
]
},
methods: {
add(index) {
this.inputs.push({ thickness: '', qty: '' });
},
remove(index) {
this.inputs.splice(index, 1);
}
}
});
As you see the first two drop-downs have the same value meaning the user can select the same values. I'm looking for simple validation where if the user selects some option then he or she won't select the same value in other dropdowns.
Thanks in advance.
You could use an array of each selects' value. Just update the array whenever the change event is fired and conditionally add the disabled attribute based on these values:
var app = new Vue({
el: "#app",
data: {
thicknesses: [],
inputs: [{
thickness: '',
qty: ''
},
{
thickness: '',
qty: ''
},
{
thickness: '',
qty: ''
},
{
thickness: '',
qty: ''
},
]
},
methods: {
handleChange(e) {
this.thicknesses = [...this.$refs.selects.children].map(select => {
return select.children[0].value;
})
},
add(index) {
this.inputs.push({
thickness: '',
qty: ''
});
},
remove(index) {
this.inputs.splice(index, 1);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" ref="selects">
<div class="form-group" v-for="(input,k) in inputs" :key="k">
<select v-model="input.thickness" name="thickness-`${k}`" required #input="handleChange($event)">
<option disabled selected value> -- Select thickness -- </option>
<option value="8" :disabled="thicknesses.includes('8')">8mm</option>
<option value="10" :disabled="thicknesses.includes('10')">10mm</option>
<option value="12" :disabled="thicknesses.includes('12')">12mm</option>
<option value="16" :disabled="thicknesses.includes('16')">16mm</option>
<option value="20" :disabled="thicknesses.includes('20')">20mm</option>
<option value="25" :disabled="thicknesses.includes('25')">25mm</option>
</select>
</div>
</div>

HTML <select> conditional tag

I have a simple form that allows users to add clients and their locations (country, state, and city). There seems to be a problem in the code that causes the drop-down form fields to remain in place when the country is switched. For example, if the user selects China, followed by any Province, and then any city, and then switches the country, the drop--down for city still remains. This can be seen in the code snippet.
function displayCountry(answer) {
document.getElementById(answer).style.display = "block";
if (answer == "China") {
document.getElementById("India").style.display = "none";
document.getElementById("USA").style.display = "none";
} else if (answer == "India") {
document.getElementById("China").style.display = "none";
document.getElementById("USA").style.display = "none";
} else if (answer == "USA") {
document.getElementById("China").style.display = "none";
document.getElementById("India").style.display = "none";
}
}
function displayProvince(answer) {
document.getElementById(answer).style.display = "block";
if (answer == "Beijing Municipality") {
document.getElementById("Tianjin Municipality").style.display = "none";
} else if (answer == "Tianjin Municipality") {
document.getElementById("Beijing Municipality").style.display = "none";
}
}
function displayChinaCity(answer) {
document.getElementById(answer).style.display = "block";
if (answer == "Beijing") {
document.getElementById("Dongcheng").style.display = "none";
} else if (answer == "Dongcheng") {
document.getElementById("Beijing").style.display = "none";
}
}
<div class="container">
<h3>Add Client</h3>
<div class="tab-content">
<form action="/add/clients" method="post">
<div class="top-row">
<div class="field-wrap">
<label>Client ID<span class="req">*</span><input></label>
</div>
</div>
<div class="top-row">
<div class="field-wrap">
<label>Client name<span class="req">*</span><input></label>
</div>
</div>
<div class="field-wrap">
<label>Client type<span class= "req">*</span><select></select></label>
</div>
<div class="field-wrap">
<label>Client Origin<span class="req">*</span>
<select name="country" onchange="displayCountry(this.value)">
<option selected= "--">--</option>
<option value= "China" >China</option>
<option value= "India" >India</option>
<option value= "USA" >USA</option>
</select>
</label>
<div id="USA" style="display:none;">
<select></select>
</div>
<div id="China" style="display:none;"><br/>
Select Province<span class="req">*</span>
<select name="province" onchange="displayProvince(this.value)">
<option selected= "--">--</option>
<option value= "Beijing Municipality" >Beijing Municipality</option>
<option value= "Tianjin Municipality">Tianjin Municipality</option>
</select>
</div>
<div id="India" style="display:none;">
<select></select>
</div>
<div id="Beijing Municipality" style="display:none;"><br/>
Select City<span class="req">*</span>
<select name="city" onchange="displayChinaCity(this.value)">
<option selected= "--">--</option>
<option value= "Beijing">Beijing</option>
<option value= "Dongcheng">Dongcheng</option>
</select>
</div>
</div>
</form>
</div>
</div>
This is another approach to your problem. Instead of creating all select tags in HTML by hand, I'm making them with a function buildForms and using a data structure to keep all countries/states/cities in one place. I'm using the buildSelect function to produce all select tags and the functions updateStates and updateCities to hide/show the elements.
var data = {
countries: [{
name: 'China',
childs: [{
name: 'Beijing',
childs: [{name: 'Beijing'}, {name: 'Dongcheng'}]
}, {
name: 'Tianjin',
childs: [{name: 'Guangzhou'}, {name: 'Shanghai'}]
}]
}, {
name: 'India',
childs: [{
name: 'Uttar',
childs: [{name: 'Kanpur'}, {name: 'Ghaziabad'}]
}, {
name: 'Maharashtra',
childs: [{name: 'Mumbai'}, {name: 'Pune'}]
}]
}, {
name: 'USA',
childs: [{
name: 'Washington',
childs: [{name: 'Washington'}, {name: 'Seatle'}]
}, {
name: 'Florida',
childs: [{name: 'Orlando'}, {name: 'Miamy'}]
}]
}]
};
function buildSelect(name, data, childs) {
var div = $('<div>');
div.addClass('hidden autoSelect ' + data.name + ' ' + name);
var label = $('<label>');
label.text(name);
var select = $('<select>');
var option = $('<option>');
option.text('--');
select.append(option);
data.childs.forEach(function (child) {
option = $('<option>');
option.val(child.name);
option.text(child.name);
select.append(option);
});
if (childs) select.on('change', updateCities);
label.append(select);
div.append(label);
$('.country').append(div);
}
function buildForms(data) {
data.countries.forEach(function (country) {
buildSelect('State', country, true);
country.childs.forEach(function (state) {
buildSelect('City', state);
});
});
}
function hideAutoSelect (name) {
$('div.autoSelect.'+name).addClass('hidden');
}
function updateStates() {
var v = this.value;
if (v) {
hideAutoSelect('State');
hideAutoSelect('City');
var div = $('div.autoSelect.'+v);
div.removeClass('hidden');
var select = $('select', div);
if (select.val()) $('div.autoSelect.'+select.val()).removeClass('hidden');
}
}
function updateCities() {
var v = $(this).val();
if (v) {
hideAutoSelect('City');
$('div.autoSelect.'+v).removeClass('hidden');
}
}
$(document).on('ready',function () {
buildForms(data);
$('[name=country]').on('change', updateStates);
});
.hidden {display: none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h3>Add Client</h3>
<div class="tab-content">
<form action="/add/clients" method="post">
<div class="top-row">
<div class="field-wrap">
<label>Client ID<span class="req">*</span>
<input placeholder="0000000">
</label>
</div>
</div>
<div class="top-row">
<div class="field-wrap">
<label>Client name<span class="req">*</span>
<input placeholder="John">
</label>
</div>
</div>
<div class="field-wrap">
<label>Client type<span class= "req">*</span>
<select>
<option selected= "--">--</option>
</select>
</label>
</div>
<div class="field-wrap country">
<label>Client Origin<span class="req">*</span>
<select name="country">
<option selected= "--">--</option>
<option value= "China" >China</option>
<option value= "India" >India</option>
<option value= "USA" >USA</option>
</select>
</label>
</div>
</form>
</div>
</div>

How to clear radio button on select box value change? VueJS2

I'm a newbie to JavaScript/VueJS and I need some help on clearing all radio inputs when a select box value (office code) is changed.
Here's my HTML/view code:
<div id="app">
<form id="myForm'>
<select id="office" v-model="selectedOffice" required>
<option value="" selected disabled>-Select-</option>
<option v-for="office in officeList" :value="office">{{office.code}}</option>
</select>
<section v-if="selectedOffice !== ''">
<h2>Please specify your product type:</h2>
<div id="productsList>
<label>
<input type="radio" name="productType" id="book" v-model="selectedProductType"> BOOKS
</label>
<label>
<input type="radio" name="productType" id="magazines" v-model="selectedProductType"> MAGAZINES
</label>
....snipped...
</form>
</div>
My model:
var vm = new Vue({
el: '#app',
data: {
selectedOffice: '',
selectedProductType: '',
officeList: [
{ code: 'Office1' }, {code: 'Office2' }, ...snipped...
]
I thought maybe I'd do create a method in the Vue instance like so:
methods: {
clearRadio: function(){
productType.prop('checked', false);
}
}
...but I am unsure how to implement that to the view (assuming that's the best way to do this) on office value change.
Thanks for any help!
You can do this using
#change
<template>
.....
<select #change="clearType" id="office" v-model="selectedOffice" required>
<option value="" selected disabled>-Select-</option>
<option v-for="office in officeList" :value="office">{{office.code}}</option>
</select>
.....
</template>
<script>
.....
methods: {
clearType: function(){
this.selectedProductType = ''
}
}
.....
</script>

Categories