How to conditionally render the screens with button in vuejs? - vue.js

export default {
name: "HelloWworld",
data: function () {
return {
isHidden: false,
isWelcome: false,
isFadeout: false,
}
}
<div v-if="!isHidden">
//some code for screen1
<button v-on:click="isHidden = true"> HELLO</button>
</div>
<div v-else-if="isHidden && !isFadeout">
//some code for screen 2
<button v-on:click="isFadeout = true"> Hi</button>
</div>
<div v-else-if="isFadeout && isHidden && !isWelcome">
<input
:type="passwordFieldType"
v-model="user.password"
id="password"
name="password"
class="input-section-three"
:class="{ 'is-invalid': submitted && $v.user.password.$error }"
placeholder="Enter new password"
:maxlength="maxpassword"
v-on:keypress="isPassword($event)"
/>
<div
v-if="submitted && $v.user.password.$error"
class="invalid-feedback-two"
>
<span v-if="!$v.user.password.required">Password is required</span>
<span v-if="!$v.user.password.minLength"
>Minimum 8 character with
alphanumeric along with 1 capital letter, 1 small letter
and 1 special character at least</span
>
</div>
<input
:type="passwordFieldTypetwo"
v-model="user.confirmPassword"
id="confirmPassword"
name="confirmPassword"
class="input-section-three"
:class="{
'is-invalid': submitted && $v.user.confirmPassword.$error
}"
placeholder="Confirm password"
:maxlength="maxconfirmpassword"
v-on:keypress="isconfirmPassword($event)"
:disabled="user.password.length < 8"
/>
<div
v-if="submitted && $v.user.confirmPassword.$error"
class="invalid-feedback-two"
>
<span v-if="!$v.user.confirmPassword.required"
>Confirm Password is required</span
>
<span v-else-if="!$v.user.confirmPassword.sameAsPassword"
>Password must match</span
>
</div>
<button v-on:click="isWelcome = true" :disabled="user.confirmPassword.length < 8" > SUBMIT </button>
</div>
<div v-else-if="isWelcome">
//some code for screen 4
<button>Fine</button>
</div>
conditional rendering is working fine but, In screen3 submit button code, i have ""v-on:click="isWelcome = true""", if i remove this line, password validation is happening onclick of submit button, Where if i place again ""v-on:click="isWelcome = true""" without checking the validations simply its moving to 4th screen

You could try to use steps to show everything you need.
data() {
return{
submissionStep: 1
}
}
I believe that you render different components for each screen. So you can show each component with v-if="submissionStep === 1"
Each time you click the next/submit button you change the submissionStep with a method binded like
update(){
if(this.submissionStep <= 3){
this.submissionStep += 1
}
},
Instead of 3 you can limit your steps as the number of screens you have

<button v-if="isHidden" v-on:click="isWelcome = true"> HELLO</button>
<button v-if="!isHidden" v-on:click="isWelcome = true"> HELLO</button>
Use the v-if attribute inside the buttons.
If you have more than one condition, do it in computed.
computed: {
displayButton() {
return (this.isHidden && this.isWelcome);
},
}
<button v-if="displayButton" v-on:click="isWelcome = true"> HELLO</button>

Related

Vue's reactivity not triggered when using Bootstrap 5's alert div

