How to display the components based on category selection - html

Here I have written a Vue.js code. So here I have multiple templates so for multiple templates I have written multiple components.
So now I have to display each components based on selected category.
For example in the select option if i select single family homes then step2 component should display if i select real state then step3 components should displayed.
And also how to display the entered value in preview page
*vuejs*
<script>
Vue.component(
'step1',
{
template: '#step1',
props: [
'currentStep',
'step1'
]
}
);
Vue.component(
'step2',
{
template: '#step2',
props: [
'currentStep',
'step2'
]
}
);
Vue.component(
'step3',
{
template: '#step3',
props: [
'currentStep',
'step1',
'step2'
]
}
);
Vue.component(
'step4',
{
template: '#step4',
props: [
'currentStep',
'step1',
'step2'
]
}
);
var app = new Vue(
{
el: '#app',
data: {
currentStep: 1,
step1: {
category: '',
title: '',
address: '',
city:'',
state:'',
Zip:'',
price:'',
description:'',
},
step2: {
bedrooms_p: '',
bathrooms_p: '',
square_ft_p: '',
lot_size_p: '',
total_rooms_p: '',
stories_p: '',
year_built_p: '',
h_o_a_p: '',
garages_p: '',
basement_p: '',
roof_p: '',
exterior_p: '',
cooling_p: '',
heating_p: '',
schools_p: '',
image_p: '',
image2_p: '',
image3_p: '',
image4_p: '',
},
},
ready: function() {
console.log('ready');
},
methods: {
goToStep: function(step) {
this.currentStep ++;
},
stepsback: function(step) {
this.currentStep --;
},
}
}
);
</script>
<select>
<option>single family homes</option>
<option>real state</option>
<option>IT industry</option>
</select>

Here is the solution, although it has arbitrary values, as your example code is not complete.
<step1
currentStep="some_value"
step1="another_value"
v-if="'step1' === select_value"
/>
<step2
currentStep="some_value"
step2="another_value"
v-if="'step2' === select_value"
/>
<step3
currentStep="some_value"
step1="another_value"
step2="yet_another_value"
v-if="'step3' === select_value"
/>
<step4
currentStep="some_value"
step1="another_value"
step2="yet_another_value"
v-if="'step4' === select_value"
/>
The variable select_value is the selected value of the select element in your HTML. To use it you have to bind the value of the select in the Vue model.
For example you could use inside your Vue app something like that:
var app = new Vue(
{
el: '#app',
data: function () {
return {
select_value: ''
// rest of your data properties
}
}
// rest of your component functionality
}
);
and then change your select element to something like that:
<select v-model="select_value">
<option value="step1">single family homes</option>
<option value="step2">real state</option>
<option value="step3">IT industry</option>
<option value="step4">Some Other Option</option>
</select>
By making those changes you will have at the end the result you need.

Try out to give a value to your options then using dynamic component :
<select v-model="select_value">
<option value="1">single family homes</option>
<option value="2">real state</option>
<option value="3">IT industry</option>
<option value="4">Some Other Option</option>
</select>
and :
<component currentStep="some_value" step1="another_value" step2="yet_another_value" :is="`step${select_value}`" />

Related

React - value of select element not changing with state change

Im working on a project where when creating a user i have to pick city,institution and department. When you pick city you get a list of institution that are in that city and when you pick institutions you get departments. What i want to achieve is when you pick another city, institution and department reset to default value. And the problem is that it doesn't work.
Here is the code:
<select
autoComplete="off"
name="institution"
value={caregiverState.institution}
onChange={(e) => {
handleChange(e);
handleDepartmentQuery(e);
}}
>
{institutions.map((institution: IInstitution, index: number): ReactElement => {
return (
<option key={index} value={institution._id}>
{institution.name}
</option>
);
})}
<option value="" selected disabled hidden>
Select institution
</option>
</select>
This is state and handleChange method:
const [caregiverState, setCaregiverState] = useState<ICaregiver>({
name: '',
description: '',
email: '',
city: '',
institution: '',
department: '',
role: 'caregiver',
});
const handleChange = (e): void => {
switch (e) {
case e.target.name === 'city':
return setCaregiverState({
...caregiverState,
institution: '',
department: '',
});
case e.target.name === 'institution':
return setCaregiverState({
...caregiverState,
department: '',
});
default:
return setCaregiverState({
...caregiverState,
[e.target.name]: e.target.value,
});
}
};
Problem is even if i change state to "" select element does't change it to :
<option value="" selected disabled >
Select institution
</option>
I actually get the firstinstitution from map()
Thanks in advance!

ReactJS problem with defaulting value on select tag

