VueJS multiple selection - laravel-5

I tried to multiple select with select2
i used laravel and my data on userRoles is returned data on User model with relation roles, and allRoles is just all in Role model
code on view
<select class="form-control" name="roles[]" id="roles" multiple>
<option v-for="role in allRoles"
:value="role.id"
>
#{{ role.name }}
</option>
</select>
how to set selected options using userRoles array?

Add a computed hashMap (object) to search for selected roles:
computed: {
selectedRoleMap() {
var map = {};
this.userRoles.forEach(role => {
map[role] = 1;
});
return map;
}
}
Then add :selected="selectedRoleMap.hasOwnProperty(role.id)" to options.
Working fiddle here: https://jsfiddle.net/df7j8xhz/
Alternatively, you can add a hasRole method to loop through userRoles to see if an id is in userRoles, but build a hashMap and search in it has a better performance than looping the array allRoles.length times.

Related

Vue Js2 cant kep old data from laravel on select option

I am working on a crud operation with vue js and laravel. Everything works fine but I am thinking of a small improvement to make the site more user friendly. So where i click edit button all my inputs have they old value (fetched from laravel) except selected options. They do not update with the corresponding values from the db and when i edit an record this is a problem . How can i set old value or coresponding value on this option
form select for my options
<div class="form-group">
<label class="form-label select-label" for="team_foreman">Team Skill</label>
<select v-model="edit_team_skills" class="form-select" id="team_foreman" >
<option v-if="!skills.length" class="text-center" disabled>No data to show</option>
<option v-for="skill in skills" :value="skill.id" :key="skill.id" >{{skill.skills_name}}</option>
</select>
</div>
vue data
data() {
return {
edit_team_skills: '',
}
}
//edit method
editTeam(id) {
axios.get('/teams/'+id+'/edit')
.then(response => {
// console.log(response.data.teams.skills)
this.id = response.data.teams.id,
this.edit_team_name = response.data.teams.team_name
.....
this.edit_team_skills = response.data.teams.skills
})
},
laravel edit controller
public function edit($id)
{
$teams = Team::with('skills')->find($id);
return response()->json([
'teams' =>$teams,
], Response::HTTP_OK);
}
The v-model of the select should be an array of active option values, as you fill those with the id of the skill you should make this.edit_team_skills an array of id's.
this.edit_team_skills = response.data.teams.skills.map(skill => skill.id)

How get old value of select in laravel 8 blade?

