$ref from child component is always undefined in parent(vuejs) - javascript

For some reason when trying to grab the ref for the child component I am getting undefined even when only asking for it later then lifecycle events of mounted and created.
Here is the child component:
<template>
<div>
<div class="form-row">
<label>Season</label>
<select placeholder="Season" v-model="semester.Season">
<option v-for="s in seasons" :value="s.key">{{s.key}}</option>
</select>
</div>
<div class="form-row">
<div class="form-columns start-year-group">
<div class="form-group" style="width:50%">
<label>Start Month</label>
<select v-model="StartMonth" #change="calculateStartDate('Month', $event.currentTarget.value)" placeholder="Start Month">
<option v-for="m in months" :value="m.value">{{m.key}}</option>
</select>
</div>
<div class="form-group" style="width:50%">
<label>Start Year</label>
<select v-model="StartYear" #change="calculateStartDate('Year', $event.currentTarget.value)" placeholder="Start Year">
<option v-for="y in years" :value="y.key">{{y.key}}</option>
</select>
</div>
</div>
</div>
<div class="form-row">
<div class="form-columns end-year-group">
<div class="form-group" style="width:50%">
<label>End Month</label>
<select v-model="EndMonth" #change="calculateEndDate('Month', $event.currentTarget.value)" placeholder="End Month">
<option v-for="m in months" :value="m.value">{{m.key}}</option>
</select>
</div>
<div class="form-group" style="width:50%">
<label>End Year</label>
<select v-model="EndYear" #change="calculateEndDate('Year', $event.currentTarget.value)" placeholder="End Year">
<option v-for="y in years" :value="y.key">{{y.key}}</option>
</select>
</div>
</div>
</div>
</div>
</template>
<script>
import { eMonth, eYear, eSeason } from '#/shared/lib/enums';
export default {
name: 'SemesterForm',
props: ['schoolID', 'sData', 'sessionSchool'],
data () {
var cYear = (new Date()).getFullYear();
return {
semester: {
Season: 'Spring',
StartDate: null,
EndDate: null,
SchoolID: null,
Interactions: []
},
StartMonth: 0,
StartYear: cYear,
EndMonth: 5,
EndYear: cYear
};
},
mounted () {
this.semester.SchoolID = this.schoolID || this.sessionSchool;
this.semester.StartDate = this.calculateDate(this.StartYear, this.StartMonth);
this.semester.EndDate = this.calculateDate(this.EndYear, this.EndMonth);
if (this.sData) {
Object.assign(this.semester, this.sData);
this.StartMonth = this.sData.StartMonth;
this.StartYear = this.sData.StartYear;
this.EndMonth = this.sData.EndMonth;
this.EndYear = this.sData.EndYear;
}
},
computed: {
seasons () {
return eSeason.enums;
},
months () {
return eMonth.enums;
},
years () {
return eYear.enums;
}
},
methods: {
calculateStartDate (yearOrMonth, value) {
var date;
if (yearOrMonth === 'Year') {
date = this.calculateDate(value, this.StartMonth);
}
else if (yearOrMonth === 'Month') {
date = this.calculateDate(this.StartYear, value);
}
this.semester.StartDate = date;
},
calculateEndDate (yearOrMonth, value) {
var date;
if (yearOrMonth === 'Year') {
date = this.calculateDate(value, this.EndMonth);
}
else if (yearOrMonth === 'Month') {
date = this.calculateDate(this.EndYear, value);
}
this.semester.EndDate = date;
},
calculateDate (year, month) {
return new Date(year, month, 1);
}
}
};
</script>
<style scoped>
.form-group{
flex: 1;
}
</style>
Here is the parent component, this component has very little beyond the $ref to the child and then a cancel/save option:
<template>
<div>
Add Semester
<Modal :show="show" title="Add New Semester" name="Semester" width="500px" height="360px" #close="toggleSemesterModal">
<template>
<div>
<semester-form ref="form" :schoolID="schoolID"></semester-form>
</div>
<footer>
<a #click.prevent="save" class="btn btn pull-right" style="margin-left: 10px;">Save</a>
<button href="#" class="btn btn pull-right" style="margin-left: 10px;" #click="toggleSemesterModal">Cancel</button>
</footer>
</template>
</Modal>
</div>
</template>
<script>
import Modal from '#/shared/components/ui/modal';
import SemesterForm from './SemesterForm';
export default {
name: 'NewSemester',
data: () => ({
semester: {},
show: false
}),
props: ['schoolID'],
components: { Modal, SemesterForm },
methods: {
toggleSemesterModal () {
this.show = !this.show
},
save () {
console.log(this.$refs); //undefined
const semester = this.$refs.form.semester;
console.log('need to save this data', {...semester});
this.show = !this.show
}
}
};
</script>
<style scoped>
.
.
.
</style>