Trying to set the default value on a select tag in a react component but I cannot get it to work:
const ComboBox = (props) => {
const options = [
{ id: 1, value: "SHOES" },
{ id: 2, value: "SOCKS" },
{ id: 3, value: "SHIRTS" },
{ id: 4, value: "BELTS" }
];
return (
<React.Fragment>
<label htmlFor={props.id}>{props.label}</label>
<select id={props.id} value={props.selected} onChange={props.changeHandler}>
{options.map((row, ndx) => (
<option key={ndx} value={row.id}>{row.value}</option>
))}
</select>
</React.Fragment>
);
};
Always selects the first option in the list.
Provided an example of the behavior here: CodeSandBox
Pls replace below code. use value={props.value} not props.selected
<select
id={props.id}
value={props.value}
onChange={props.changeHandler}
>
{options.map((row, ndx) => (
<option key={ndx} disable={ndx === 0 ? "true" : false} value={row.id}>
{row.value}
</option>
))}
</select>
You are trying to set default value to 1 then you can do it using usestate in react.
here is the code.
import React, { useState } from "react";
import "./styles.css";
const ComboBox = (props) => {
const options = [
{ id: 1, value: "SHOES" },
{ id: 2, value: "SOCKS" },
{ id: 3, value: "SHIRTS" },
{ id: 4, value: "BELTS" }
];
return (
<React.Fragment>
<label htmlFor={props.id}>{props.label}</label>
<select id={props.id} value={props.value} onChange={props.changeHandler}>
{options.map((row, ndx) => (
<option key={ndx} value={row.id}>
{row.value}
</option>
))}
</select>
</React.Fragment>
);
};
export default function App() {
const [selectedValue, setSelectedValue] = useState(1);
const comboHandler = (e) => setSelectedValue(e.target.value);
return (
<div className="App">
<ComboBox
id="test"
name="test"
value={selectedValue}
changeHandler={comboHandler}
></ComboBox>
<div>
<h2>Value Should Be {selectedValue}</h2>
</div>
</div>
);
}
Just note the default usestate value is the first one
const [selectedValue, setSelectedValue] = useState(1);
You can change the value inside useState(here) to make the default selected value.

Applying HTML formatting to React this.setstate

