How to use Bootstrap button-group radios with Vue's v-model? - vue.js

I'm using vuejs with bootstrap 4.4. Refactoring the code I'd like to move from invoking methods to using v-model (some bootstrap markup omitted for clarity). The radios button group is modeled after https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons:
{{mode}}
<div class="btn-group btn-group-toggle py-4 mb-2" data-toggle="buttons">
<label>
<input type="radio" name="mode" value="off" v-model="mode">Stop</input>
</label>
<label>
<input type="radio" name="mode" value="now" v-model="mode">Sofort</input>
</label>
</div>
mode is a simple property:
data: function () {
return {
mode:"pv",
};
},
Unfortunately, after changing from the previous implementation using v-on:click="setMode(...)" to v-model, mode is never updated, no error given.
The bootstrap docs state:
The checked state for these buttons is only updated via click event on the button
Might that conflict with vuejs's v-model handling? How can I make v-model work with bootstrap radio groups?

Issue is with data-toggle property, as long as you remove it, it will work. I have tried with following and it is working, you just need to manage active class with Vue variable's value.
<div id="app">
{{mode}}
<div class="btn-group btn-group-toggle">
<label class="btn btn-secondary active">
<input type="radio" name="options" value="now" id="option1" v-model="mode" autocomplete="off" checked> Active
</label>
<label class="btn btn-secondary">
<input type="radio" name="options" value="off" id="option2" v-model="mode" autocomplete="off"> Radio
</label>
</div>
</div>

Related

VUE pass value from checkbox from multiple checkboxes from v-for element

my html
<div v-for="(client, index) in clients" :key="index">
<div>
<span>{{index+1}} {{client.id}}</span>
</div>
<div>
<div>
<label>
<input type="checkbox" :checked="client.IsScreenShot"/>
<span class="slider"></span>
</label>
</div>
<div>
<label>
<input type="checkbox" :checked="client.IsPhotoReport" />
<span class="slider"></span>
</label>
</div>
<div>
<label>
<input type="checkbox" :checked="client.IsShowReport" />
<span class="slider"></span>
</label>
</div>
<button type="submit" #click.prevent="onChangeAccess(client)">Change</button>
</div>
</div>
I have multiple checkboxes in div thats coming from v-for and array of data.
Each checkbox is came from data and give true or false value to start position, thats represent value right now.
When user check or uncheck checkbox (it depends want he or not give to client right to see pages on site), I want to take new value from check box and send it to server.
How I can take this new value from each checkbox?
And this is array of div's with three checkboxes in each div, but I need at time only this specific change value from this specific div. I don't need to know if every value in multiple div change. I need to pass only this specific changes value from 1 this div.
For example at first user get 1 div with first input value true, second - false, third - true.
Then user change checkboxes to first input - false, second - true, third - true.
So when he clicked on button, I need to get value from first, second and third checkbox and pass it to method.
How I can get it? any idea please
Vue is perfect, so I find a great solution, hope it helps someone, I just little correct the code
<div v-for="(client, index) in clients" :key="index">
<div>
<span>{{index+1}} {{client.id}}</span>
</div>
<div>
<div>
<label>
<input type="checkbox" :checked="client.IsScreenShot" #click="client.IsScreenShot = !client.IsScreenShot"/>
<span class="slider"></span>
</label>
</div>
<div>
<label>
<input type="checkbox" :checked="client.IsPhotoReport" #click="client.IsPhotoReport = !client.IsPhotoReport"/>
<span class="slider"></span>
</label>
</div>
<div>
<label>
<input type="checkbox" :checked="client.IsShowReport" #click="client.IsShowReport = !client.IsShowReport"/>
<span class="slider"></span>
</label>
</div>
<button type="submit" #click.prevent="onChangeAccess(client)">Change</button>
</div>
</div>
God save Vue =)

VueJS - v-model in for-loop

I'm trying to build something like the questions in OkayCupid, but all the questions - which are different forms - are located on the same component.
I use an object of questions and 3 possible answers for each question, and I use v-for to loop through the object and create cards with a question, 3 answers with radios, and a submit button.
The problem is that I want to get not only the answer the user chooses, but also the question it belongs to.
Here is my form in the template:
<div class="container">
<div class="row">
<div
class="col-lg-3 col-md-4 col-6"
v-for="(question,index) in questionCollection"
:key="index"
>
<form class="form">
<div class="img-fluid img-thumbnail shadow-lg p-3 mb-5 bg-white rounded">
<!-- <input type="text" :value="question.question" v-model="q" /> -->
<h3 class="d-block mb-4 h-100" alt data-holder-rendered="true">{{ question.question }}</h3>
<div class="card-body container">
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a1"
:value="question.answer1"
v-model="answer"
/>
<h4 class="font-weight-light" for="a1">{{ question.answer1 }}</h4>
</div>
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a2"
:value="question.answer2"
v-model="answer"
/>
<h4 class="font-weight-light" for="a2">{{ question.answer2 }}</h4>
</div>
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a3"
:value="question.answer3"
v-model="answer"
/>
<h4 class="font-weight-light" for="a3">{{ question.answer3 }}</h4>
</div>
</div>
<div class="card-text container">
<small class="text-muted">{{ question.user }}</small>
<button
href="#"
class="btn btn-primary my-3 mx-10 btn float-right shadow-sm rounded"
#click.prevent="answerQuestion"
>Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
And the script:
export default {
name: "questions",
data() {
return {
q: null,
answer: null
};
},
}
As you can see, at the beginning of the form, I tried to get the question element using v-model in a "fake" input, but it gives me an error that it's conflicted with the v-bind of the value (the question) I want to grab. Of course, I can't use v-model on the headline itself because Vue allows to use it only on inputs.
I've tried to change the v-model into v-model="questionCollection[index].question, but then I have no idea how to get it in the script and, let's say, log it to the console with the corresponding answer.
One way to handle this is to submit the question and answer together in the Save button's click-handler. That is, change answerQuestion() to receive question (the iterator variable in v-for) and answer, and update the Save button's click handler in the template to pass those two variables:
// template
<div v-for="(question, index) in questionCollection">
...
<button #click.prevent="answerQuestion(question, answer)">Save</button>
</div>
// script
answerQuestion(question, answer) {
console.log({ question, answer })
}
demo