Related

How to remove character "T" in a DateTimeField in Django Vue.js?

I have a list with comments, those comments have a moment field, which is a DateTimeField. In this DateTimeField I have for example this --> 2020-06-03T15:32:01.803027 and I want to delete that T character, or replace with a blank space.
I'm using Django for the backend and Vue.js for the frontend.
I was able to remove the Z character by changing the USE_TZ = True to False option in the settings.py file. But I can't remove the T character, that's all I need. I have tried from the frontend to remove the T character using methods and computed properties, but I can't use the replace("T", " ") method on a DateTimeField, I can only use it on a String
<template lang="html">
<div class="container">
<div class="row">
<div class="col text-left">
<h2>Detalles del partido</h2>
</div>
</div>
<div class="row">
<div class="col">
<div class="card">
<div class="card-body">
<form>
<form #submit="onSubmit">
<div class="form-group row">
<label for="nombreLocal" class="col-sm-2 col-form-label">Local</label>
<div class="col-sm-6">
<input type="text" name="nombreLocal" class="form-control" readonly v-model.trim="form.nombreLocal">
</div>
</div>
<div class="form-group row">
<label for="nombreVisitante" class="col-sm-2 col-form-label">Visitante</label>
<div class="col-sm-6">
<input type="text" name="nombreVisitante" class="form-control" readonly v-model.trim="form.nombreVisitante">
</div>
</div>
<div class="form-group row">
<label for="resultado" class="col-sm-2 col-form-label">Resultado</label>
<div class="col-sm-6">
<input type="text" name="resultado" class="form-control" readonly v-model.trim="form.resultado">
</div>
</div>
<div class="form-group row">
<label for="pronosticoSistema" class="col-sm-2 col-form-label">Pronóstico del sistema</label>
<div class="col-sm-6">
<input type="text" name="pronosticoSistema" class="form-control" readonly v-model.trim="form.pronosticoSistema">
</div>
</div>
<div class="form-group row">
<label for="premio" class="col-sm-2 col-form-label">Premio</label>
<div class="col-sm-6">
<input type="number" name="premio" class="form-control" readonly v-model.trim="form.premio">
</div>
</div>
<div class="form-group row">
<label for="dificultad" class="col-sm-2 col-form-label">Dificultad</label>
<div class="col-sm-6">
<input type="text" name="dificultad" class="form-control" readonly v-model.trim="form.dificultad">
</div>
</div>
<div class="rows">
<div class="col text-left">
<b-button size="sm" variant="primary" :to="{ name:'CreatePronostico', params: {partidoId: this.partidoId} }">
Pronosticar
</b-button>
<b-button size="sm" variant="primary" :to="{ name:'CreateComentario', params: {partidoId: this.partidoId}}">
Comentar
</b-button>
<b-button size="sm" type="submit" class="btn-large-space" :to="{ name: 'PronosticadorUsuario'}">Atrás</b-button>
</div>
</div>
</form>
<br>
<h2>Comentarios</h2>
<br>
<div class="comentarios">
<b-table striped hover
:items="comentarios"
:fields="fields"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc">
<template v-slot:cell(action)="data">
<b-button size="sm" variant="primary" :to="{ name:'CreateComentarioRespuesta', params: {comentarioId: data.item.id} }">
Responder
</b-button>
<b-button size="sm" variant="primary" :to="{ name:'DarMeGusta', params: {comentarioId: data.item.id} }">
Me gusta
</b-button>
<b-button size="sm" variant="primary" :to="{ name:'EditComentario', params: {comentarioId: data.item.id} }">
Editar
</b-button>
<b-button size="sm" variant="danger" :to="{ name:'DeleteComentario', params: {comentarioId: data.item.id} }">
Eliminar
</b-button>
</template>
</b-table>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import swal from 'sweetalert'
import router from "../../router";
export default {
mounted() {
this.checkLoggedIn();
},
data() {
return {
sortBy: 'momento',
sortDesc: false,
partidoId: this.$route.params.partidoId,
form: {
nombreLocal: '',
nombreVisitante: '',
resultado: '',
pronosticoSistema: '',
premio: '',
dificultad: ''
},
fields: [
{ key: 'id', label: 'Número de comentario' },
{ key: 'momento', label: 'Momento', sortable: true},
{ key: 'texto', label: 'Texto' },
{ key: 'meGustas', label: 'Número de "me gustas"', sortable: true},
{ key: 'autor', label: 'Autor' },
{ key: 'comentarioRespuesta', label: 'Responde a' },
{ key: 'action', label: '' }
],
comentarios: []
}
},
methods: {
checkLoggedIn() {
this.$session.start();
if (!this.$session.has("token")) {
router.push("/auth");
}
},
onSubmit(evt){
evt.preventDefault()
const path = `http://localhost:8000/api/v1.0/partidos/${this.partidoId}/`
axios.get(path, this.form).then((response) =>{
this.form.nombreLocal = response.data.nombreLocal
this.form.nombreVisitante = response.data.nombreVisitante
this.form.resultado = response.data.resultado
this.form.pronosticoSistema = response.data.pronosticoSistema
this.form.premio = response.data.premio
this.form.dificultad = response.data.dificultad
})
.catch((error) => {
console.log(error)
})
},
getPartido (){
const path = `http://localhost:8000/api/v1.0/partidos/${this.partidoId}/`
axios.get(path).then((response) =>{
this.form.nombreLocal = response.data.nombreLocal
this.form.nombreVisitante = response.data.nombreVisitante
this.form.resultado = response.data.resultado
this.form.pronosticoSistema = response.data.pronosticoSistema
this.form.premio = response.data.premio
this.form.dificultad = response.data.dificultad
})
.catch((error) => {
console.log(error)
})
},
getComentarios (){
const path = 'http://localhost:8000/api/v1.0/comentarios/'
axios.get(path).then((response) => {
this.comentarios = response.data
})
.catch((error) => {
console.log(error)
})
},
},
computed: {
comentariosFormateados: function (){
var res = [];
for(var i = 0; i < this.comentarios.length; i++){
this.comentarios[i].momento.toISOString().replace('T', '');
res.push(comentarios[i]);
}
return res;
}
},
created() {
this.getPartido(),
this.getComentarios()
}
}
</script>>
<style lang="css" scoped>
</style>
Just return the Django DateTime object formatted however you want, for example:
myDateTime = strftime(MyModel.objects.get(id=id).moment, "%Y-%m-%d %H:%M:%S.%f")
Or:
comment = MyModel.objects.get(id=id)
moment = strftime(comment.moment, "%Y-%m-%d %H:%M:%S.%f")
comment.formatted_moment = moment
...
Then return it to your view in that format (a formatted string).
I've solved with this:
formatMomento(value) { const formattedDate = DateTime.fromISO(value).toLocaleString(DateTime.DATETIME_SHORT); return formattedDate; },
And calling it from the formatter attribute:
fields: [
{ key: 'id', label: 'Número de comentario' },
{ key: 'momento', formatter: "formatMomento", label: 'Momento', sortable: true},
{ key: 'texto', label: 'Texto' },
{ key: 'meGustas', label: 'Número de "me gustas"', sortable: true},
{ key: 'autor', formatter: "nombreDeUsuario", label: 'Autor' },
{ key: 'comentarioRespuesta', label: 'Responde al comentario:' },
{ key: 'action', label: '' }
],