I have an event handler which updates state when a button is clicked which then renders the state to the page. The way this is rendered is not correct and is breaking my UI. My question is, Is it possible to apply formatting directly to the following event handler?
I have attempted to create a nested array so only 1 state is updated but no joy.
see this video for formatting issue I am having: https://www.screencast.com/t/HksUkk7g3G
I have also posted previously about this with the full code here.
React Nested Array
handleAddTelephone = () => {
this.setState({
telephoneType: this.state.telephoneType.concat([{ name: "" }]),
telephone: this.state.telephone.concat([{ name: "" }])
});
};
I need to format each state update. Something like...
handleAddTelephone = () => {
this.setState({
<span>telephoneType: this.state.telephoneType.concat([{ name: "" }])</span>,
<span>telephone: this.state.telephone.concat([{ name: "" }])</span>
});
};
This is my render function. The call to state needs to be around the MDBRow (Bootstrap row class). JSX will not allow this and Im currently using 2 separate calls, one for telephoneType and another for telephone.
<MDBRow className="grey-text no-gutters my-2">
{this.state.telephoneType.map((tt, ttidx) => (
<MDBCol key={ttidx} md="4" className="mr-2">
<select
defaultValue={tt.name}
onChange={this.handleTelephoneTypeChange(ttidx)}
className="browser-default custom-select">
<option value="Mobile">Mobile</option>
<option value="Landline">Landline</option>
<option value="Work">Work</option>
</select>
</MDBCol>
))}
{this.state.telephone.map((tn, tnidx) => (
<MDBCol key={tnidx} md="7" className="d-flex align-items-center">
<input
value={tn.name}
onChange={this.handleTelephoneChange(tnidx)}
placeholder={`Telephone No. #${tnidx + 1}`}
className="form-control"
/>
<MDBIcon icon="minus-circle"
className="mr-0 ml-2 red-text"
onClick={this.handleRemoveTelephone(tnidx)} />
</MDBCol>
))}
</MDBRow>
and the button...
<div className="btn-add" onClick={this.handleAddTelephone}>
<MDBIcon className="mr-1" icon="plus-square" />Add Telephone</div>
<br />
and array...
class InstallerAdd extends React.Component {
constructor() {
super();
this.state = {
role: "Installer",
name: "",
/* telephone: {
type: [{ name: "" }],
number: [{ name: "" }]
}, */
telephoneType: [{ name: "" }],
telephone: [{ name: "" }],
emailType: [{ email: "" }],
email: [{ email: "" }]
};
}

Populate select options based on another select with Vue and JSON

Need help creating a dynamic search form with select options for Districts, Regions and locations.
Regions select must be populated based on the District and Locations based on the Regions
The data is stored on a JSON file with the following structure:
[
{
"level": 1,
"code": 1,
"name": "District"
},
{
"level": 2,
"code": 101,
"name": "Region"
},
{
"level": 3,
"code": 10101,
"name": "Location"
}
]
here´s the complete JSON file:
https://gist.github.com/tomahock/a6c07dd255d04499d8336237e35a4827
html snippet
<select name="district" v-model="district">
<option value=''>Select District</option>
<option v-for="district in filterDistricts" :value="district.code">
{{ district.name }}
</option>
</select>
<select name="region" v-model="region">
<option value=''>Select Region</option>
<option v-for="region in filterRegions" :value="region.code">
{{ region.name }}
</option>
</select>
<select name="location" v-model="location">
<option value=''>Select Location</option>
<option v-for="location in filterLocations" :value="location.code">
{{ location.name }}
</option>
</select>
javascript snippet
data() {
return {
searchData: [],
districts: [],
regions: [],
locations: []
}
},
created(){
this.fetchData();
},
computed: {
filterDistricts() {
return this.districts = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 1)
},
filterRegions() {
return this.regions = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 2)
},
filterLocations() {
return this.locations = this.searchData.map(res => ({
level: res.level,
code: res.code,
name: res.name
}))
.filter( res => res.level === 3)
}
},
methods: {
fetchData(){
axios.get('http://localhost:8000/json/searchData.json')
.then((response) => (
this.searchData = response.data
))
.catch((err) => {
console.log(err)
})
}
}
I think I need to associate de code numbers, but I can´t figure out how.
Any ideas?
Thanks
First, I wouldn't bother with those map calls since you're only reproducing the same structure.
Second, I'll assume that each sub-element (region / location) relates to its parent (district / region) via a pattern where each sub's code is prefixed with the parent code, followed by a two-digits, zero-padded.
With that in mind, try this in your computed properties
filterDistricts () {
return this.searchData.filter(({ level }) => level === 1)
},
filterRegions () {
// assuming you don't want any selections until a district is chosen
if (!this.district) return []
const codeCheck = new RegExp(`^${this.district}\\d{2}$`)
return this.searchData.filter(({ level, code }) =>
level === 2 && codeCheck.test(code))
},
filterLocations () {
if (!this.region) return []
const codeCheck = new RegExp(`^${this.region}\\d{2}$`)
return this.searchData.filter(({ level, code }) =>
level === 3 && codeCheck.test(code))
}
Extra notes...
From looking at your template, it seems you should initialise your data as
data () {
return {
searchData: [],
district: null,
region: null,
location: null
}
}
Computed properties don't need to be stored in data properties so you don't need districts, regions and locations.
Your label options should also be disabled so they cannot be selected, eg
<option disabled value="">Select Region</option>

Default selected checkbox

I want to ask about how I can set option to be default selected?
<form [formGroup]="form2">
<select formControlName="drop">
<option disabled>Choose one</option>
<option *ngFor="let example of examples" [value]="example.id" [disabled]="example.isDisabled" [selected]="example.isSelected">{{ example.name }}</option>
</select>
</form>
Component:
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormControl, Validators } from '#angular/forms';
#Component({
selector: 'app-drop-down-list',
templateUrl: './drop-down-list.component.html',
styleUrls: ['./drop-down-list.component.css']
})
export class DropDownListComponent implements OnInit {
public form = new FormGroup({
drop: new FormControl('',
Validators.required,
),
});
public form2 = new FormGroup({
drop: new FormControl('',
Validators.required,
),
});
examples = [{
id: 1, name: 'Test1', isSelected: false, isDisabled: true,
},
{
id: 2, name: 'Test2', isSelected: true, isDisabled: false,
},
{
id: 3, name: 'Test3', isDisabled: false,
}
];
constructor() { }
ngOnInit() {
}
onSubmit(form) {
console.log(form);
}
}
I was searching on stack but I don't want to mix reactive forms with ngModel, also I don't wan't to use patchValue because It only set default value without choosing element in list. Thanks for help!
if you want option to be selected then do like this , just pass id value in your formcontrol intialization
public form2 = new FormGroup({
drop: new FormControl(this.examples[0].id,
Validators.required,
),
});
or if you dont want to initialization immediately and want later on then make use of setValue method, below is required when you are fecthing data from server and want to set value i just hard coded value just to show as example , you should replace with the value you get from server
form2.get('drop').setValue('1');
html should be as below no need of [selected]
<select formControlName="drop">
<option disabled>Choose one</option>
<option *ngFor="let example of examples" [value]="example.id" [disabled]="example.isDisabled" >{{ example.name }}</option>
</select>