How to open popup, onclick of link in Vuejs? - vue.js

<label class="label-set">
<input type="checkbox" class="" name="sameadr" />
I agree to all statements of
Terms of Use
</label>
How to open popup, onclick of link. simple popup should open as soon as user click on link

In html
give a id to your a tag.
<label class="label-set" id="mainId">
<input type="checkbox" class="" name="sameadr" />
I agree to all statements of
Terms of Use
</label>
In javascript
document.getElementById("newId").addEventListener("click", function(){
confirm("confirm this") // or your popop code
})
Try this for vue.js
Terms of Use
And write this inside your method
new Vue({
el: '#mainId',
methods: {
openPopup: function () {
alert('ok')
}
}
})
Try this

Make a modal component. Add a click to your a tag. When clicked show your modal component. After another action (confirm etc.) close and continue.
How to make a reusable modal component in Vue.js: How to make a Modal Component

Related

VueJs handle Form Submit on Enter press

I have a background in Angular. Starting with vue was an okay experience for me until I came across a problem which VueJS developers seem to have shit on and slid under the carpet.
How can we create a form in which user can press enter from an input field to submit the form
This was seriously disappointing.
and please if you know the answer be kind enough to post in the Official vue documentation as well.
*Note:
my workaround: I used v-on:keydown.enter.prevent='loginUser' on every input field.
is there any way to not use it this way ( on every input field).
With button type as submit as well, form gets submitted when Enter key is pressed on any input.
No explicit binding is required on keypress.
new Vue({
el: '#app',
data() {
return {
title: "Vue 2 -Form submission on Enter",
formInput:{
fname:'',
lname:'',
gender:'male'
}
};
},
methods:{
onSubmit(){
console.log('submitted', this.formInput)
}
}
})
.form{
display:flex;
flex-direction:column;
gap:10px;
max-width:200px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"><h2>{{title}}</h2>
<form v-on:submit.prevent="onSubmit" class="form">
<input v-model="formInput.fname" #keydown.enter.prevent placeholder="first name"/>
<input v-model="formInput.lname" placeholder="last name"/>
<div>
<input v-model="formInput.gender" name="gender" placeholder="Gender" type="radio" value="male"/>male
<input v-model="formInput.gender" name="gender" placeholder="Gender" type="radio" value="female"/>Female
</div>
<button type="submit">Submit</button>
<pre>{{formInput}}</pre>
</form>
</div>
I'd urge you to check out this page on the VueJS documentation.
It explains how to set events on certain interactions. For example, you can trigger a function call on pressing the Enter key within an input field by doing this:
<input type="text" #keyup.enter="submit">
This will call the submit() method when the Enter key is pressed and released (keyup). On press, you can use keydown instead.'
In fact, the example I've taken is directly from this section in the page I linked above.
EDIT: A pure-HTML way to do this is to set your input type as submit, which will allow Enter to submit the form
You need to wrap your inputs within <form> ... </form> tag

Asking for confirmation before changing the radio option

How do I ask the user for a confirmation before changing the option in a radio button using Vue.js?
Something like Are you sure? would be fine.
Assuming you have the following DOM structure:
<div id="app">
<input type="radio"/>
</div>
you can bind a #change directive to the radio button with a method implementing the expected "Are you sure?" confirmation popup. So you can enrich the above mentioned DOM structure like this:
<div id="app">
<input type="radio" #change="showConfirm"/>
</div>
And in the Vue instance you can define the expected confirmation method, for example:
new Vue({
el: '#app',
methods: {
showConfirm: function(event) {
event.preventDefault();
let checkedRadio = window.confirm("Are you sure?");
event.target.checked = checkedRadio;
}
}
})
Here you find the working example.

Compute not updating if radio is checked through code

Sorry for the title, didn't know how I could better explain it.
I have 3 radio buttons. The output should be the value of whichever radio button is selected. Except, the 3rd radio button has a textarea, and if that radio button is selected, the resulting output should be what is in the textarea. I've also linked the #click of textarea to automatically check the radio button, so if a user clicks on the textarea, that radio button gets checked automatically.
Everything works, if you see the JSFiddle code and click on the 3rd radio button and type text in the textarea, the output should work fine. But if you refresh the page, and instead of clicking the radio button, if you directly click on the textarea (which indirectly checks the radio button), writing in the textarea will not update the output. Which means the compute function is not working.
However if you click on another radio button and then click back on the 3rd radio button, things will start working fine.
Here's the code (JSFiddle here: https://jsfiddle.net/eywraw8t/43651/ )
<div id="app">
Selected option 1: {{ selectedText }}
<BR>
<input type="radio" name="item1" value="" v-model="selected[0]" /> Empty<BR>
<input type="radio" name="item1" value="Hi" v-model="selected[0]" /> Hi<BR>
<input type="radio" name="item1" value="**custom**" v-model="selected[0]" /> <textarea name="textarea0" id="textarea0" cols="30" rows="10" v-model="custom[0]" #click="customClicked"></textarea><BR>
</div>
<script>
new Vue({
el: "#app",
data: {
selected: ['', ''],
custom: ['', ''],
},
computed: {
selectedText: function() {
if (this.selected[0] != '**custom**') return this.selected[0];
return this.custom[0];
}
},
methods: {
customClicked: function(e) {
//$(e.target).prev().prop('checked', true);
this.selected[0] = '**custom**';
this.$forceUpdate();
}
}
})
</script>
You don't need jQuery for this - just bind the values to one array and use #focus event on the textarea:
new Vue({
el: "#app",
data: {
values: ['', 'Hi', ''],
selected: '',
},
computed: {
selectedText: function() {
return this.values[this.selected];
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
Selected option 1: {{ selectedText }}
<BR/>
<input type="radio" name="item1" value="0" v-model="selected" /> Empty
<BR/>
<input type="radio" name="item1" value="1" v-model="selected" /> Hi
<BR />
<input type="radio" name="item1" value="2" v-model="selected" />
<textarea name="textarea0" id="textarea0" cols="30" rows="10" v-model="values[2]" #focus="selected = '2'"></textarea>
</div>
Also the JSFiddle.
Update
As the questioner choose another answer, but i don't think that is the key point.
The reason is $forceUpdate() only force the view to re-render, not the computed properties. See the issue forceUpdate does not update computed fields
And i create a simple jsfiddle to descript it.
Raw Answer
The problem you faced is that vuejs cannot detect array change in some situation. You can see more detail in the doc vuejs list rendering
So the solution is replaced these code
this.selected[0] = '**custom**';
this.$forceUpdate();
with
this.$set(this.selected, 0, '**custom**')
While writing the answer I got an idea and it seems to work. However I still want to know if there is a "right" way of doing things which I'm missing.
The fix was to "click" the radio button instead of "checking" it:
$(e.target).prev().click();

Handling form submission without replacing template in VueJS

First of all, please be kind. I'm new to VueJS coming from the Angular world where things are different ;-)
I am creating a multi-page website using VueJS for simple things like a floaty header and submission of forms etc. I'd like the markup for my contact form to be in my HTML (rendered by the CMS) and I'd like to have VueJS handle the form submission and replacing the form with a thank-you message. So, a simplified version of the form would look like this.
<contact-form>
<form class="contact-form_form">
...
<input name="emailaddress" type="text" />
...
<button></button>
</form>
<div class="contact-form_thanks">
Thanks for filling in this lovely form
</div>
</contact-form>
So, the obvious thing to do is to create a VueJS component, but I don't want it to introduce a new template, I just want it to submit the form when the button is pressed (using Axios) and hide the form and show the thank you message.
I know how to do all of this in angular using attribute directives and ng-show/hide etc. but can't really see how to do this in VueJS because all the tutorials are geared to wards SPAs and Single file components with templates.
Any kick in the right direction would be appreciated.
Seems like you just want a data item indicating whether the form has been submitted, and v-if and v-else to control what displays in either case.
new Vue({
el: 'contact-form',
components: {
contactForm: {
data() {
return { hasBeenSubmitted: false };
},
methods: {
doSubmit() {
console.log("Some behind-the-scenes submission action...");
this.hasBeenSubmitted = true;
}
}
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<contact-form inline-template>
<div v-if="hasBeenSubmitted" class="contact-form_thanks">
Thanks for filling in this lovely form
</div>
<form v-else class="contact-form_form">
...
<input name="emailaddress" type="text" /> ...
<button #click.prevent="doSubmit">Submit</button>
</form>
</contact-form>

What is the proper way to use multiple heavy same VueJS components on a page?

I am trying to create custom input as VueJS component. It will have <input type="text"> field and button. This component must implement such behavior: you can type text with autocomplete or press button which opens modal dialog with records from database and then select one. Something like this:
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button" #click="openModal">Choose</button>
</span>
</div>
The modal dialog will contain complicated logic and a lot of HTML code. I think I will put modal dialog in other component.
After all my custom input component will be used on page in table rows like:
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
The table may contain 10-30 rows and that is a question - should I exclude heavy modal dialog code from my custom input component or it is fine in VueJS to have such many tens duplications in DOM?
What variant should I choose:
1) exclude modal dialog, place it once in top of page and call it from custom input components
<body>
<modal-component></modal-component>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td>
</tr>
</tbody></table>
</body>
2) include modal dialog and have tens of its duplicated code in DOM
<body>
<table><tbody>
<tr v-for="item in items">
<td><input-component :item="item"><input-component></td><!--now contains <modal-component></modal-component>-->
</tr>
</tbody></table>
</body>
Use a dynamic component and bind the component type to a reactive property.
Vue.component('customer-dialog', {
template: '<p>Customer Dialog</p>'
})
Vue.component('supplier-dialog', {
template: '<p>Supplier Dialog</p>'
})
var app = new Vue({
el: '#app',
data: {
dialog: null // initial dialog to use
},
methods: {
showDialog: function(d) {
this.dialog = d
// additional dialog initialization code
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<div id="app">
<component :is="dialog"></component>
<button #click="showDialog('customer-dialog')">Customers</button>
<button #click="showDialog('supplier-dialog')">Suppliers</button>
</div>
If you want to keep the switched-out dialogs in memory so that you can preserve their state or avoid re-rendering, you can wrap the dynamic component in a element.
<keep-alive><component :is="dialog"></component></keep-alive>
Just use one modal dialog for the whole page.
Fill in the dialog with relevant data from an array that will look like this
var dialogs = [
{ name: 'john', surname: 'snow' },
{ name: undefined, surname: undefined },
...
]
var currentDialog = 4
var dialogData = dialogs[currentDialog]