in Vuejs, is it possible to bind a model to a button? - vuejs2

Just starting to work with Vuejs - is it possible to bind a model to a button like so:
<button class="btn btn-outline-secondary" v-model="pricing" #click="showCountyModal = true">edit</button>
It doesn't appear to. Would the idiomatic pattern be to use:
<button class="btn btn-outline-secondary" #click="willShowCountyModal(pricing)">edit</button>
which does seem to work?

v-model in vuejs is used for two-way binding of data from model to template and template to model used for input field to bind data with model, you cannot add v-model to button, its not correct. So second approach is correct:
<button class="btn btn-outline-secondary" #click="willShowCountyModal(pricing)">edit</button>

Related

why event system markup is needed while functions can be passed as props

Vue has special template markup for event handling
<template>
<button type="button" #click="onClickFunction">
click me
</button>
</template>
but I have no idea why this event handling markup is needed since functions can be passed as props, the code above can change to
<template>
<button type="button" :onClick="onClickFunction">
click
</button>
</template>
Using v-bind syntax for event handling can save a lot docs, isn't it?
And making the template less DSL-ish, much easier to learn.
https://v2.vuejs.org/v2/guide/events.html

Syntax for variable class name (or within a v-if)

I have a loop and I'm creating many different buttons. In my data property, I have boolean values that I want to use to control whether to display an icon or a spinning loader.
I was thinking of using either a v-if or bind a class so that I apply css. I know the v-if and :class below are incorrect but I just want to show the 2 different approaches I have so far. What is the correct syntax for either of the approaches?
<button
v-for="action in actionTypes"
<div
class="btn btn-shell-grey">
<component
:is="`icon-${ action }`"
v-if="[`${ action }LoadingComplete`]"
:class="{ hidden: ![ action + 'LoadingComplete']}>
</component>
<icon-spin
v-if="![`${ action }LoadingComplete`]"
:class="{ hidden: ![ action + 'LoadingComplete']}>
</icon-spin>
</div>
</button>
data(){
return {
saveLoadingComplete: true,
uploadLoadingComplete: true
}
}
You're very close to having the correct syntax in the snippet you've provided.
To access your data via a dynamically constructed property name in your HTML, use $data, which proxies access to the data, like so:
v-if="$data[`${action}LoadingComplete`]"
And here's a basic working example of this in action.
I never had the need to use css to hide components in vue. I Always use conditional renders(https://v2.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show). In your case it should look something like this.
<button
v-for="action in actionTypes"
<div
class="btn btn-shell-grey">
<component
:is="`icon-${ action }`"
v-if="action.loadingComplete"
</component>
<icon-spin
v-if="!action.loadingComplete"
</icon-spin>
</div>
</button>

Vue v-model not reactive with BS4 radio button group

I'm hoping I'm just missing something simple because I've been looking at this for too long, but I'm stumped.
I have a form with inputs bound to vuejs. I have a group of 2 radio buttons for selecting the "gender", and the binding is working perfectly. If I click on either of the radio buttons, I can see the data change in the vue component inspector.
But I'm trying to change the radio buttons to a Bootstrap 4 button group, and can't seem to get the v-model binding to work. No matter what I try, the gender_id in my vue data is not getting updated when I click either of the buttons in the button group.
The form input values are being fed in through vue component properties, but for simplicity, my data for the radio buttons/button group would look like this:
export default {
data() {
return {
genders: {
1: "Men's",
2: "Women's"
},
gender_id: {
type: Number,
default: null
}
}
}
}
Here is the code I have for the radio button version (which is working properly):
<div class="form-group">
<label>Gender:</label>
<div>
<div class="form-check form-check-inline" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="form-check-input"
name="gender_id"
:id="'gender_' + key"
:value="key"
v-model.number="gender_id">
<label class="form-check-label" :for="'gender_' + key">
{{ gender }}
</label>
</div>
</div>
</div>
Here is the button group version that is not properly binding to the gender_id data in vue.
<div class="form-group">
<label>Gender:</label>
<div>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-outline-secondary" v-for="(gender, key) in genders" :key="key">
<input type="radio"
class="btn-group-toggle"
name="gender_id"
:id="'gender_' + key"
:value="key"
autocomplete="off"
v-model.number="gender_id">
{{ gender }}
</label>
</div>
</div>
</div>
I've been using the following Boostrap 4 documentation to try to get this working.
https://getbootstrap.com/docs/4.0/components/buttons/#checkbox-and-radio-buttons
In the documentation for button groups they don't even include the value property of the radio inputs, whereas they do include it in the documentation for form radio buttons.
https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios
Is this for simplicity or do button groups of radio buttons not even return the value of the checked button?
I see other threads stating that buttons groups are not meant to function as radio buttons, but if that's true for BS4, then why would Bootstrap have button groups with radio buttons as they do in their documentation referenced above? If you can't retrieve the checked state, then why not just use a <button> instead of <label><input type=radio></label>?
Any ideas as to what I'm doing wrong and/or not understanding correctly?
Thanks so much!
Thanks so much to #ebbishop for his helpful insights.
The issue was related to vue and bootstrap both trying to apply javascript to the buttons in the button group.
To get around this issue, it was as simple as removing data-toggle="buttons" from the button group. By removing the data-toggle attribute, the bootstrap js is not applied and vue can manage the button group.
Nothing is actually wrong your use of v-model here.
However: you must add the class "active" to the <label> that wraps each radio-button <input>.
See this fiddle for a working example.
Is that what you're after?

Validate a form with fields wrapped in another components in Aurelia

I'm wondering if I can validate a form with input fields that are wrapped in another components.
Something like this:
<template>
<require from="./inpWrap"></require>
<form submit.delegate="submit()">
<div class="form-group">
<inp-wrap value.bind="firstName & validate"></inp-wrap>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</template>
Here's the full gist: https://gist.run/?id=f94dd7502141f865468465ef25c9e5a1
Visually, in this example, the validation will run only on running the .validate() method (by clicking on the submit button) for the wrapped element.
Would it be possible to have the same validation behaviour for the component-wrapped elements?

Show or Hide buttons from property value

I have a list of items in a table and want to enable or disable some buttons based off a boolean property called "enabled". Code for the buttons are as follows
<button class="btn btn-sm btn-primary" show.bind="item.enabled" click.delegate="toggleEnabled()">Disable</button>
<button class="btn btn-sm btn-warning" show.bind="!item.enabled" click.delegate="toggleEnabled()">Enable</button>
No matter what the value for item.enabled, only the disable button shows. Wondering what I am missing?
click.delegate="item.toggleEnabled()" add the item. before toggleEnabled and you'll be good to go!
Here is an example with working code: https://github.com/AshleyGrant/skeleton-navigation/tree/so-answer-20150416-02/src
Make sure that item.enabled is being returned as a boolean and not a string.