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

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!

Related

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>

Select options based on another option selected

Im trying to select an option when i choose a specific option from list above. Any help how can achieve that?
Print of frontend
The main idea is, when i choose Field_Support, select option "94" from StardardTemplateID
My actual try:
$(document).ready(function () {
setTimeout(function () {
const Action = Core.Config.Get("Action");
const SupportedActions = ["AgentTicketNote"];
if ($.inArray(Action, SupportedActions) !== -1) {
if (Action === "AgentTicketNote") {
$('#DynamicField_QueueNote').on('change', function () {
const Option = $(this).val();
if (Option === '- Move -')
$('#Subject').val('');
else if (Option === 'Field_Support')
$('#Subject').val('Nota para Field');
else if (Option === 'Field_Support')
$("#StandardTemplateID").html("<option value='94'>dados_para_field</option>");
else if (Option === 'Helpdesk')
$('#Subject').val('Nota para Helpdesk');
else if (Option === 'Sistemas_Windows')
$('#Subject').val('Nota para Sistemas');
else if (Option === 'Networking')
$('#Subject').val('Nota para Networking');
});
}
}
})
});
Here's one way. Bake the value associations into the select option elements as data-attributes. Then just reference it on the change event.
$(document).ready(function() {
$('select#DynamicField_QueueNote').change(function() {
$('select#StandardTemplateID').val($(this).find('option:selected').data('link'))
$('#StandardTemplateID_Search').val($('select#StandardTemplateID').find('option:selected').text());
$('#Subject').val($(this).find('option:selected').data('subject'))
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="DynamicFieldText Modernize" id="DynamicField_QueueNote" name="DynamicField_QueueNote" size="1">
<option value="">-</option>
<option value="- Move -" selected="selected">- Move -</option>
<option value="Field_Support" data-link='94' data-subject='Nota para Field'>Field_Support</option>
<option value="Helpdesk" data-link='' data-subject='Nota para Helpdesk'>Helpdesk</option>
<option value="Sistemas_Windows" data-link='' data-subject='Nota para Sistemas'>Sistemas_Windows</option>
</select>
<hr>
<label>Subject</label>
<input type="text" id="Subject" name="Subject" value="" class="W75pc Validate Validate_Required" aria-required="true">
<hr>
<label for="StandardTemplateID">Text Template:</label>
<div class="Field">
<div class="InputField_Container" tabindex="-1">
<div class="InputField_InputContainer"><input id="StandardTemplateID_Search" class="InputField_Search ExpandToBottom" type="text" role="search" autocomplete="off" aria-label="Text Template:" style="width: 273.333px;" aria-expanded="true"></div>
</div>
<select class="Modernize" id="StandardTemplateID" name="StandardTemplateID" style="display: none;">
<option value="">-</option>
<option value="71">1ª_Tentativa_Contacto</option>
<option value="72">2ª_Tentativa_Contacto</option>
<option value="73">3ª_Tentativa_Contacto</option>
<option value="80">Acesso_VPN_atribuido</option>
<option value="94">dados_para_field</option>
</select>
<p class="FieldExplanation">Setting a template will overwrite any text or attachment.</p>
</div>
<!--
<select id='select1'>
<option> Choose...</option>
<option value='option1' data-link='100'> Option 1 (link to 100)</option>
<option value='option2' data-link='133'> Option 2 (link to 133)</option>
<option value='option3' data-link='94'> Option 3 (link to 94)</option>
<option value='option4' data-link='120'> Option 4 (link to 120)</option>
</select>
<select id='select2'>
<option></option>
<option value='94'>Template 94</option>
<option value='100'>Template 100</option>
<option value='120'>Template 120</option>
<option value='133'>Template 133</option>
</select> -->
You can create a conditional that checks the value of the select on change and then sets the value of the input if the value of the select equals the target value.
Using jQuery:
$(document).ready(function() {
$('#StandardTemplate').change(function() {
if ($(this).val() === '94') {
$('#text_template').val($('option[value="94"]').text())
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent">
<select class="Modernize" id="StandardTemplate" name="StandardTemplate">
<option value>-</option>
<option value="71">1_Tentative_Contacto</option>
<option value="72">2_Tentative_Contacto</option>
<option value="73">3_Tentative_Contacto</option>
<option value="80">Accesso_VPN_atibuido</option>
<option value="94">dadios_para_field</option>
</select>
<label for="text_template">Text Template: <input name="text_template" id="text_template"></label>
</div>
Using Vanilla JS:
const sel = document.getElementById('StandardTemplate')
const input = document.getElementById('text_template')
sel.addEventListener('change', e => {
if(e.target.value === '94'){
document.getElementById('text_template').value = document.querySelector('option[value="94"]').textContent
}
})
<div id="parent">
<select class="Modernize" id="StandardTemplate" name="StandardTemplate">
<option value>-</option>
<option value="71">1_Tentative_Contacto</option>
<option value="72">2_Tentative_Contacto</option>
<option value="73">3_Tentative_Contacto</option>
<option value="80">Accesso_VPN_atibuido</option>
<option value="94">dadios_para_field</option>
</select>
<label for="text_template">Text Template: <input name="text_template" id="text_template"></label>
</div>

Change the colours of a button on the basis of the selected values in React

I am new to the react js. I have a form which is a normal form , using simple bootstrap 3 forms. Here, I have two select
<form className="form-inline text-center row" role="form">
<div className="col-xs-4">
<div className="form-group col-xs-12">
<label className="control-label">company/project</label>
<select id="company" className="form-control" onChange={(event, newValue) => this.setState({ company: event.target.value, hasUserFilledCompany: true })}>
<option disabled selected value>None Selected</option>
<option>abc</option>
<option>pqr</option>
<option>xyz</option>
<option>cdcdc</option>
<option>abcd</option>
</select>
</div>
</div>
<div className="col-xs-4">
<div className="form-group col-xs-12">
<label>Select Technology</label>
<select id="Technology" className="form-control" onChange={(event, newValue) => this.setState({ Technology: event.target.value, hasUserFilledTech: true })}>
<option disabled selected value>None Selected</option>
<option>qwe</option>
<option>gahs</option>
<option>cdbcdbhcd</option>
<option>cdcdc</option>
<option>cdcbdc</option>
</select>
</div>
</div>
<div className="col-xs-4">
<div className="form-group col-xs-12" style={jobUpload}>
<div className="row">
<label>Job Description</label>
<button type="button" className={"btn " + ((this.state.hasUserFilledTech && this.state.hasUserFilledCompany) ? 'enable-Button' : 'jd-button')} onClick={(event) => this.createJob(event)}>Add/Paste</button>
<span style={or}>Or</span>
<button type="button" className="btn jd-button">Upload File</button>
</div>
</div>
</div>
</form>
Now, Here, what I want to do is that is user selects value from the select then buttons colour will get changed and also it will enabled. for this, my solution is I have use two variables on select as a state variable and if this becomes true then I am applying condition classes to this buttons.
This is working, But I don't think this is a proper solution to validate a form . How can I do this?
This is how you can do this. A few good practise would be how you implement onChange function in select. You repeat a bit there. Notice how I destructured the event in onChange function. And You don't need another variable you can just check !!company && company.length > 0.
Here is the demo https://codesandbox.io/s/30yj7mrq4q
class App extends React.Component {
state = {
company: "",
tech: ""
}
onChange = ({ target: { name, value } }) => {
this.setState({ [name]: value });
}
render() {
const { tech, company } = this.state;
const enabled = (!!tech && tech.length > 0) && (!!company && company.length > 0)
return (
<div>
<div>
<label> Company </label>
<select name="company" onChange={this.onChange}>
<option disabled selected value>None Selected</option>
<option> Google </option>
<option> Facebook </option>
<option> Microsoft </option>
</select>
</div>
<div>
<label> Tech </label>
<select name="tech" onChange={this.onChange}>
<option disabled selected value>None Selected</option>
<option> React </option>
<option> Angular </option>
<option> Vue </option>
</select>
</div>
<div>
<button className={`btn ${enabled ? "enabled" : "disabled"} `} disabled={!enabled}>Upload File</button>
</div>
</div>
)
}
}

Scroll to div when input has been completed

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>

Assign value of radio button based on dynamic number of user selected values

After a user makes his/her selections of the five select dropdowns, I want to set the value of a radio button from field "radio_btn_name" based on up to 3 of the users selections. Think of each object as a "rule". If a combination of selections matches that rule, give "radio_btn_x" the "output" value.
In Part 1 of my question I achieved my desired result when the number of "selected_option_names_" is equal to the number of select dropdowns. However, I need to be able to check for a dynamic number of dropdowns against only up to 3 user selections.
I imagine the solution will be drastically different from part 1, as a result I feel a new question is warranted.
JSFiddle
$(document).ready(function() {
// A successful solution would render all these rules true, radio_button_4,
// radio_button_8 and radio_button_1 would get their respective new values
var objs = [{
selected_option_name_1: "select_1",
selected_option_name_2: "",
selected_option_name_3: "",
selected_option_value_1: "1-1",
selected_option_value_2: "",
selected_option_value_3: "",
radio_btn_name: "radio_button_4",
output: "5000-R"
}, {
selected_option_name_1: "select_1",
selected_option_name_2: "select_2",
selected_option_name_3: "select_5",
selected_option_value_1: "1-1",
selected_option_value_2: "2-2",
selected_option_value_3: "5-2",
output: "10000-R",
radio_btn_name: "radio_button_8"
}, {
selected_option_name_1: "select_4",
selected_option_name_2: "",
selected_option_name_3: "",
selected_option_value_1: "4-1",
selected_option_value_2: "",
selected_option_value_3: "",
output: "15000-R",
radio_btn_name: "radio_button_1"
}];
// Solution for part 1. Will only work if number of dropdowns == "selected_option_name_"
$("#submit").on("click", function() {
$("#wrapper").find("input[type='radio']").each(function(i, o) {
var btn = $(this);
var btn_name = $(this).attr("name");
$.each(objs, function(index, rule) {
if (btn_name == rule.radio_btn_name) {
if(rule.selected_option_value_1 == $('#select_1').val()
&& rule.selected_option_value_2 == $('#select_2').val()
&& rule.selected_option_value_3 == $('#select_3').val()) {
btn.val(rule.output);
console.log(rule.output);
}
}
});
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div>
<select class="group_1" name="select_1">
<option value=""></option>
<option value="1-1">Dropdown 1-1</option>
<option value="1-2">Dropdown 1-2</option>
<option value="1-3">Dropdown 1-3</option>
</select>
</div>
<br>
<div>
<input type="radio" name="radio_button_1" value="r()">
<input type="radio" name="radio_button_2" value="o()">
<input type="radio" name="radio_button_3" value="n()">
</div>
<div>
<select class="group_1" name="select_2">
<option value=""></option>
<option value="2-1">Dropdown 2-1</option>
<option value="2-2">Dropdown 2-2</option>
<option value="2-3">Dropdown 2-3</option>
</select>
</div>
<br>
<div>
<input type="radio" name="radio_button_4" value="r()">
<input type="radio" name="radio_button_5" value="o()">
<input type="radio" name="radio_button_6" value="n()">
</div>
<div>
<select class="group_1" name="select_3">
<option value=""></option>
<option value="3-1">Dropdown 3-1</option>
<option value="3-2">Dropdown 3-2</option>
<option value="3-3">Dropdown 3-3</option>
</select>
</div>
<br>
<div>
<input type="radio" name="radio_button_7" value="r()">
<input type="radio" name="radio_button_8" value="o()">
<input type="radio" name="radio_button_9" value="n()">
</div>
<br>
<div>
<select class="group_1" name="select_4">
<option value=""></option>
<option value="4-1">Dropdown 4-1</option>
<option value="4-2">Dropdown 4-2</option>
<option value="4-3">Dropdown 4-3</option>
</select>
</div>
<br>
<div>
<input type="radio" name="radio_button_10" value="r()">
<input type="radio" name="radio_button_11" value="o()">
<input type="radio" name="radio_button_12" value="n()">
</div>
<br>
<div>
<select class="group_1" name="select_5">
<option value=""></option>
<option value="5-1">Dropdown 5-1</option>
<option value="5-2">Dropdown 5-2</option>
<option value="5-3">Dropdown 5-3</option>
</select>
</div>
<br>
<button id="submit">Submit</button>
</div>
It turns out the solution wasn't as far off as I thought. I just needed to add an input type hidden with name equal to empty string to account for any empty strings in my objects.
I also updated my jQuery to find the value of names vs id's from part one of my post.
Updated fiddle
$(document).ready(function() {
$("#submit").on("click", function() {
$("#wrapper").find("input[type='radio']").each(function(i, o) {
var btn = $(this);
var btn_name = $(this).attr("name");
$.each(objs, function(index, rule) {
if (btn_name == rule.radio_btn_name) {
if(rule.selected_option_value_1 == $('[name="'+rule.selected_option_name_1 + '"]').val()
&& rule.selected_option_value_2 == $('[name="'+rule.selected_option_name_2 + '"]').val()
&& rule.selected_option_value_3 == $('[name="'+rule.selected_option_name_3 + '"]').val()) {
btn.val(rule.output);
console.log(rule.output);
}
}
});
});
});
});
<div>
<input type="hidden" name="" value="">
<button id="submit">Submit</button>
</div>

Categories