Unable to bind v-model with vue-date-picker

I have used vue-date-picker and v-model for two way data binding. Initially I have set value to date(i.e. startDate in this case) and in console I am printing that passed value(i.e. startDate). At first, that passed value to startDate (i.e. 2019-09-17 is printed) but when I chose new Date, startDate value didn't get updated rather value remained same as it was when it was initially passed.
<div class="col-md-3">
<label for="startDate" class>Start Date</label>
<datepicker v-model="startDate" :readonly="true" format="YYYY-MM-DD" name="startDate">
</datepicker>
</div>
<p>Start Date: {{startDate}}</p>
<div class="col-md-2">
<div class="md-form mb-0">
<button type="button" class="btn btn-primary" #click="showDateValues">Apply</button>
</div>
</div>
import datepicker from "vue-date-picker";
<script>
import datepicker from "vue-date-picker";
export default {
name: "Example",
components: {
datepicker
},
data() {
return {
startDate: "2019-09-17"
};
},
methods:{
showDateValues(){
console.log("Start Date: "+this.startDate)
}
}
};
</script>
try this:
data() {
return {
startDate: new Date("2019-09-17")
};
},
var elm = new Vue({
el: '.app8',
mounted () {
var vm = this
$('#datedate').datepicker ({
onSelect: function(dateText) {
vm.date = dateText
}
})
});
<div class="row mt-5">
<div class="col">
<div class="app8">
<input v-model="date" name="date" class="input" type="date" id="datedate">
</div>
</div>
</div>
Hope this will help

How do i make React Datepicker states independent when the same DatePicker component is iterated many in a list?

I have a component that adds dynamically new fields in a list by a click of a button, then when all fields are filled it is populated to an array of objects
in this format
"prices": [
{
"from": "2019-01-01",
"to": "2019-06-30",
"price": 1560
},
{
"from": "2019-07-01",
"to": "2019-09-30",
"price": 2010
},
{
"from": "2019-10-01",
"to": "2019-12-31",
"price": 2010
}
],
But the problem is when i add a another section which are DatePicker fields, it is already prefilled with the previous state of the date, a new set of fields need to be empty at all times until a value is put, what happens in the background does not reflect on the User Interface
here is a picture of the two sections and the second section is already prefilled with this.state.startDate and this.state.endDate,
https://imgur.com/fgWFeMR
import React, { Component} from 'react';
import DatePicker from "react-datepicker";
import 'react-datepicker/dist/react-datepicker.css';
class Brand extends Component {
constructor(props) {
super(props);
this.state = {
prices: [{ from: null, to: null, price: 0}]
}
this.handleAdd = this.handleAdd.bind(this);
this.handleRemovee = this.handleRemove.bind(this);
this.handleChangePrices = this.handleChangePrices.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleChangeStart = this.handleChangeStart.bind(this);
this.handleChangeEnd = this.handleChangeEnd.bind(this);
}
handleChange = (value, name) => {
this.setState(this.state[name] = value);
};
handleChangeStart(startDate){
this.setState({startDate});
console.log(this.state.startDate);
}
handleChangeEnd(endDate){
this.setState({endDate});
console.log(this.state.endDate);
}
handleChangePrices(i, e) {
const prices = [...this.state.prices];
prices[i].price = e.target.value;
prices[i].from = this.state.startDate;
prices[i].to = this.state.endDate;
this.setState({ prices });
console.log(this.state.prices);
const {price, from, to} = this.state.prices;
console.log(from);
if(from === undefined){
console.log("this is a mistake");
}
}
handleAdd() {
this.setState(prevState => ({
prices: [...prevState.prices, { from: null, to:null,
price:
null }]
}));
}
handleRemove(i) {
const prices = [...this.state.prices];
prices.splice(i, 1);
this.setState({ prices });
}
handleSubmit(e) {
alert("A name was submitted: " + this.state.prices.join(",
"));
console.log(this.state.prices);
}
render() {
{
const items = this.state.prices.map((el, i) => (
<div key={i}>
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
{/* <div className="but-ons-brand">
<span>
<a onClick={() =>
this.handleRemove(i)} className="btn btn-year btn-font" > Delete
Year</a>
</span>
</div> */}
</div>
<div className="field-inputs__form-input
date">
<div className="date-picker-wrapper">
<div className="date-picker"> From
Date
</div>
<div className="date-
picker__individual">
<DatePicker
selected=
{this.state.startDate}
selectsStart
startDate=
{this.state.startDate}
endDate={this.state.endDate}
onChange=
{this.handleChangeStart}
/>
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-picker">To Date
</div>
<div className="date-
picker__individual">
<DatePicker
selected={this.state.endDate}
selectsEnd
startDate=
{this.state.startDate}
endDate={this.state.endDate}
onChange=
{this.handleChangeEnd}
minDate={this.state.startDate}
/>
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-
picker__individual">
<label className="label-unique
band-price"> USD</label>
<input type="number" min="1"
placeholder="0" name="price" value={this.state.price}
onChange={e => this.handleChangePrices(i, e)}
className="input-band-price mb-3" required />
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-
picker__individual">
<div className="but-ons-brand">
<span>
<a onClick={() =>
this.handleRemove(i)} className="btn btn-danger btn-font" >
Delete Band</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
));
return (
<>
<form>
{items}
<div className="field-inputs__wrapper border-up-
year">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input
date">
</div>
</div>
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input
date">
<div className="but-ons-brand">
<span>
<a onClick={() =>
this.handleAdd()} className="btn btn-success btn-font" > Add
Pricing Band</a>
</span>
</div>
</div>
</div>
<div className="field-inputs__wrapper border-up-
year">
<div className="field-inputs__label">
<div className="but-ons-brand">
<span>
<a onClick={() =>
this.handleSubmit()} className="btn btn-green btn-
font" > Add Year</a>
</span>
</div>
</div>
<div className="field-inputs__form-input
date">
</div>
</div>
</form>
</>
)
}
}
}
export default Brand;
I got a simple fix just used the index 'i' parameter for all my expected values to make them unique for each instance
import React, { Component } from 'react';
import DatePicker from "react-datepicker";
import 'react-datepicker/dist/react-datepicker.css';
import { connect } from 'react-redux';
import { ErrorLabels } from '../ErrorLabels';
import { FormInput } from 'shards-react';
class Brand extends Component {
constructor(props) {
super(props);
this.state = {
prices: [{ from: null, to: null, price: "" }],
disabled: true
}
this.handleAdd = this.handleAdd.bind(this);
this.handleRemove = this.handleRemove.bind(this);
this.handleChangePrices = this.handleChangePrices.bind(this);
this.handleDateChange = this.handleDateChange.bind(this);
}
handleDateChange(dateName, dateValue, index) {
if (this.state.prices[index].price === 0) {
console.log("error on prices")
}
if (dateName === 'startDateTime') {
this.state.prices[index].from = dateValue;
this.setState({ startDate: dateValue });
return;
}
this.state.prices[index].to = dateValue;
this.setState({ endDate: dateValue });
this.props.setPrices(this.state.prices);
}
handleChangePrices(i, e) {
const prices = [...this.state.prices];
prices[i].price = e.target.value;
prices[i].from = this.state.startDate;
prices[i].to = this.state.endDate;
this.setState({ prices });
this.props.setPrices(this.state.prices);
}
handleAdd() {
if (this.state.prices.length <= 2) {
this.setState(prevState => ({
prices: [...prevState.prices, { from: null, to: null, price: null }]
}));
}
return;
}
handleRemove(i) {
const prices = [...this.state.prices];
prices.splice(i, 1);
this.setState({ prices: prices });
}
handleSubmit() {
this.props.setPrices(this.state.prices);
}
render() {
{
const items = this.state.prices.map(( i) => (
<div key={i}>
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input date">
<div className="date-picker-wrapper">
<div className="date-picker"> From Date
</div>
<div className="date-picker__individual">
<DatePicker
id="start-date-time"
name="startDateTime"
placeholderText="-"
className="form-control"
showDisabledMonthNavigation
selected={this.state.prices[i].from || null}
selectsStart
startDate={this.state.startDate}
endDate={this.state.endDate}
onChange={date => this.handleDateChange('startDateTime', date, i)}
autosuggest="off"
/>
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-picker">To Date
</div>
<div className="date-picker__individual">
<DatePicker
id="end-date-time"
name="endDateTime"
className="form-control"
placeholderText="-"
showDisabledMonthNavigation
selected={this.state.prices[i].to || null}
selectsEnd
startDate={this.state.prices[i].from || null}
endDate={this.state.endDate}
onChange={date => this.handleDateChange('endDateTime', date, i)}
minDate={this.state.startDate}
autosuggest="off"
/>
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-picker__individual">
<label className="label-unique band-price"> USD</label>
<ErrorLabels errors={this.props.errors} name="price" />
<FormInput type="number" min="0" placeholder="0" name="price" value={this.state.price} onChange={e => this.handleChangePrices(i, e)} className="input-band-price mb-3" required />
</div>
</div>
<div className="date-picker-wrapper">
<div className="date-picker__individual">
<div className="but-ons-brand-delete">
<span>
<div onClick={() => this.handleRemove(i)} className="btn btn-danger btn-font" > Delete Band</div>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
));
return (
<>
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input date">
</div>
</div>
{items}
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input date">
</div>
</div>
<div className="field-inputs__wrapper">
<div className="field-inputs__label">
</div>
<div className="field-inputs__form-input date">
<div className="button-brand">
<span>
<div onClick={() => this.handleAdd()} className="btn btn-success btn-font" > Add Pricing Band</div>
</span>
</div>
</div>
</div>
</>
)
}
}
}
const mapStateToProps = ({ posts }) => {
const { errors } = posts;
return {
errors,
}
}
export default connect(mapStateToProps)(Brand);

Filter array based on multiple options (Vue/JavaScript)

If this is a duplicate post I apologize. I searched a couple different things before posting this. I'm trying to figure out how to filter results based off of two options. I can get one of the options to work but need both to drive the results.
I have 4 computed properties:
filteredResults: where the filtering is taking place
phases: collection of all the phases based on the results
results: original results list (stored in Vuex)
states: collection of all the states based on the results
In the data on that component I have two properties that are binded to what the user selects. I'm running the filtering off of those selected values.
Code
<template>
<div class="results">
<Banner/>
<div class="container">
<div class="columns">
<main role="main" class="column is-8-tablet is-9-widescreen">
<p class="title is-4">Results for: {{ $route.query.q }}</p>
<p class="subtitle">{{ results.length }} Trials Avaliable</p>
<ul>
<li v-for="trial in results" :key="trial.studyid">
<div class="card" :data-location="trial.state" :data-phases="trial.phasename">
<div class="card-content">
<div class="content">
<h2 class="title is-4">
<a href="void:javascript(0)" #click="goToDetail(trial.studyname)">
{{ trial.studyname }}
</a>
</h2>
<p>{{ trial.protocoltitle.replace('�', '') }}</p>
<p>Available in {{ trial.studyentitylocation.split('`').length -1 }} location(s)</p>
</div>
</div>
</div>
</li>
</ul>
</main>
<aside role="complementary" class="column is-4-tablet is-3-widescreen">
<p class="title is-4">Filter Options</p>
<button class="accordion">Locations</button>
<div class="panel">
<form>
<div class="control">
<label class="radio">
<input type="radio" name="states" value="All" v-model="checkedLocations">
All
</label>
<label class="radio" v-for="(state, i) in states" :key="i">
<input type="radio" name="states" :value="state" v-model="checkedLocations">
{{ state }}
</label>
</div>
</form>
</div>
<button class="accordion">Phase</button>
<div class="panel">
<form>
<div class="control">
<label class="radio">
<input type="radio" name="phases" value="All" v-model="checkedPhases">
All
</label>
<label class="radio" v-for="(phase, i) in phases" :key="i">
<input type="radio" name="phases" :value="phase" v-model="checkedPhases">
Phase {{ phase }}
</label>
</div>
</form>
</div>
</aside>
</div>
</div>
</div>
</template>
<script>
import Banner from '#/components/Banner'
export default {
name: 'Results',
components: {
Banner
},
data () {
return {
checkedLocations: 'All',
checkedPhases: 'All'
}
},
mounted () {
this.activateAccordion()
},
computed: {
results () {
return this.$store.state.results
},
states () {
let statesArray = []
this.results.forEach((result) => {
if (result.state) {
var state = result.state
state.forEach((item) => {
if (statesArray.indexOf(item) === -1) {
statesArray.push(item)
}
})
}
})
return statesArray.sort()
},
phases () {
let phaseArray = []
this.results.forEach((result) => {
if (result.phasename) {
var phase = result.phasename
phase.forEach((item) => {
if (phaseArray.indexOf(item) === -1) {
phaseArray.push(item)
}
})
}
})
return phaseArray.sort()
},
filteredResults () {
let results = ''
if (this.checkedLocations !== 'All') {
results = this.results.filter((result) => result.state.includes(this.checkedLocations))
return results
} else {
return this.results
}
}
}
}
</script>
Here is what the app looks like on the front end
Trials App
I'm also new to the modern JavaScript syntax so please be nice lol.
If i understand you, it Seems like you can just add another filter according to the checkedPhases, similar to the filter you already have?
I have created a codepen to try to show how you can achieve it. There is a list of items containing carID and cityID. Also, there are two selects to filter the result. When you change a select, it will filter the options of the other select as well. I hope it can help you, if you have any question, just ask.
const data = [
{
cityID: 1,
carID:1,
name: 'Ted'
},
{
cityID: 1,
carID:2,
name: 'Tod'
},
{
cityID: 2,
carID:1,
name: 'Michel'
},
{
cityID: 3,
carID:1,
name: 'Romeu'
},
{
cityID: 2,
carID:3,
name: 'Thomas'
},
{
cityID: 3,
carID:4,
name: 'Lucy'
},
{
cityID: 4,
carID:1,
name: 'Mary'
},
]
const cities = [{ cityID: 1, name:'New York'},{ cityID: 2, name:'Sydney'}, { cityID: 3, name:'Chicago'},{ cityID: 4, name:'Perth'}]
const cars = [{ carID: 1, name:'Cruze'},{ carID: 2, name:'Mustang'}, { carID: 3, name:'Blazer'},{ carID: 4, name:'Tucson'}]
new Vue({
el: '#app',
data: function() {
return {
data,
cities,
cars,
city: "",
car: "",
}
},
methods: {
findCarName: function (carID) {
return this.cars.find(car => car.carID === carID).name
},
findCityName: function (cityID) {
return this.cities.find(city => city.cityID === cityID).name
},
reset: function () {
this.city = ""
this.car = ""
}
},
computed: {
filteredData: function() {
let resultData = this.data
if (this.city) {
resultData = resultData.filter(item => item.cityID === this.city)
}
if (this.car) {
resultData = resultData.filter(item => item.carID === this.car)
}
return resultData
},
filteredCars: function () {
const carIDs = this.filteredData.reduce((acc, next) => {
if (acc.indexOf(next.carID) === -1){
return [...acc, next.carID]
}
return acc
},[])
if (carIDs.length) {
return carIDs.map(carID => ({carID, name: this.findCarName(carID)}))
}
return this.cars
},
filteredCities: function () {
const citiesIDs = this.filteredData.reduce((acc, next) => {
if (acc.indexOf(next.cityID) === -1){
return [...acc, next.cityID]
}
return acc
},[])
if (citiesIDs.length) {
return citiesIDs.map(cityID => ({cityID, name: this.findCityName(cityID)}))
}
return this.cities
}
}
})
#app {
margin: 30px;
}
#app .form-group {
display: flex;
align-items: center;
}
#app .form-group label {
font-weight: bold;
color: #337ab7;
margin-right: 20px;
}
#app .filters {
margin-bottom: 20px;
display: flex;
width: 700px;
justify-content: space-around;
}
#app .table {
width: 700px;
}
#app .table thead tr td {
font-weight: bold;
color: #337ab7;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="filters row">
<div class="form-group">
<label for="city">City</label>
<select v-model="city" id="city" class="form-control">
<option value="">Select City</option>
<option v-for="item in filteredCities" :key="item.cityID" :value="item.cityID">{{item.name}}</option>
</select>
</div>
<div class="form-group">
<label for="car">Car</label>
<select v-model="car" id="car" class="form-control">
<option value="">Select Car</option>
<option v-for="item in filteredCars" :key="item.carID" :value="item.carID">{{item.name}}</option>
</select>
</div>
<div class="form-group">
<button type="button" class="btn btn-primary" #click="reset">Reset</button>
</div>
</div>
<table class="table table-striped table-bordered">
<thead>
<tr><td>Name</td><td>Car</td><td>City</td></tr>
</thead>
<tbody>
<tr v-for="item in filteredData" :key="data.name">
<td>{{item.name}}</td>
<td>{{findCarName(item.carID)}}</td>
<td>{{findCityName(item.cityID)}}</td>
</tr>
</tbody>
</table>
<div>