Vue's reactivity not triggered when using Bootstrap 5's alert div.
See my code:
<template>
<div>
<div
v-if="alertICDMsg!==''"
id="alertICDCode"
class="alert alert-info alert-dismissible fade show"
role="alert"
>
<i class="fa-solid fa-lightbulb" />
<strong> Note!</strong> <span v-html="alertICDMsg" />
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
/>
</div>
<div class="input-group mb-3">
<div class="col-xs-1">
<input
id="ICDCode"
v-model="editing_icdCode"
class="form-control"
placeholder="ICD Code"
aria-label="ICD Code"
#input="ICDCodeSearchRequested"
>
</div>
<input
id="Diagnosis"
v-model="editing_diagnosis"
type="text"
class="form-control"
placeholder="Diagnosis"
aria-label="Diagnosis"
aria-describedby="basic-addon1"
list="icdsearchlist"
#change="SelectedDiagnosisTextOption"
#input="ICDTextSearchRequested"
>
<datalist id="icdsearchlist">
<option
v-for="(disease_option, index) in icd_diagnosis_options"
:key="index"
>
{{ disease_option }}
</option>
</datalist>
<button
id="btnAddDiagnoses"
href="#"
class="btn btn-primary mx-1"
#click="AddDiagnosis"
>
<i class="fal fa-plus-circle" />
</button>
<button
id="btnCopyPreviousDiagnoses"
href="#"
class="btn btn-primary BtnSaveGroup mx-1"
>
<i class="far fa-history" />
</button>
<button
id="quickbill"
class="btn btn-primary mx-1"
>
<i class="fas fa-search-plus" />
</button>
<button
id="clearICD"
class="btn btn-danger mx-1"
#click="ClearICDFields"
>
<i class="fad fa-times-circle" />
</button>
</div>
</div>
<template>
<script>
export default {
data() {
return {
alertICDMsg:"",
};
},
watch: {
alertICDMsg: {
handler(val) {
console.log(`Val for alertICDMsg changed to :${val}`);
},
immediate: true,
deep: true,
},
},
methods: {
ICDCodeSearchRequested() {
console.log(`Search by ICD code`);
this.alertICDMsg="Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box."
console.log(`alertICDMsg is ${this.alertICDMsg}`);
setTimeout(function() {
console.log(`Dismissing alert`);
this.alertICDMsg='';
console.log(`alertICDMsg is ${this.alertICDMsg}`);
}, 5000);
},
},
}
</script>
Console log:
Search by ICD code
SubClinicalBlock.vue?d801:291 alertICDMsg is Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:220 Val for alertICDMsg changed to :Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:293 Dismissing alert
SubClinicalBlock.vue?d801:298 alertICDMsg is
The problem is that after 5 seconds, though the value of the variable changes, the alert is still visible.
I checked some similiar questions, and have seen this happening when bootstrap's javascript wasnt loaded. But for me, Bootstrap v5.0.1 JS is being loaded from the CDN and appears in the sources tab in Chrome.
Try to change the function inside of setTimeout to arrow function like this
setTimeout(() => { // code here })
The this inside of setTimeout(function () => {}) reference to the wrong context (the function itself) instead of the Vue component.
The arrow function doesn't have the this binding so when you use the arrow function the this keyword will reference the Vue component and change the state.
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Vue click two input one button

I want to pick a new value when the button is clicked, but I can't
<div class="col-lg-12 col-sm-6 col-4" style="margin-top:5px;">
<p style="margin-bottom:0rem;" > Цена</p>
<label>
<input id="PriceRangeMin" type="number" :value='text' >
-
<input id="PriceRangeMax" placeholder="до" type="number" :value='text1'>
</label>
<button id="PriceRangeMin" type="submit" style="margin-left:30px;" #click='textcon()'>Применить</button>
</div>
My script
<script>
export default {
name: 'Applesmartphone',
data () {
return {
text:[],
text1:[]
}
},
methods: {
textcon(){
console.log(text)
console.log(text1)
}
}
}
Hi, I want to pick a new value when the button is clicked, but I can't.
Bind input to properties using v-model like :
input id="PriceRangeMin" type="number" v-model='text' >
then use this to access that properties inside the method :
textcon(){
console.log(this.text)
console.log(this.text1)
}

boostrap vue modal not hide when click ok button with validation

I want to add validation to a modal window, I need a behavior in which when the OK button (form submission) is clicked, validation would take place, and if the result is negative, the window should not close
my modal
<b-modal
size="lg"
id="modalToRepair"
title="Add Problem"
title-class="font-18"
centered
body-class="p-4"
no-close-on-backdrop
no-close-on-esc
#ok="onClickModalRepair"
>
<div class="row">
<div class="col-lg-12">
<div class="form-group row">
<label class="col-4 col-form-label">
Repair Problem
<span class="text-danger">*</span>
</label>
<div class="col-8">
<input
v-model="theProblem"
type="text"
class="form-control"
placeholder="Input problem"
name="theProblem"
:class="{
'is-invalid': typesubmit && $v.theProblem.$error
}"
/>
<div
v-if="typesubmit && $v.theProblem.$error"
class="invalid-feedback"
>
<span v-if="!$v.theProblem.required">Requred field.</span>
</div>
</div>
</div>
</div>
</div>
</b-modal>
and my methods
Vue.js
methods: {
onClickModalRepair() {
this.typesubmit = true;
this.$v.$touch();
if (this.$v.$invalid) {
this.$bvModal.show("modalToRepair"); // not work - modal hide
//code for not hide this modal
return;
}
}
},
validations: {
theProblem: {
required
}
}
is it possible?
The method used in the #ok event, is passed an event, which you can call .preventDefault() on, if you want to prevent the modal from closing.
onClickModalRepair(bvModalEvt) {
this.typesubmit = true;
this.$v.$touch();
if (this.$v.$invalid) {
bvModalEvt.preventDefault();
return;
}
}
You can see an example of this on the docs.

Cannot read property 'focus' of undefined in VUE When setting focus to button

I am new to vue I have component which if the endpoint fails, calls my generic 'Error' modal. All this is working fine but I keep getting the following error:
Cannot read property 'focus' of undefined
This only happens for the else part of my method function.
For this specific issue is I my 'failedPrcess' equals any of the following, this is when I get is, all others are fine:
existOrderSearchProdOrders
stockSearchStockLevels
cartFetchCouriers
Code
<template>
<div class="modal fade danger-modal" id="errorModal" tabindex="-1" role="dialog" aria-labelledby="errorModalTitle" aria-hidden="true"
data-keyboard="false" data-backdrop="static" style="z-index: 99999">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content danger-modal-content">
<div class="modal-header danger-modal-headerfooter">An error has occurred</div>
<div class="modal-body">
<p v-if="failedProcess === 'appGetAccount' || failedProcess === 'existOrderSearchProdOrders' || failedProcess === 'stockSearchStockLevels'
|| failedProcess === 'cartFetchCouriers'">
{{ contactTxt | capitalize }}
</p>
<p v-else-if="errorCount < 3">If the error continues, {{ contactTxt }}</p>
<p v-else>As the error has continued, {{ contactTxt }}</p>
<p>
<b>
01234 567890
<br />
Open from 00:00 to 07:00
</b>
</p>
<p>Advising of what you were doing when the error occurred.</p>
</div>
<div class="modal-footer danger-modal-headerfooter">
<a v-if="failedProcess === 'appGetAccount'" ref="logoutButton" class="btn btn-primary" :class="logoutButtClicked" #click="logoutClicked = true" href="/site/logout">
<span v-if="!logoutClicked" id="logoutButtonLabel">Logout</span>
<span v-else id="logoutSpinner">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Logging out
</span>
</a>
<router-link v-else-if="failedProcess === 'fetchOrderReportDetails'" to="/review" tag="button"
ref="existOrdersButton" class="btn btn-primary" type="button" data-dismiss="modal" #click.native="closeButton">
Return to existing orders
</router-link>
<button v-else-if="errorCount < 3 && (failedProcess !== 'productsFetchProducts' && failedProcess !== 'existOrderSearchProdOrders'
&& failedProcess !== 'stockSearchStockLevels' && failedProcess !== 'cartFetchCouriers')" ref="closeButton" class="btn btn-primary"
type="button" data-dismiss="modal" #click="closeButton">
Close
</button>
<router-link v-else to="/" tag="button" ref="homeButton" class="btn btn-primary" type="button" data-dismiss="modal" #click="closeButton">
Return to homepage
</router-link>
</div>
</div>
</div>
</div>
</template>
<script>
import * as params from '../params';
export default {
name: "ErrorModal",
data() {
return {
contactTxt: 'please contact us on:',
errorCount: 0,
failedProcess: '',
}
},
mounted() {
VueEvent.$on('show-error-modal', (failedProcess) => {
if (this.failedProcess !== failedProcess) {
this.errorCount = 0;
}
this.failedProcess = failedProcess;
$('#errorModal').modal('show').on('shown.bs.modal', this.focus);
});
},
methods: {
focus() {
if (this.failedProcess === 'appGetAccount') {
this.$refs.logoutButton.focus();
} else if (this.failedProcess === 'fetchOrderReportDetails') {
this.$refs.existOrdersButton.$el.focus();
} else if (this.errorCount < 3 && this.failedProcess !== 'productsFetchProducts') {
this.$refs.closeButton.focus();
} else {
this.$refs.homeButton.$el.focus();
}
},
}
}
</script>`enter code here`
I've tried using v-if before and I also had similar problems and the best solution I found was, instead of using v-if/v-else-if/v-else, use v-show instead to perform conditional rendering.
Also, as the Vue.js doc says:
Generally speaking, v-if has higher toggle costs while v-show has higher initial render costs. So prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtime.