I am a beginner in Web and Laravel.I posted the same question yesterday but I delete it, because it is not clear for this I post again with more clarification. I have Select tag and a table, the table values change according to what I selected, When I select item the table is changed each time based on what I selected when I submit the Select all this works fine but the problem here is the Select lost the value I selected and goes back to the first element whose value '-1', please any suggestion to update my code to get the old value of Select after submit.
I load the same view twice with the same function the first with get an the second with post :
Route::get('/plaintes/trib', [PlainModelController::class,'suivi']);
Route::post('/plaintes/trib', [PlainModelController::class,'suivi']);
In my controller PlainModelController.php
public function suivi(Request $request)
{
$id_user = Auth::id();
$id_cour = explode('/', $id_user)[0];
$id_trib = ($request->choose_trib == "-1") ? $id_cour : $request->choose_trib;
$tribs = DB::select('SELECT CODE_TRIB as code_trib,
DESIG as desig
FROM TRIB
WHERE CODE_COUR = ? ORDER BY CODE_TRIB',[$id_cour]);
//query111 to fill the table it's work fine.
return view('suivi',compact('plaintes','tribs','id_trib'));
}
View suivi.blade.php:
<form action="/plaintes/trib" method="POST">
#csrf
<label for="choose_trib"> choose trib : </label>
<select name="choose_trib" id="choose_trib" onchange="this.form.submit()">
<option value="-1" > choose trib</option>
#foreach ($tribs as $trib)
<option value="{{ $trib->desig }}" {{ old('choose_trib') == $trib->desig ? 'selected' : '' }}> {{$trib->desig}}</option>
#endforeach
</select>
</form>
.....
I fill my table here with query111// It's work fine here.
.....

Use methods and computed properties in child component

In my List component I have a method which count the length of the array within certain categories.
methods: {
getLengthofaCategory(cat) {
const LowerCaseSearch = this.search.toLowerCase();
let categoryCount = this.products.filter(
product =>
(product.name.toLowerCase().includes(LowerCaseSearch) ||
product.category.toLowerCase().includes(LowerCaseSearch)) &&
(!this.checked.length || this.checked.includes(product.category)) &&
product.category === cat
);
return categoryCount.length;
}
}
See here my setup in this sandbox.
But I want the values next to the checkboxes (which are coming from my CheckBox component).
How do I get the logic from the method getLengthofaCategory into my CheckBox component?
So I am able to use {{ getLengthofaCategory('tennis') }} in the v-for loop, inside the CheckBox component. And then maybe I can also use category.value instead of hardcoding e.g 'tennis' as the paramater?
In your list.vue, you can use the already created computed function filteredData instead of doing the filter again. This saves some performance because in Vue, computed properties are "cached" once run.
So you can create a new computed function that creates an object with keys per category and value can either be just the amount or an array of products in this category.
I would then pass this computed value to the CheckBox component via a prop, then inside the CheckBox component, you can display the .length or value regarding how many items each category has:
List.vue:
computed: {
//...
amountPerCategory() {
return this.filteredData.reduce((categories, product) => {
if (!(product.category in categories)) {
categories[product.category] = [];
}
categories[product.category].push(product);
return categories;
}, {});
}
}
CheckBox.vue:
<span class="ml-2 text-gray-700 capitalize">{{ category.value }}</span> -
<span
v-if="count[category.value]"
class="ml-2 text-gray-700 capitalize"
>{{ count[category.value].length }}</span>
count: {
type: Object,
default: () => ({})
}
https://codesandbox.io/s/admiring-ellis-4hojl?file=/src/components/CheckBox.vue

How to create method to sort by property value (string)?

I'm creating the following list in Vue by iterating through payeefundingAccountList.
<cx-select id="payee-select" #cxChange="changeSelectedPayee" class="dropdown">
<option value="" disabled selected>Choose payment account</option>
<option
v-for="(account, index) in payeefundingAccountsList"
:value="index"
:key="index"
:checked="index === paymentAccountSelectedIndex"
>{{ account.bankName }}...{{account.displayAccountNumber}}({{account.accountType}})</option>
<option
v-bind:key="payeefundingAccountsList.length + 1"
v-bind:value="payeefundingAccountsList.length +1"
>Add a payment account</option>
</cx-select>
I need to sort this list by the property account.accountType. This property can have two values: CHECKING or SAVINGS and I need the items with accountType CHECKING to be sorted to the top.
I'm trying to create a method to run the list through before iterating, as such:
v-for="(account, index) in sortByAccountType(payeefundingAccountsList)"
...but, I'm having some trouble getting any sort of results from the sortByAccountType method. I feel like my approach is way off. If anyone could point me in the right direction, I'd be over the moon.
#Nikolas Yankov is right. But do yourself a favor and import the one function from lodash:_.sortBy. You can:
import _sortBy from ‚lodash/sortBy‘
export default {
computed: {
sortedAccountsList() {
return _sortBy(this.payeeFundingAccountsList, [‚accountType‘])
}
}
}
You can use a computed property where you can make your sorting before v-for loop start using it. For instance, if your collection "payeefundingAccountsList" is a data property in data, then the computed property would look like this:
computed: {
sortedList() {
return this.payeefundingAccountsList.sort(this._compare);
},
},
methods: {
_compare(a, b) {
if (a.accountType < b.accountType) {
return -1;
}
if (a.accountType > b.accountType) {
return 1;
}
return 0;
},
},
And then use this computed property in your v-for:
<option
v-for="(account, index) in sortedList"
/>

vue.js: vue-multiselect, clearing input value after selected

I am working on my project in laravel/vue.js and I decided to use simple vue-multiselect to choose categories from my database. Thing is I want to clear the value from input field (to look for item in list).
My multiselect component:
<multiselect
v-model="value"
placeholder="Find the category"
label="category_name"
:options="categories"
#input="addReceiversFromCategory">
</multiselect>
I try to clear an v-model but it work only on first select after page load (and also it is not a smart way..).
Last thing i try was the :clear-on-select="true" but it works onlu when multiple is true (which I dont want to be true).
I think its simple to do but I didn't find any way in documentation doc
If your v-model is just modeling the value selected, then you need to use that value however you want and reset value to null. I don't really know how your component is set up but it would look something like this:
<template>
<select v-model="value" v-on:change="doSomething()">
<option :value="null">-- Select --</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
</select>
</template>
<script>
module.exports = {
data: function(){
return {
value: null
};
},
methods: {
doSomething: function() {
if( this.value ) {
var data = this.value; // now you can work with data
this.value = null; // reset the select to null
}
}
}
}
</script>

Resources