V-for in alphabetical order - sorting

I'm having some issues sorting/ordering my v-for table in alphabetical order. I've tried things like Sort an array in Vue.js but I can't get it to work for me?
<tbody>
<tr v-for="(client, index) in clients" :key="index">
<td>{{ client.name }}</td>
<td>{{ client.contactpersonfirstname }} {{ client.contactpersonlastname }}</td>
<td>{{ client.email }}</td>
<td>{{ client.phone }}</td>
<td>
<div :class="{ active: index == currentIndex }" #click="setActiveClient(client, index)">
<a class="badge badge-success" :href="'/clients/' + client.id" >Open</a>
</div>
</td>
</tr>
</tbody>
<script>
import ClientDataService from "../services/ClientDataService";
export default {
name: "clients-list",
data() {
return {
clients: [],
currentClient: null,
currentIndex: -1,
name: "",
};
},
methods: {
retrieveClients() {
ClientDataService.getAll()
.then(response => {
this.clients = response.data;
// eslint-disable-next-line no-console
console.log(response.data);
})
.catch(e => {
// eslint-disable-next-line no-console
console.log(e);
});
},
setActiveClient(client, index) {
this.currentClient = client;
this.currentIndex = index;
},
},
mounted() {
this.retrieveClients();
}
};
</script>
Hope you can help - let me know of you need more of my code.
//Rue

You need to write your own sorting function if you want to sort array of objects (clients) or use some 3rd party library like loadash or underscore.
With usage of underscore library, your code would then look something like this:
<template>
<tbody>
<tr v-for="(client, index) in sorted" :key="index">
<td>{{ client.name }}</td>
<td>
{{ client.contactpersonfirstname }} {{ client.contactpersonlastname }}
</td>
<td>{{ client.email }}</td>
<td>{{ client.phone }}</td>
<td>
<div
:class="{ active: index == currentIndex }"
#click="setActiveClient(client, index)"
>
<a class="badge badge-success" :href="'/clients/' + client.id"
>Open</a
>
</div>
</td>
</tr>
</tbody>
</template>
<script>
import _ from "underscore";
import ClientDataService from "../services/ClientDataService";
export default {
name: "clients-list",
data() {
return {
clients: [],
currentClient: null,
currentIndex: -1,
name: "",
};
},
computed: {
sorted(){
return this.clients ? _.sortBy(this.clients, "name") : [];
}
}
methods: {
retrieveClients() {
ClientDataService.getAll()
.then(response => {
this.clients = response.data;
// eslint-disable-next-line no-console
console.log(response.data);
})
.catch(e => {
// eslint-disable-next-line no-console
console.log(e);
});
},
setActiveClient(client, index) {
this.currentClient = client;
this.currentIndex = index;
},
},
mounted() {
this.retrieveClients();
}
};
</script>

This code is work if you want to sort by name:
<tr v-for="(client, index) in clients.sort((a, b) => (a.name > b.name) ? 1 : -1)" :key="index">
<td>{{ client.name }}</td>
<td>{{ client.contactpersonfirstname }} {{ client.contactpersonlastname }}</td>
<td>{{ client.email }}</td>
<td>{{ client.phone }}</td>
<td>
<div :class="{ active: index == currentIndex }" #click="setActiveClient(client, index)">
<a class="badge badge-success" :href="'/clients/' + client.id" >Open</a>
</div>
</td>
</tr>
You can sort by order fields, just change field name with another field in v-for

Related

Laravel datatables can't create custom columns

