I am making a site with a lot of pictures and videos using Bootstrap and Isotope. Each video/picture has an ID (called "nyeste") and a score, and I want both nyeste and score to sort descending, when users press the link "score" or "nyeste"
I have copy pasted a lot from isotope and the relevant code looks like this:
<ul id="sort-by" class="option-set clearfix" data-option-key="sortBy">
<li>score</li>
<li>nyeste</li>
</ul>
....
<ul id="sort-direction" class="option-set clearfix" data-option-key="sortAscending">
<li>sort ascending</li>
<li>sort descending</li>
</ul>
How do I combine these two functions, so that both "score" and "nyeste" sort ascending without users having to press two different links?
You can make the descending works as default for all your sorting rules.
Just add sortAscending: false:
$container.isotope({
itemSelector: '.element',
sortAscending: false, // <---------------- HERE
getSortData: {
symbol: function ($elem) {
return $elem.attr('data-symbol');
},
category: function ($elem) {
return $elem.attr('data-category');
},
number: function ($elem) {
return parseInt($elem.find('.number').text(), 10);
},
weight: function ($elem) {
return parseFloat($elem.find('.weight').text().replace(/[\(\)]/g, ''));
},
name: function ($elem) {
return $elem.find('.name').text();
}
}
});
Related
Good Afternoon.
I'm trying to build a stylized table with "v-data-table", without being used to it. Mainly put style into second or third cell (table, tr, td). I don't find the solution for my problem. Help me, please.
thanks.
You can use the item-class attributes to style every row
Property on supplied items that contains item’s row class or function that takes an item as an argument and returns the class of corresponding row
It works as the following :
It takes a function as argument that return a class depending on the row.
If you want to return a specific class depending on the item use it like this :
<template>
<v-datad-table :item="items" :item-class="getMyClass"></v-data-table>
</template>
<script>
methods: {
getMyClass(item){
// here define your logic
if (item.value === 1) return "myFirstClass"
else return "mySecondClass"
}
}
</script>
If you want to always give the same class you can just return the class you want to give (note that this is the same as stylized the td of the table using css)
<template>
<v-data-table :items="items" :item-class="() => 'myClass'"></v-data-table>
</template>
In your case, you can add an index to your data using a computed property and added a class based on the index
computed: {
myItemsWithIndex(){
retunr this.items.map((x, index) => {...x, index: index})
}
}
methods: {
getMyClass(item){
if(item.index === 2 || item.index === 3) return "myClass"
}
}
Working example
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: () => {
return {
items: [
{name: "foo"},
{name: "bar"},
{name: "baz"},
{name: "qux"},
{name: "quux"},
{name: "corge"},
{name: "grault"},
],
headers: [{ text: 'Name', value: 'name'}],
}
},
computed: {
itemsWithIndex(){
return this.items.map((item, index) => ({ ...item, index:index }))
}
},
methods: {
getMyClass(item){
if(item.index === 2 || item.index === 3){
return "myClass"
} else return
}
}
})
.myClass {
background: red
}
<script src="https://unpkg.com/vue#2.x/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#2.6.4/dist/vuetify.min.css" />
<div id="app" data-app>
<v-data-table :items="itemsWithIndex" :headers="headers" :item-class="getMyClass"></v-data-table>
</div>
I'd bet that what you're trying to achieve can be done using named slots
See this example from the docs. Basically, the template tag you see in the example will become whatever node is 'above it' (which it really isn't because it takes its place, but you get the point). For instance, in the case of data-tables, <template #item="{ item }">... represents every <td> of your table. Then you can use the destructured item and apply some logic to it to still of modify you table as you will.
Don't forget to upvote/validate the answer if it helped your to solve your issue, comment if you need more details and welcome to Stack!
There are also the possibility to use cellClass, which is part of the headers.
The image is from https://vuetifyjs.com/en/api/v-data-table/#props
As computed property i have:
headers() {
return [
{ text: this.$t('Name'), align: 'left', sortable: true, value: 'name', cellClass:'select' },
{ text: 'CVR', sortable: false, value: 'cvrno' },
{ text: this.$t('Updated At'), sortable: false, value: 'updatedAt' }
]
},
and by v-data-table tag looks like:
<v-data-table
v-model="selected"
:headers="headers"
:items="customerFiltered"
:loading="loadingCustomers"
:items-per-page="-1"
selected-key="id"
show-select
hide-default-footer
fixed-header
>
I have an index table with a user that have an information status of verification based on passed on ID every time user register. Every status has 3 value which is 'Draft','Need Verify','Verified' under DB name status_records based on this picture. I want to make colouring text based on ID. For example, If user under 'Draft', the text status in index datatable will colouring text 'Draft' with blue colour while if user under 'Verified' the colour for text will be green.
I'm using Datatable for showing the index. For value under status column, it only passed the ID and just showing the standard black colour. Refer the picture below,
I'm still new to Datatable and i do not know where to put the logic whether in controller or JS index blade.
But here is my mode user.php for relationship with statusrecord :
public function statusrecord(){
return $this->hasOne(StatusRecord::class, 'id', 'status_record');
}
UserController
public function index(){
$record = User::with('ownership','assetdpa','statusrecord')->where('asset_type_id','=',1)->orderby('id', 'asc')->get();
if(request()->ajax()){
return DataTables()::of($record)
->addIndexColumn()
->addColumn('status', function($record){
if($record->statusrecord){
return '<span class="badge badge-primary" >Active</span>';
}else{
return '<span class="badge badge-danger">Deactive</span>';
}
})
->rawColumns(['action', 'fullOrganisation','fullLocation','fullCategory'])
->make(true);
}
return view('asset.index',compact('record'));
}
index.blade.php
$(document).ready(function(){
$('#item_table').DataTable({
columnDefs: [{data:('statusrecord'),
render: function ( statusrecord, type, row ) {
var color = 'black';
if (id = 1) {
color = 'green';
}
if (id = 2) {
color = 'blue';
}
if (id = 3) {
color = 'red';
}
return '<span style="color:' + color + '">' + data + '</span>';
}
}]
})
})
Instead of rendering the table on the index. Make an Ajax call to the data and have it produce the table.
In web.php create a route -
Route::get ('trailer/list', [TrailersController::class, 'getTrailers'])->name ('trailers.list');
In your controller example (This way you can map the data you want to show in the Table) -
// Tractor list for DataTables
public function getTrailers(Request $request)
{
$trailers= Trailers::latest()->get();
return Datatables::of($trailers)
->addColumn('Actions', function ($trailers) {
return '<button class="btn btn-light btn-active-light-info btn-sm" data-bs-toggle="modal" data-bs-target="#edit-trailers-'.$trailers->id.'" class="menu-link px-3">Edit</button>';
})
->rawColumns(['Actions'])
->make(true);
}
For example - Here is what I have to show a trailer. In the status column all I'm doing is a call stating if status = 'Active' show a green badge. If 'Inactive' show a red badge.
$(function () {
$("#trailer_table").DataTable({
processing: !0,
serverSide: !0,
searching: !1,
order: [[0, "desc"]],
search: { return: !0 },
pageLength: 7,
ajax: '{!! route('trailers.list') !!}',
columns: [
{ data: "status",
render: function(data, type, row, meta){
if(type === 'display'){
if(data === 'Active'){
data = '<span class="badge badge-light-success">Active</span>';
}
else if(data === 'Inactive'){
data = '<span class="badge badge-light-danger">Inactive</span>';
}
return data;
}}},
{ data: "trailer_id", name: "trailer_id" },
{ data: "year", name: "year" },
{ data: "make", name: "make" },
{ data: "model", name: "model" },
{ data: "owned_by", name: "owned_by" },
{ data: "last_inspection", name: "last_inspection" },
{ data: "Actions", name: "Actions", orderable: !1, serachable: !1, sClass: "text-center" },
],
});
});
Hope this helps a little.
I tried removing the header in the exported PDF from the DataTable but it didn't work. Also, how to change the color table to full white and border black?
var table = $('#ReportTable').DataTable( {
lengthChange: false,
buttons: [
{"extend": 'pdf',
"className": 'btn btn-sm btn-primary rounded-pill px-3 mb-3 mb-sm-0',
customize: function(doc) {
doc.header = false;
doc.pageMargins = [ 150, 20, 150, 20 ];
},
},
{
"extend": 'print',
"className": 'btn btn-sm btn-primary rounded-pill px-3 mb-3 mb-sm-0'
},
]
} );
table.buttons().container()
.appendTo( '#ReportTable_wrapper .col-md-6:eq(0)' );
You can use title to control the title ("SiPanda") and you can use customize to control the different colors (striped lines) used for alternate rows in the PDF.
I don't want to interfere with your existing use of customize, so here is my test example which you can use as a model:
var table = $('#example').DataTable( {
dom: 'Brftip',
buttons: [
{
extend: 'pdfHtml5',
text: 'To PDF',
title: '',
customize: function ( pdf, btn, tbl ) {
delete pdf.styles.tableBodyOdd.fillColor;
}
}
]
} );
The title: '' is straightforward (assuming your PDF is actually getting its title from the web page's title).
The delete pdf.styles.tableBodyOdd.fillColor; assumes that your DataTable is using the "standard" zebra-stripes" style.
This command works because the DataTable passes the following properties to PDFMake:
tableBodyEven: Object { }
tableBodyOdd: Object { fillColor: "#f3f3f3" }
So, we remove the fillColor: "#f3f3f3" property from the tableBodyOdd object.
If you have used a different DataTables styling, you may see something different from what I see - in which case you can use console.log( pdf ); to take a closer look.
UPDATE
I missed the part about "and border black" - so here is an approach for that, also:
buttons: [
{
extend: 'pdfHtml5',
text: 'To PDF',
title: '',
customize: function ( pdf, btn, tbl ) {
delete pdf.styles.tableBodyOdd.fillColor;
pdfMake.tableLayouts = {
exampleLayout: {
hLineWidth: function (i) {
return 0.2;
},
vLineWidth: function (i) {
return 0.2;
},
hLineColor: function (i) {
return 'black';
},
vLineColor: function (i) {
return 'black';
}
//paddingLeft: function (i) {
// return i === 0 ? 0 : 8;
//},
//paddingRight: function (i, node) {
// return (i === node.table.widths.length - 1) ? 0 : 8;
//}
}
};
pdf.content[0].layout = "exampleLayout";
}
}
]
In the above snippet, I define an object called pdfMake.tableLayouts which contains a custom object called exampleLayout.
My exampleLayout defines thin black lines around every cell in the table.
I then use this custom layout by using:
pdf.content[0].layout = "exampleLayout";
You can choose your own line widths and colors.
The end result:
I have cloned this awesome shopping cart repo from https://github.com/vueschool/learn-vuex, and i get data like this:
ProductList.vue
<template>
<div>
<ul>
<li v-for="product in products">
- {{product.name}} - {{product.price}}
</li>
</ul>
</div>
</template>
<script>
methods: {
...mapActions({
fetchProducts: 'products/fetchProducts'
})
}
</script>
export default new Vuex.Store({
state: {
products: {},
},
actions: {
fetchProducts({commit},data) {
axios.get(`api/product`).then((response) => {
commit('updateProducts', response.data);
})
},
mutations: {
updateProducts (state, products) {
state.products = products
}
}
});
I'm trying to paginate results and need help in that direction, do i need to create a pagination state or new module in the vuex store, thanks in advance.
Try following
I use one of the RenderlessLaravelVuePagination component for pagination.
<pagination :data="products" #pagination-change-page="getProducts"></pagination>
and remaining code is below
export default {
name: 'ProductList',
mounted() {
this.getProducts();
},
methods: {
getProducts(page = 1){
this.$store.dispatch('getProducts',{
page: page
});
},
}
Hope this works for you.
You need to define meta object in order to store the meta data returning from your axio post. Then, you can use that meta object in your vue.
Do something like this:
export default new Vuex.Store({
state: {
products: {},
productsMeta: {}
},
actions: {
getProducts({commit},data) {
axios.get(`api/product`).then(response => {
this.productsMeta = response.meta;
}).commit('updateProducts', response.data);
})
},
mutations: {
updateProducts (state, products) {
state.products = products
}
}
});
in my Laravel 5.4 app I want to use Select2 to filter for my "Providers" like that:
https://paste.laravel.io/RowKK
The Select2 Box show the correct content but when I start typing the name of a Provider it doesn't filter the correct items.
When using the same on the example pages, this is working.
Any ideas what I make wrong?
Regards
kay899
It will still be your API backend that will do the filtering, all you have to do is to pass the query term via data property in your ajax. Example the params.term was passed to a q property and pulled from the API backend.
Example GitHub Repositories pulling:
function formatRepo (repo) {
if (repo.loading) return repo.text;
return repo.full_name
}
function formatRepoSelection (repo) {
return repo.full_name || repo.text;
}
$(".js-data-example-ajax").select2({
placeholder: 'Select an item',
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// notice we return the value of more so Select2 knows if more results can be loaded
//console.log(data.items)
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 1,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
<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.1/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.min.css" rel="stylesheet"/>
<select class="js-data-example-ajax" style="width:500px;">
<option selected="selected"></option>
</select>