vuejs - bootstrap-select options not working - javascript

I have this select:
<select v-model="filterState" #change="search()" class="selectpicker livesearch form-control" ref="stateSelect" id="stateSelect">
<option value="">Alle Status</option>
<option v-for="assignmentState in assignmentStates" v-bind:value="assignmentState.state">
{{ assignmentState.state }}
</option>
</select>
It will only work when I refresh it like this:
export default {
name: "AssignmentList",
data() { ....
},
updated() {
$(this.$refs.stateSelect).selectpicker('refresh');
}
But with this method the options like "livesearch" didn't work.
// Select2 Livesearch
$('.livesearch').selectpicker({
liveSearch: true,
noneSelectedText: 'Nichts ausgewählt',
});
I can enable the livesearch only with the "data-live-search" attribute like this:
<select v-model="filterState" #change="search()" data-live-search="true" class="form-control" ref="stateSelect" id="stateSelect">
But I want to set the options in my JS file without using the data attributes.
How can I did this?

first thing in your v-for you need to bind a key, see the doc for better explanation.
second advice, if you can, don't mix jquery with vue, you don't need to do that, eg:
$(this.$refs.stateSelect).selectpicker('refresh');
can be:
this.$refs.stateSelect.selectpicker('refresh'); // this can be wrong because selectpicker need a jquery object, but se the logic XD
i don't understand very well wich is your purpose, but i think you can use the watch hook:
watch: {
filterstate(){//v-model of select
$('.livesearch').selectpicker({
liveSearch: true,
noneSelectedText: 'Nichts ausgewählt',
});
}
}
with vue for the ui you can use bootstrap-vue or vuetify

Related

How can I pass a param to a custom validator?

I have the below custom validator, which is working great when passed to my input like this:
<select id="salesOwnerIdInput" v-model="currentCompany.salesOwnerId" name="salesOwnerId"
v-validate.immediate="{ 'required': salesOwnerRequired, 'contains': !userHasPlanAccess }"
:class="{'form-control': true, 'is-invalid': errors.has('main-tab.salesOwnerId') }"
data-vv-as="Sales Owner"
data-vv-scope="main-tab">
<option value="">- Select -</option>
<option v-for="option in ownerList" v-bind:value="option.id" v-bind:key="option.id">
{{ option.name }}
</option>
</select>
But as soon as I try to add a param
v-validate.immediate="{ 'required': salesOwnerRequired, 'contains:test': !userHasPlanAccess }"
I get this stupid error
vee-validate.esm.js:290 Uncaught (in promise) Error: [vee-validate] No such validator 'contains:test' exists.
What am I doing wrong??
const ContainsValidator = {
params: [
'message'
],
getMessage(field, args) {
return 'get message from args';
},
validate(value, args) {
return false;
}
}
I tried adding the param name to my registration, but it has no effect - I'm not sure if this even makes sense?
VeeValidate.Validator.extend("contains", ContainsValidator, { paramNames: ['message'] });
I am using vee-validate 2.1.4
I managed to solve it by calling the validator like this
v-validate.immediate="`required:${salesOwnerRequired}|contains:testMessage,${salesOwnerHasPlanAccess}`"
So passed the entire ruleset as a string, and interpolated anything that needed to be passed down

vuejs2 with select option get the value and other attribute

I'm using vuejs.
Let's say I have select and inside I have multiple options
like this:
<select v-model='line.unit' name='unit[]' required #change='change_unit($event)'>
<option v-for='(unit) in line.units' price='line.price' :value='unit.id'>#{{unit['get_unit_id']['name']}}</option>
<option selected class='selected' price='line.price' v-if='line.smallest_unit' :value='line.smallest_unit.id'>#{{line.smallest_unit['name']}}</option>
</select>
And this is the change_unit method:
change_unit:function($event)
{
}
How can I access the attribute price if I want the value of the selected option? I can get it like this ..
console.log(event.target.value);
But now can I access the price value attribute?
you could tweak the option value binding it to Vue.js
as you can see in this fiddle, which I'll explain here
Consider this HTML
<div id="app">
<select v-model="line.unit" name='unit[]' required>
<option v-for='(unit) in line.units' :value="unit">
{{unit.name}}
</option>
</select>
<h2 v-if="line.unit">
{{line.unit.price}}
</h2>
</div>
As you can see, I'm setting the <option> value binding it to unit, which is each single line.units item object. by doing that, selecting an option will actually set the v-model to unit, instead of an object's attribute
Consider this JS, in which I've created a hypotetic reproduction of your .data.
new Vue({
el: '#app',
data() {
return {
line: {
unit: {},
units: [{
id: 1,
price: 100,
name: 'foo'
},{
id: 2,
price: 200,
name: 'bar'
}]
}
}
}
})
Selecting an option will now show you it's price (I've put a <h2> as a demonstration)