I have two tables first one simple html with no datatables, second with datables. My purpose transform first table two datatables second. But I had two main problems Grazinimo terminas column is using laravel #if and column Veiksmai using if statemens as well how can i add those as custom columns in second table.
First table code
<table class="table table-bordered">
<thead class="bg-warning">
<th>Knygos pavadinimas</th>
<th>Miestas</th>
<th>Išdavimo data</th>
<th>Grąžinimo terminas</th>
<th>Vardas</th>
<th>Pavardė</th>
<th>Kliento nr.</th>
<th>Veiksmai</th>
</thead>
<tbody>
#foreach($paskolinimai as $p)
<input type="hidden"
value="{{ $skirtumas = \Carbon\Carbon::parse(\Carbon\Carbon::today()->toDateString())->diffInDays( \Carbon\Carbon::parse( $p->terminas),false) }}">
<tr>
<td>{{ $p->pavadinimas }}</td>
<td>{{ $p->miestas }}</td>
<td>{{ $p->isdavimo_data }}</td>
#if($p->grazinimo_data != NULL)
<td>
<strong style="color: green;">Knyga grąžinta!</strong>
</td>
#elseif($skirtumas > 0)
<td>
Liko <strong style="color: crimson;">{{ $skirtumas }}</strong> dienų.
</td>
#elseif($skirtumas < 0) <td>
<strong style="color: crimson;">Terminas praėjo!</strong>
</td>
#elseif($skirtumas = 0)
<td>
<strong style="color: crimson;">Šiandien paskutinė grąžinimo diena!</strong>
</td>
#endif
<td>{{ $p->vardas }}</td>
<td>{{ $p->pavarde }}</td>
<td>{{ $p->klientasnr }}</td>
#if($p->grazinimo_data == null)
<td><a href="{{ url('patvirtinti-grazinima-'.$p->id.'-'.$p->bookid) }}"
class="btn btn-primary">Grąžinimas</a> </td>
#else
<td>
<p class="btn btn-success">Grąžinta</p>
</td>
#endif
#endforeach
</tr>
</tbody>
</table>
Second table code
<script>
$(document).ready(function () {
var darbuotojai = $('#paskolinimai').DataTable({
processing: true,
serverSide: true,
ajax:
{
url: '{!! route('get.paskolinimai') !!}'
},
columns: [
{ data: 'pavadinimas', name: 'pavadinimas' },
{ data: 'miestas', name: 'miestas' },
{ data: 'isdavimo_data', name: 'isdavimo_data' },
{ data: 'vardas', name: 'vardas' },
{ data: 'pavarde', name: 'pavarde' },
],
'oLanguage': {
'sSearch': "Paieška:",
'sZeroRecords': "Nerasta atitinkančių įrašų",
'sLengthMenu': "Rodyti _MENU_ įrašų",
'sInfo': "Nuo _START_ iki _END_ viso _TOTAL_ įrašų",
'sProcessing': "Apdorojama...",
'sLoadingRecords': "Kraunama...",
'sInfoFiltered': " - (filtruojama iš _MAX_ įrašų)",
'oPaginate': {
'sFirst': "Pirmas",
'sLast': "Paskutinis",
'sNext': "Sekantis",
'sPrevious': "Ankstesnis"
},
},
'sDom': '<"top"lfip>rt<"bottom"p><"clear">',
});
});
</script>
<table id="paskolinimai" class="table table-bordered">
<thead class="bg-warning">
<th>Knygos pavadinimas</th>
<th>Miestas</th>
<th>Išdavimo data</th>
<th>Vardas</th>
<th>Pavardė</th>
</thead>
<tbody></tbody>
</table>
</div>
So how can i add Grazinimo terminas and veiksmai correctly to the second table
I recommend you to use this package:
https://yajrabox.com/docs/laravel-datatables/master/installation
then go to section add column:
https://yajrabox.com/docs/laravel-datatables/master/add-column
and in your code will be like that:
->addColumn('intro', function(User $user) {
if($condtion){return $result}
})

How to count v-for object with if condition