Why still adding even with validation form?

When I click the button on my modal with an empty field on my input its give me an undefined value on my console. And when I put a value on my input and click the button it is adding to my database. The problem is even the empty field or the undefined value are also adding to my database and the sweetalert is not working. I want to prevent the empty field adding to my database and prevent the undefined. Can somebody help me?
//start of method
checkForm: function(e) {
if (this.category_description) {
return true;
}
this.errors = [];
if (!this.category_description) {
this.errors.push('Category required.');
}
e.preventDefault();
},
addCategory : function() {
axios({
method : "POST",
url : this.urlRoot + "category/add_category.php",
data : {
description : this.category_description
}
}).then(function (response){
vm.checkForm(); //for FORM validation
vm.retrieveCategory();
console.log(response);
swal("Congrats!", " New category added!", "success");
vm.clearData();
}).catch(error => {
console.log(error.response);
});
},
//end of method
<form id="vue-app" #submit="checkForm">
<div class="modal" id="myModal" > <!-- start add modal -->
<div class="modal-dialog">
<div class="modal-content " style="height:auto">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title"> Add Category </h4>
<button #click="clearData" type="button" class="close" data-dismiss="modal"><i class="fas fa-times"></i></button>
</div>
<!-- Modal body -->
<div class="modal-body">
<div class="form-group">
<div class="col-lg-12">
<input type="text" class="form-control" id="category_description" name="category_description" v-model="category_description" placeholder="Enter Description">
<p v-if="errors.length">
<span v-for="error in errors"> {{ error }} </span>
</p>
</div>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="submit"#click="category_description !== undefined ? addCategory : ''" class="btn btn-primary"> Add Category </button>
</div>
</div>
</div>
</div>
</form>
The easiest way to stop this is adding data check. And condition check at top of your method.category_description !== undefined. Btw, move your e.preventDefault() to top too.
First of all do this:
- <button type="submit" #click="category_description !== undefined ? addCategory : ''" class="btn btn-primary"> Add Category </button>
+ <button type="submit" #click.prevent="addCategory" class="btn btn-primary"> Add Category </button>
and then in addCategory:
addCategory() {
if (!this.category_description) {
return;
} else {
// do your stuff here
}
}
When you are clicking on Add Category button, it is triggering the addCategory along with your validation method.
The return value of validation method has no impact on triggering of addCategory.
This issue can be handled in following ways.
Call addCategory only when there is some valid data
<button type="submit" #click="category_description != undefined ? addCategory() : ''" class="btn btn-primary"> Add Category </button>
Call the validation method inside addCategory and then proceed.