VueJS 2.0 v-model dynamic target inside v-for

I've got a form with about 10 select elements built from an array in my Vue data.
The array of selectors is empty initially and then an AJAX call populates the array and Vue builds the HTML - I've kept the snippet below simplified just to demonstrate the issue I'm having with v-model
I want to create an object that has all the selected values in it, so I'm trying to use v-model="selected[ selector.name ]" as per the example below.
I want to easily be able to ask for selected.make or selected.fuel
Now this works if I initialize the selected property like this:
selected: { make: 'audi', fuel: 'petrol' }
If I leave it blank, like in the example, {}, then it doesn't get updated.
I don't want to manually hardcode all the properties of selected, I only want to be listing them once in the server side code that gets sent via AJAX
So am I missing something completely obvious, should I be doing this in a different way?
Maybe a method to find the dropdown that matches a field name and returns the value? Just that doesn't seem like a very Vue thing to do.
var app = new Vue({
el: '#example',
data: {
selectors: [
{
name: 'make',
options: ['audi','bmw']
},
{
name: 'fuel',
options: ['petrol','diesel']
}
],
selected: {}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="example">
<template v-for="selector in selectors">
<select v-model="selected[ selector.name ]">
<option v-for="option in selector.options">{{option}}</option>
</select>
</template>
<p>
{{selected.make}}
<br />
{{selected.fuel}}
</p>
</div>
it's probably becuase you're not setting new keys on an object with this.$set
try:
this.$set(this.selected, 'make', 'audi')
Not using this.$set - alias of Vue.set - will mean Vue doesn't set the new key as reactive, and in turn won't be watching for any updates to it, docs: https://v2.vuejs.org/v2/api/#vm-set
var app = new Vue({
el: '#example',
data: {
selectors: [{
name: 'make',
options: ['audi', 'bmw']
}, {
name: 'fuel',
options: ['petrol', 'diesel']
}],
selected: null,
},
created () {
// this would happen following your ajax request - but as an example this should suffice
this.selected = {}
this.selectors
.forEach((selector) => {
this.$set(this.selected, selector.name, '')
})
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.3/vue.js"></script>
<div id="example">
<div v-if="selected">
<select v-model="selected[selector.name]" v-for="selector in selectors">
<option :value="option" v-for="option in selector.options">
{{option}}
</option>
</select>
<p>make: {{selected.make}}<p>
<p>fuel: {{selected.fuel}}</p>
<pre>{{ selected }}</pre>
</div>
</div>

Select2 Default values for multiple select and allowed tags

I have a select 2 multi-select option
<select multiple name="event_type[]" class="form-control" id="selectEvents">
#foreach ($eTypes as $type)
<option>{{$type}}</option>
#endforeach
</select>
I want to set some default values just in case the user is editing the form.
I have successfully done that by doing this
var s2 = $("#selectEvents").select2({
placeholder: "Choose event type",
tags: true
});
s2.val(["Trade Fair", "CA", "Party"]).trigger("change"); //CA doesn't show as a default
But the problem is i am allowing user generated options using the tags: true option for select2.
When I set a default value that was initially in the html options it works, but when I set a default that was user generated it doesn't work.
It is my first time using select2.
How can i achieve this?
Doing a little digging, I can see this issue raised on GitHub.
One option is to check to see if the value exists, and append it if it doesn't.
var s2 = $("#selectEvents").select2({
placeholder: "Choose event type",
tags: true
});
var vals = ["Trade Fair", "CA", "Party"];
vals.forEach(function(e){
if(!s2.find('option:contains(' + e + ')').length)
s2.append($('<option>').text(e));
});
s2.val(vals).trigger("change");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.css" rel="stylesheet"/>
<select multiple name="event_type[]" class="form-control" id="selectEvents">
<option>Trade Fair</option>
<option>Party</option>
<option>Foo</option>
<option>Bar</option>
</select>
An other simple way is set value to select option and make it select2
again :
$('#properties').val(["Trade Fair", "CA", "Party"]);
$('#properties').select2({});
It is working for me
Little improvement:
$('#province').val(["3", "4", "5"]).trigger('change');
I recently had to implement a select2 with options 'multiple' and 'tags' in a PHP script, and ran into a similar problem. The documentation said to add any initial selections as html option tags, but when I tried to add two, only one would show up in my select2 control.
I ended up initializing the select2 control with the config object 'data' option, which I would create dynamically.
var initialPropertyOptions = [];
#foreach ($model->properties as $initialProperty`)
var initialPropertyOption = {
id: {{ $initialProperty->id }},
text: '{{ $initialProperty->name }}',
selected: true
}
initialPropertyOptions.push(initialPropertyOption);
#endforeach
$('#properties').select2({
ajax: {
url: route('models.propertySearch'),
dataType: 'json',
delay: 250,
processResults: function(data) {
return {
results: data
}
}
},
placeholder: 'Enter property name',
minimumInputLength: 1,
multiple: true,
tags: true,
data: initialPropertyOptions
});
<div>
<label for="properties">Properties</label>
<select name="properties[]" id="properties">
</select>
</div>

AngularJS option selected

I know there's been a lot of questions for this but I am having the most annoying time figuring out how AngularJS handles select option values and which one is selected. I have a simple item which I pass onto a modal window. This item contains template_id. I also have templates which have a name and an id and I wish to create a simple select where the option which has the value of the item's template_id gets selected:
<select name="templateId">
<option value="8000">name</option>
<option value="8001" selected>name 2</option>
</select>
Now with AngularJS I do this:
<select name="templateId"
ng-model="domain.templateId"
ng-options="t.template_id as t.name for t
in templates track by t.template_id">
<option value="">Choose template</option>
</select>
In the controller I set the 'selected' value with:
Data.get('templates').then(function(result) {
$scope.templates = result;
});
$scope.domain = {
template_id: item.template_id,
templateId: { template_id: item.template_id }
};
I have actually gotten to a point where I can send the template_id to the REST API and the response there reads
template_id: 8000
However, there is some minor annoying behaviour in the select element. I get the item I want selected, but when I attempt to select another option it switches the selected to the pre-set 'Choose template' option but the value or rather the 'real selected item' is still the original "selected" value I set in the controller. I can see it in the REST API response. This is not however what I selected. After this initial bug it continues to work as it's supposed to but how can I get rid of this?
Here a example to solve your issue.
angular.module('app.select', [])
.controller('SelecetCtrl', function($scope) {
$scope.templates = [{
template_id: 1,
name: 'tst1'
}, {
template_id: 2,
name: 'tst2'
}, {
template_id: 3,
name: 'tst3'
}];
$scope.selected = {
template: {
template_id: 2
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app.select'>
<div ng-controller='SelecetCtrl'>
<select name="templateId" ng-model="selected.template"
ng-options="t as t.name for t
in templates track by t.template_id">
<option value="">Choose template</option>
</select>
</div>
</div>

Categories