I try to count totalPaids(transaction.paid).
vue component:
<tr v-if="studentFees" v-for="(studentFee, index) in studentFees">
<td style="text-align: center;">{{ index+1 }}</td>
<td style="text-align: center;">{{ studentFee.programe }}</td>
<td style="text-align: center;">{{ studentFee.level }}</td>
<td style="text-align: center;">{{ studentFee.course_fee }}</td>
<td style="text-align: center;">{{ studentFee.student_amount }}</td>
<td style="text-align: center;">{{ studentFee.discount }}</td>
<div v-for="studentTransaction in studentTransactions">
<div v-if="studentTransaction.s_fee_id == studentFee.s_fee_id">
<td style="text-align: center;">{{ totalPaids(studentTransaction.paid) }}</td>
</div>
</div>
</tr>
or see https://i.stack.imgur.com/aGoLo.png
in vue method:
totalPaids(values){
console.log(values)
}
console.log: 3000, 5000, 2000, 1000
please help to sumation.
Working snippet:
new Vue({
el: '#app',
data: {
message: 'p',
sum:0
},
methods:{
totalPaids: function(values){
this.$data.sum+= Number(values);
console.log( this.$data.sum);
return this.$data.sum;
}
},
mounted(){
for(var i=0;i<5;i++)
this.message=this.totalPaids(900);
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<p>{{ message }}</p>
</div>
I would suggest you to register the variable in the data section to save it's state:
data: {
sum: 0,
},
Later modify the method totalPaids like this:
totalPaids(values){
this.sum+= Number(values);
console.log(sum);
return sum;
}
Hope this helps.
Assuming your values is an array of numbers then you can use the reduce method in JavaScript. So you can adjust your TotalPaid function to this:
totalPaids(values){
var sum = values.reduce((sum, currentVal) => sum + currentVal);
console.log(sum);
return sum;
}
So this just takes your array of values, then runs through them adding the current value to the sum value each time.

vuejs loopin over array of objects as a prop renders incorrectly compared to hardcoding as data

When I try to pass an array of objects to my component as a prop...
[{"prize":"first","abbr":"1st Prize","value":"50"},{"prize":"second","abbr":"2nd Prize","value":"30"},{"prize":"third","abbr":"3rd Prize","value":"20"}]
...I don't get 3 columns that I expected, but I get over 100, and I'm missing my placeholder and data attribute in the text box.
export default {
props: ['settings', 'colour', 'draw_type'],
data: function() {
return {
prizes: {
first: {
name: '',
telephone: ''
},
second: {
name: '',
telephone: ''
},
third: {
name: '',
telephone: ''
},
fourth: {
name: '',
telephone: ''
}
}
}
},
...
...
How can I fix my code so I can pass a given array of objects as a prop and still render it correctly?
When I hardcode settings, the table renders properly:
<template>
<form #submit.prevent="submit" class="mb-5">
<div class="row">
<div class="col-md-3" v-for="(setting, index) in settings">
<p>{{setting.abbr}}</p>
<div class="card">
<div :class="colour">
<div class="box">
{{ setting.prize }}
</div>
</div>
<div class="card-body text-center">
<h5 class="card-title">£{{ setting.value }}</h5>
<div class="form-group">
<input type="text" class="form-control" :placeholder="setting.abbr" maxlength="2" :data-prize="setting.prize" v-model="setting.prize">
</div>
</div>
</div>
</div>
</div>
<table class="table table-striped">
<tr>
<th>Prize</th>
<th>Number</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr v-for="(setting, index) in settings">
<td>£{{ setting.value }}</td>
<td>{{ setting.prize }}</td>
<td>{{ prizes[setting.prize].name }}</td>
<td>{{ prizes[setting.prize].telephone }}</td>
</tr>
</table>
<div class="form-group row">
<div class="col-sm-8">
<button type="submit" class="btn btn-primary">
Save Results
</button>
</div>
</div>
</form>
</template>
<script>
export default {
props: ['colour', 'draw_type'],
data: function() {
return {
settings: [
{
"prize":"first",
"abbr":"1st Prize",
"value":"50"
},
{
"prize":"second",
"abbr":"2nd Prize",
"value":"30"
},
{
"prize":"third",
"abbr":"3rd Prize",
"value":"20"
}
],
prizes: {
first: {
name: '',
telephone: ''
},
second: {
name: '',
telephone: ''
},
third: {
name: '',
telephone: ''
},
fourth: {
name: '',
telephone: ''
}
}
}
},
mounted() {
console.log(this.settings);
}
};
</script>
Add key on element v-for maybe is your issue
<tr v-for="(setting, index) in settings" :key="index">
<td>£{{ setting.value }}</td>
<td>{{ setting.prize }}</td>
<td>{{ prizes[setting.prize].name }}</td>
<td>{{ prizes[setting.prize].telephone }}</td>
</tr>
By default, props are string types, so when you pass in an object array, it will be interpreted as a string. The v-for iterates the string as an array of characters, which might explain the 100+ items without the expected properties.
The prop types should be set like this:
export default {
props: {
settings: {
type: Array,
default: () => []
},
colour: String,
draw_type: String
},
}
Vue.component('prizes', {
template: `<table class="table table-striped">
<tr>
<th>Prize</th>
<th>Number</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr v-for="(setting, index) in settings">
<td>£{{ setting.value }}</td>
<td>{{ setting.prize }}</td>
<td>{{ prizes[setting.prize].name }}</td>
<td>{{ prizes[setting.prize].telephone }}</td>
</tr>
</table>`,
props: {
settings: {
type: Array,
default: () => []
},
colour: String,
draw_type: String
},
data() {
return {
prizes: {
first: {
name: 'jack',
telephone: '(555) 111-1111',
},
second: {
name: 'jill',
telephone: '(555) 222-2222',
},
third: {
name: 'james',
telephone: '(555) 333-3333',
},
fourth: {
name: 'jane',
telephone: '(555) 444-4444',
}
}
}
}
})
new Vue({
el: '#app',
data: () => ({
settings: [
{
prize: 'first',
abbr: '1st Prize',
value : 50
},
{
prize: 'second',
abbr: '2nd Prize',
value: 30
},
{
prize: 'third',
abbr: '3rd Prize',
value: 20
}
]
}),
})
<script src="https://unpkg.com/vue#2.6.10"></script>
<div id="app">
<prizes :settings="settings"></prizes>
</div>

table is not displaying, when i pull data from database

this is my table which is soppose to display subject details from the database
<div class="card-body table-responsive p-0">
<table class="table table-hover">
<tbody>
<tr>
<th>ID</th>
<th>Subject Code</th>
<th>Subject Name</th>
<th>Credit Hours</th>
<th>Created_at</th>
<th>Action</th>
</tr>
<tr v-for="subject in subjects" :key="subject.id">
<td>{{ subject.id }}</td>
<td>{{ subject.code | capitalize}}</td>
<td>{{ subject.name }}</td>
<td>{{subject.credit_hours}}</td>
<td>{{ subject.created_at |datetime }}</td>
<td>
<!-- Edit User -->
<a href="#" #click="editModal(subject)">
<i class="fa fa-edit text-green"></i>
</a>
<!-- Delete User -->
<a href="#" #click="deleteSubject(subject.id)">
<i class="fa fa-trash text-red"></i>
</a>
</td>
</tr>
this is my vuejs code to get data from subjectcontroller#index
<script>
import { Form, HasError, AlertError } from 'vform'
export default {
data () {
return {
editmode : false,
subjects: {}
form: new Form({
id: '',
subject_code: '',
subject_name: '',
credit_hours: '',
})
}
},
methods:{
loadSubjects(){
axios.get("api/subject")
.then(
({data}) => (this.subjects = data.data)
);
}
},
created(){
this.loadSubjects();
}
}
</script>
this is the code from subjectController#index
public function index()
{
$subjects = Subject::latest();
return $subjects->get();
}
the subject data displays in the consoles Network.XHR,
there are no console errors or warning
Any help will be appreciated
I was facing the same problem recently. Inside the axios module, try the following:
axios
.get("api/subject")
.then(response => (this.subjects = response.data));

How to get value from Dynamic Dropdown and submit it in database in VueJs and Laravel

I am creating a form in which you add cities on the basis of countries you get from dynamic drop-down. I am able to get the category_id (foreign key) in Vuejs but I don't how to pass it to the laravel back-end. I want to create a subcategory object with name and category_id. category_id is foreign key. I am unable to get category_id and it is passing NULL to db.
**Category = Country**
**Subcategory = City**
<template id="add-post">
<div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>City Name</th>
<th>Country id</th>
</tr>
</thead>
<tbody>
<tr v-for="(subcategory, index) in citylist" :key="subcategory.id">
<td>{{ index + 1 }}</td>
<td>{{ subcategory.name }}</td>
<td>{{ subcategory.category_id }}</td>
</tr>
</tbody>
</table>
<h3>Add City</h3>
<form v-on:submit.prevent = "createPost">
<select v-model="countryid" name="country" class="form-control" #change="myFunction()">
<option countryid disabled>Select Country</option>
<option v-for="category in categories" v-bind:value='category.id' v-text="category.name">{{category.name}}</option>
</select>
<div class="form-group">
<label for="add-name">Name</label>
<input v-model="subcategory.name" class="form-control" required />
</div>
<button type="submit" class="btn btn-xs btn-primary">Add City</button>
<!-- <button v-on:click="setPostId()">click</button> -->
<router-link class="btn btn-xs btn-warning" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>
export default {
data: function () {
return {
categories: [],
category: '',
countryid:'',
subcategories: [],
subcategory: {name: '', category_id: ''}
};
},
mounted(){
this.loadCategories()
},
created: function() {
let uri = 'http://localhost:8000/cities/';
Axios.get(uri).then((response) => {
this.subcategories = response.data;
});
},
computed: {
citylist: function(){
if(this.subcategories.length) {
return this.subcategories;
}
}
},
methods: {
myFunction: function() {
console.log(this.countryid)
},
loadCategories(){
axios.get('/api/categories')
.then(response => this.categories = response.data)
.catch(error => console.log(error))
},
createPost: function() {
let uri = 'http://localhost:8000/addsubcategory/';
Axios.post(uri, this.subcategory).then((response) => {
this.$router.push({name: 'City'})
})
}
}
}
</script>
you can make drop down
<select v-model="fruit" id="deptList">
<option v-for="company_master in company_masters.data" v-bind:value="company_master.CompanyId"> {{company_master.CompanyName}}
</option>
</select>
and call the data with axios like
axios.get("api/company_master").then(response => (this.company_masters = response.data));
also define
company_masters:[],
fruit:'',

Resources