Calling a method in a modal initially hidden (transition)

I have a simple method "updateTotal" initialized in my app / vue :
// start app
new Vue({
el: '#app2',
data: {
showModal1: false,
showModal2: false,
total : 0
},
methods: {
updateTotal: function (num) {
this.total = this.total + num
}
}
})
When I call this method from by example a button in the HTML code in the app2 section, it's OK (text "total" updated).
When I call this method from a div section hidden at the loading of the page (it's a modal, with vue.js "transition" system), I have this error :
Property or method "updateTotal" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
The code of this modal / transition (it's IN the app2 div) is :
<!-- template for the modal component SERVICES-->
<script type="text/x-template" id="modal2-template">
<transition name="modal2">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-container">
<div class="modal-header">
<slot name="header">
Header
</slot>
</div>
<div class="modal-body">
<!-- LISTE SERVICES -->
<div>
<div>
<div class="control">
<label class="radio">
<input type="radio" name="service1" v-on:click="updateTotal(10)">
Oui
</label>
<label class="radio">
<input type="radio" name="service1" checked v-on:click="updateTotal(-10)">
Non
</label>
</div>
</div>
<div>
<div class="control">
<label class="radio">
<input type="radio" name="service2" v-on:click="updateTotal(20)">
Oui
</label>
<label class="radio">
<input type="radio" name="service2" checked v-on:click="updateTotal(-20)">
Non
</label>
</div>
</div>
</div>
<!-- LISTE SERVICES -->
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button class="modal-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</div>
</transition>
</script>
What can I do to be able to call this method from this modal / transition div ?
Thanks !
MAMP MySQL PHP5
The issue occurs since you try to call updateTotal() from within the template of a different component.
The context within the template is always the component itself (this). Since the method updateTotal() is not defined in this component, you cannot call it.
There are several workarounds, but I consider two the cleanest:
For simple projects/apps: emit an event that triggers the method in the parent (like your close event)
For more complex apps: Use shared state with Vuex and make your method an action

VueJS simple togooling with radio buttons

My requirement is something like this.
I have two radio buttons namely Live Paper and Normal Paper
If user select Live Paper another two html input elements(datatime-local,time) must be shown.
If the user selected the Normal Paper these two additional input elements should be hide.
How do I achieve this through vueJS.
This is my code.
<div class="row">
<div class="col">
<input type="radio" name="paper" value="">Live Papaer
<br>
Live on <input type="datetime-local" name="" value="" > Time <input type="time" name="" value="">
</div>
<div class="col">
<input type="radio" name="paper" value="">Normal Paper
</div>
</div>
Just initialize a property named selected in your data option
new Vue({
el:"#app",
data(){
return{
selected: 'live'
}
}
})
Bind this selected property to both the radio inputs. See that the value attribute of radio inputs is set to live and normal respectively
Set up v-if on the div you conditionally want to render. The v-if is only true when selected === 'live'
<div id="app">
<div class="row">
<div class="col">
<input type="radio" name="paper" v-model="selected" value="live">Live Papaer
<div v-if="selected === 'live'">
Live on <input type="datetime-local" name="" value="" > Time <input type="time" name="" value="">
</div>
</div>
<div class="col">
<input type="radio" name="paper" v-model="selected" value="normal">Normal Paper
</div>
</div>
Here is the fiddle
Reference: radio inputs
Have a look to these documentations :
VueJS Forms : Basics
Vue JS Forms : Radio buttons
Vue JS Conditional Rendering
Also, from the community, you can find a lot of resources to understand View Binding and Forms in VueJS :
Understand what's behind v-model
2-Way Binding in Vue with V-Model - Vue.js 2.0 Fundamentals

bootstrap remove active class from radio type btn-group

I am creating a bootstrap btn-group that I want to give the user the ability to select one or no options from. Everything on the data end is working great except for the fact that I can not remove the active class from the button when the user turns it off.
<div class="btn-group" id="localRasterBG" data-toggle = "buttons">
<label class="btn btn-default localBaseMaps" id="btnLand Cover" data-layerName="Land Cover" onclick="rasterButtonClick(event)" >
<input type="radio" name="options" id="btnLandCover" autocomplete="off"> Land Cover
</label>
<label class="btn btn-default localBaseMaps" data-layerName="Elevation" onclick="rasterButtonClick(event)">
<input type="radio" name="options" id="btnElevation" autocomplete="off"> Elevation
</label>
<label class="btn btn-default localBaseMaps active" id="btnPopulation" data-layerName="Population" onclick="rasterButtonClick(event)">
<input type="radio" name="options" id="btnLandScan" autocomplete="off"> Population
</label>
</div>
However, I am unable to remove the "active' class with javascript:
function rasterButtonClick(e){
e.target.removeClass("active");
}
Any idea what I could be doing wrong?
Thanks, Tyler
removeClass is a jQuery function, you need to change it to:
$(e.target).removeClass("active");