How to populate value in edit mode in select tag in react?

I am having the response of list of all clients which is having in state
this.state= {
clients: {
"response": "SUCCESS",
"totalClientUsers": 2,
"users": [{
"id": "5bae32e360dfee76e67e6b24",
"username": "sivasai",
"firstName": "siva",
"lastName": "sai",
"phone": "9878989098",
"organizationName": "TCS",
}, {
"id": "5bb1ab9d60dfee130c22cdea",
"username": "demo",
"firstName": "test user",
"lastName": "new",
"phone": "9876567898",
"organizationName": "Jp morgan",
}]
}
}
Based on the response I am trying to populate list of all client username
import React from 'react';
import { Link } from 'react-router';
import * as UserAction from '../../actions/userAction.jsx';
import UserStore from '../../store/userstore.jsx';
class Company extends React.Component {
constructor(props) {
super(props);
this.state = {
clientName: '-1',
singleUser: {
user: {
addressLine1: '',
organizationName: '',
}
},
clientslist: {
users: [],
}
};
this._userStoreChange = this._userStoreChange.bind(this);
}
componentWillMount() {
const details = UserStore._getSingleEnquiry();
if (Object.keys(details).length) {
this.setState({ ...details.enquiry, old: true });
}
UserStore.on('change', this._userStoreChange);
}
componentWillUnmount() {
UserStore.removeListener('change', this._userStoreChange);
}
componentDidMount() {
UserAction._getClientsList();
}
_userStoreChange(type) {
if (type == 'ClientsList') {
let clientslist = UserStore._getClientsList() || {};
this.setState({ clientslist });
}
if (type == 'SingleUser') {
let singleUser = UserStore._getSingleUser() || {};
this.setState({ singleUser });
}
}
handleClientChange(e) {
this.setState({ clientName: e.target.value });
let data = {
id: e.target.value
}
UserAction._getSingleUserDetails(data);
}
createEnquiry() {
let data = {
id: this.state.old ? this.state.id : null,
clientName: this.state.old ? this.state.clientName : this.state.singleUser && this.state.singleUser.user && this.state.singleUser.user.organizationName,
}
this.state.old ? UserAction._UpdateEnquiry(data) : UserAction._createEnquiryDetails(data)
}
render() {
let clientslist = this.state.clientslist.users;
return (
<div>
<button className="btn btn-primary btn-round btn-simple float-right hidden-xs m-l-10" onClick={this.createEnquiry.bind(this)}> {this.state.old ? 'Update' : 'Save'}</button>
<div className="row">
<div className="col-sm-4 col-6">
<h2 className="card-inside-title" > Client Name</h2>
<select className="c-select form-control " onChange={this.handleClientChange.bind(this)} value={this.state.clientName}>
<option value='-1' disabled>Select Client</option>
{clientslist.map((el) => <option name={el.username} id={el.id} value={el.id}>{el.username}</option>)}
</select>
</div>
<div className="col-md-4 col-6">
<h2 className="card-inside-title" > Address</h2>
<div className="form-group">
<input type="text" className="form-control " placeholder="" name='' id="" value={this.state.singleUser.user.addressLine1} disabled />
</div>
</div>
<div className="col-md-4 col-6">
<h2 className="card-inside-title" >Email</h2>
<div className="form-group">
<input type="text" className="form-control " placeholder="" name='' id="" value={this.state.singleUser.user.email} disabled />
</div>
</div>
<div className="col-md-4 col-6">
<h2 className="card-inside-title" >Reg No.</h2>
<div className="form-group">
<input type="text" className="form-control " placeholder="" name='' id="" value={this.state.singleUser.user.registrationNumber} disabled />
</div>
</div>
<div className="col-md-4 col-6">
<h2 className="card-inside-title" >Organization Name</h2>
<div className="form-group">
<input type="text" className="form-control " placeholder="" name='' id="" value={this.state.singleUser.user.organizationName} disabled />
</div>
</div>
</div>
</div>
)
}
}
export default Company;
After using above in create mode I can able to select the username like below
Now i can able to select option I want. But here while in creation mode I am sending organizationName in the request.
In edit mode in am able to get organizationName in the response. based on that the selected client should get populated but as I am getting organizationName in the response I cannot able to populate the selected client.
As for what I understand what you want to show is value preselected in the select box. For that you may need to pass this.state.clientId instead of this.state.clientName in the value attribute of select tag
<select
className="c-select form-control "
onChange= {this.handleClientChange.bind(this)}
value={this.state.clientId}>
<option value='-1' disabled>Select Client</option>
{clientslist.map((el) =>
<option name={el.username} id={el.id} value={el.id}>
{el.username}
</option>)}
</select>
Also make sure you have selected client id inside your state
this.state = {
clientId: '43953fuse9fuwef'
}
When rendering your edit page, find the option, and set attribute selected in the option you want to be preselected.
Like this: <option selected="selected">asdasd</option>
Add more detail: you can use if to conditionally rendering. I don't remember exactly JSX syntax, but you can do something like:
clientslist.map((el) => {
if (this.state.clientName == el.username)
<option seleted name={el.username} id={el.id} value={el.id}>{el.username}</option>
else
<option name={el.username} id={el.id} value={el.id}>{el.username}</option>
}

Categories