Retain zebra striping of table after rows are filtered with Alpine.js - alpine.js

I have a table that has zebra striping.
I'm using Alpine.js to filter rows based on buttons you click.
When the table is filtered, the row striping is from the original, unfiltered state.
I'd like the striping to be recalculated when the filter is updated.
Code is below and I've created a CodePen.
<div x-data="{ filterID: 'all', filter: (id, allowed) => allowed.includes(id) }">
<nav class="mb-4">
<a
class="bg-purple-200 hover:bg-purple-400"
#click.prevent="filterID = 'all', striping"
:class="{ 'bg-purple-400' : filterID === 'all' }"
href="#"
>All</a>
<a
class="bg-purple-200 hover:bg-purple-400"
#click.prevent="filterID = 'A'"
:class="{ 'bg-purple-400' : filterID === 'A' }"
href="#"
>A</a>
<a
class="bg-purple-200 hover:bg-purple-400"
#click.prevent="filterID = 'B'"
:class="{ 'bg-purple-400' : filterID === 'B' }"
href="#"
>B</a>
</nav>
<table>
<thead>
<th>Column A</th>
<th>Column B</th>
</thead>
<tbody>
<tr
x-show.transition="filter(filterID, [ 'A' ]) || filterID === 'all'"
:class="{ 'active': filter(filterID, [ 'A' ]) }"
class=""
>
<td>Data 1A</td>
<td>Data 1B</td>
</tr>
<tr
x-show.transition="filter(filterID, [ 'B' ]) || filterID === 'all'"
:class="{ 'active': filter(filterID, [ 'B' ]) }"
class="bg-purple-200"
>
<td>Data 2A</td>
<td>Data 2B</td>
</tr>
<tr
x-show.transition="filter(filterID, [ 'A' ]) || filterID === 'all'"
:class="{ 'active': filter(filterID, [ 'A' ]) }"
class=""
>
<td>Data 3A</td>
<td>Data 3B</td>
</tr>
</tbody>
</table>
</div>

use :key="row.id" in order to give those items specific ids. This way, alpine.js will remove the inactive rows from the DOM so the odd/even count will not be messed up with the rows being hidden.

Related

Vuetify Draggable Data-table with nested children rows

I have a Vuetify data table with draggable rows. Working well. Here is my code:
<template v-slot:body="props">
<draggable
:list="props.items"
tag="tbody"
>
<tr
v-for="(item, index) in props.items"
:key="index"
#drop="dropIntoParentRelationship($event, index)"
#dragover.prevent
#dragenter.prevent
#dragstart="startDrag($event, item, index)"
>
<td>
<v-icon
v-if="!_.isEmpty(item.children)"
color="#68007d"
#click="show = !show"
>add_circle</v-icon>
</td>
<td>
<v-checkbox
v-if="item.parent"
color="#68007d"
></v-checkbox>
</td>
<td v-if="item.parent">
<div class="text-truncate" style="max-width: 230px;">
{{ item.product_title }}
</div>
</td>
<td>
<div class="text-truncate" style="max-width: 230px;">
{{ item.sku }}
</div>
</td>
<td class="text-center">
<country-flag
:country='countryFlags[item.marketplace]'
size='normal'
class='text-center'
/>
</td>
<td class="text-center">
<p class="mt-4">{{item.quantity}}</p>
</td>
<td class="">
<p class="mt-4">{{item.currency_symbol}}{{item.price}}</p>
</td>
<td class="text-center">
<v-icon
:color="item.on_shopify ? 'green darken-4' : 'red darken-4'"
>
{{ item.on_shopify ? 'done' : 'close' }}
</v-icon>
</td>
<td class="text-center">
<v-icon
:color="item.uploaded ? 'green darken-4' : 'red darken-4'"
>
{{ item.uploaded ? 'done' : 'close' }}
</v-icon>
</td>
</tr>
</draggable>
</template>
The issue however is that I want to display children data in a row underneath the parent data which I could then also drag and drop and I'm lost on how to do this.
Any ideas?

How to make filter on table based on option select

I am working on a project (vue + laravel) where i need to fetch all table structure from db. So my table will be dynamically with all field(table header) and record. Now i need to do a filter(search) for each visible column. I have tryed some way but it does not work for me, I just dont know how to pass only column value for each option select value.
Collapse content is the option who will show on filter click and there should display the option for each column
<table class="table table-hover align-middle mb-0" :class="smallTable.smTable">
<thead class="">
<tr>
<th><input type="checkbox" class="form-check-input" v-model="selectAll" title="Select All"></th>
<th v-for="(header, i) in visibleHeaders" :key="i" scope="col">
{{ header.name }}
</th>
<th v-if="actionHide">ACTION</th>
</tr>
</thead>
<!-- Collapsed content ./ -->
<thead class="collapse" id="collapseFilter">
<tr>
<th></th>
<th v-for="(header, i) in visibleHeaders" :key="i">
<div class="filter-table col-12 d-flex">
<select id="" class="form-select" >
<option v-for="(lead, i) in leads" >{{lead}}</option>
</select>
</div>
</th>
</tr>
</thead>
<!-- ./ Collapse contet -->
<tbody>
<tr v-show="leads.length" v-for="(lead, i) in leads" :key="i">
<td>
<input type="checkbox" class="form-check-input" v-model="selected" :value="lead.id" />
</td>
<td v-for="(field, j) in lead" :key="j">
<span v-if="field == 'new'" class="badge badge-primary">
{{ field }}
</span>
<span v-else-if="field == 'contract'" class="badge badge-success">
{{ field }}
</span>
<span v-else>
{{ field }}
</span>
</td>
<td >
<button #click="editLead(lead.id)" type="button" class="btn btn-sm btn-secondary" data-mdb-toggle="modal" data-mdb-target="#editLeadModal" >
<i class="fa-solid fa-eye"></i>
</button>
</td>
</tr>
<tr v-show="!leads.length">
<td colspan="12" class="text-center">Sorry :( No data found.</td>
</tr>
</table>
data() {
return {
headers: [],
leads: [],
fields: [],
}
}
mounted() {
axios.get('/leads/getfields')
.then(response => {
this.fields = response.data.map(field => {
return {
name: field,
visible: true,
}
});
}
this.getData();
});
}
getData() {
this.headers = this.fields.map(item => {
if (item.visible) {
return item.name;
}
});
axios.post('/leads/getleads?page=' + this.pagination.current_page, {
perPage: this.displayRecord,
fields: this.headers,
})
.then(response => {
this.leads = response.data.data;
this.pagination = response.data.meta
});
},

How to define x-model in for-circle of checkboxes based on array?

in my Laravel 8 / tailwindcss 2 / Alpinejs 2.8 app I fill set of checkboxex based on array like:
<template x-for="nextCategory in categories" :key="nextCategory.id">
<tr class="p-4 mb-15">
<td>
<input type="checkbox"
x-bind:id="'cbx_' + nextCategory.id"
name="cbx_Categories"
x-bind:value="nextCategory.id"
class="p-4 checked:bg-blue-600"
>
<label :for="'cbx_' + nextCategory.id" class="whitespace-nowrap md:flex-shrink-0"
x-text="nextCategory.id+' : '+nextCategory.name">
</label>
</td>
<td class="text-right" x-text="nextCategory.ad_categories_count">
</td>
</tr>
</template>
The checkboxes are rendered ok, but I try to keep state of any checkbox element in array defined as :
searchSelectedCategoryIds: [],
and use this array in checkbox x-model definition:
<template x-for="nextCategory in categories" :key="nextCategory.id">
<tr class="p-4 mb-15">
<td>
<input type="checkbox"
x-bind:id="'cbx_' + nextCategory.id"
name="cbx_Categories"
x-bind:value="nextCategory.id"
x-model="searchSelectedCategoryIds"
class="p-4 checked:bg-blue-600"
>
<label :for="'cbx_' + nextCategory.id" class="whitespace-nowrap md:flex-shrink-0"
x-text="nextCategory.id+' : '+nextCategory.name">
</label>
</td>
<td class="text-right" x-text="nextCategory.ad_categories_count">
</td>
</tr>
</template>
as result all by clicking on any checkbox all checkboxes are selected and searchSelectedCategoryIds
has value “on”
Which way is valid ?
MODIFIED BLOCK :
#extends('layouts.app')
#section('content')
<div class="flex items-center justify-center p-8 m-10">
<div class="flex justify-center w-screen h-screen bg-gray-100" x-data="checkBoxTest()" >
categories::<span x-text="categories.id"></span><br><hr>
TestsearchSelectedCategoryIds::<span x-text="TestsearchSelectedCategoryIds"></span><br><hr>
<table x-show="categories.length">
<thead>
<tr>
<th>Name</th>
<th>Ads Number</th>
</tr>
</thead>
<tbody>
<template x-for="nextCategory in categories" :key="nextCategory.id">
<tr class="p-4 mb-15">
<td>
<input type="checkbox"
x-bind:id="'cbx_' + nextCategory.id"
name="cbx_Categories"
x-bind:value="nextCategory.id"
class="p-4 checked:bg-blue-600"
x-model="TestsearchSelectedCategoryIds"
>
<label :for="'cbx_' + nextCategory.id" class="whitespace-nowrap md:flex-shrink-0"
x-text="nextCategory.id+' : '+nextCategory.name">
</label>
</td>
<td class="text-right" x-text="nextCategory.ad_categories_count">
</td>
</tr>
</template>
</table>
</div>
</div>
#endsection
#section('scripts')
<script>
function checkBoxTest() {
return {
TestsearchSelectedCategoryIds: '',
categories : [
{
ad_categories_count: 2,
id: 1,
name: "Laptops"
},
{
ad_categories_count: 3,
id: 2,
name: "Computer Monitor"
},
{
ad_categories_count: 4,
id: 4,
name: "Computer Accessories"
}
]
}}
</script>
#endsection
[EDITED TO BE LESS CONFUSING]
I need to see your x-data. Your <template> seems fine. I tried to get the value of searchSelectedCategoryIds: [], to be "on" and can only reproduce your result if:
I set searchSelectedCategoryIds: [],; and
I remove the x-bind:value="nextCategory.id" in the <input> attribute.
Meanwhile, if:
I set searchSelectedCategoryIds: '', instead of searchSelectedCategoryIds: [], (a string instead of an array); and
I set the x-bind:value="nextCategory.id" in the <input> attribute;
I will get the the value of true which is also the wrong output.
AFAIK, the browser will determine the value of <input type="checkbox"> if we don't set it. In this case, the browser sets it to "on". So, the issue here is a failed binding but I cannot verify unless I can see your x-data structure. Here's my attempt to replicate but with everything set:
<form class="bg-gray-800">
<div class="flex justify-center items-center max-w-lg mx-auto h-screen">
<table x-data="formRender()" class="bg-gray-50">
<caption class="bg-gray-100 font-light text-yellow-700 uppercase tracking-widest">Title</caption>
<thead class="border-t border-gray-300 font-bold">
<tr>
<td>Item</td>
<td>Count</td>
</tr>
</thead>
<tbody class="divide-y border-gray-300">
<template x-for="nextCategory in categories" :key="nextCategory.id">
<tr class="p-4 mb-15">
<td>
<input type="checkbox" x-bind:id="'cbx_' + nextCategory.id" name="cbx_Categories" x-bind:value="nextCategory.id" x-model="searchSelectedCategoryIds" class="p-4 checked:bg-blue-600">
<label :for="'cbx_' + nextCategory.id" class="whitespace-nowrap md:flex-shrink-0" x-text="nextCategory.id+' : '+nextCategory.name">
</label>
</td>
<td class="text-right" x-text="nextCategory.ad_categories_count">
</td>
</tr>
</template>
</tbody>
<tfoot>
<tr>
<td class="bg-yellow-500 text-center" colspan="2">
<output x-text=" 'Item checked: ' + searchSelectedCategoryIds"></output>
</td>
</tr>
</tfoot>
</table>
</div>
</form>
<script>
function formRender() {
return {
categories: [{
id: 1,
name: 'banana',
ad_categories_count: 'one'
},
{
id: 2,
name: 'apple',
ad_categories_count: 'two'
},
{
id: 3,
name: 'orange',
ad_categories_count: 'three'
}
],
searchSelectedCategoryIds: [],
}
}
</script>
https://codepen.io/wanahmadfiras/pen/YzpmERK

Laravel Cart not picking up food price

Am building an ordering system for restaurants
When one clicks order here it takes the user to the cart page>this is the link that takes the user to the cart page
<p class="btn-holder"><a href="{{ route('restaurants.cart',$restaurant->id)}}" class="btn btn-primary btn-block text-center" role="button" > Order this</a> </p>
but my cart page isn't displaying the food price.It displays it as 0 yet the price exists.
<table id="cart" class="table table-hover table-condensed">
<thead>
<tr>
<th style="width:50%">Product</th>
<th style="width:10%">Price</th>
<th style="width:8%">Quantity</th>
<th style="width:22%" class="text-center">Subtotal</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody>
<?php $total = 0 ?>
#if(session('cart'))
#foreach(session('cart') as $id => $details)
<?php $total += (int)$details['price'] *(int)$details['quantity'] ?>
<tr>
<td data-th="Product">
<div class="row">
{{-- <div class="col-sm-3 hidden-xs"><img src="{{ $details['photo'] }}" width="100" height="100" class="img-responsive"/></div> --}}
<div class="col-sm-9">
<h4 class="nomargin">{{ $details['name'] }}</h4>
</div>
</div>
</td>
<td data-th="Price">{{(int) $details['price'] }}</td>
<td data-th="Quantity">
<input type="number" value="{{ $details['quantity'] }}" class="form-control quantity" />
</td>
<td data-th="Subtotal" class="text-center">{{(int) $details['price'] *(int) $details['quantity'] }}</td>
<td class="actions" data-th="">
<button class="btn btn-info btn-sm update-cart" data-id="{{ $id }}"><i class="fa fa-refresh"></i></button>
<button class="btn btn-danger btn-sm remove-from-cart" data-id="{{ $id }}"><i class="fa fa-trash-o"></i></button>
</td>
</tr>
#endforeach
#endif
</tbody>
<tfoot>
<tr class="visible-xs">
<td class="text-center"><strong>Total {{ $total }}</strong></td>
</tr>
<tr>
<td><i class="fa fa-angle-left"></i> Continue Shopping</td>
<td colspan="2" class="hidden-xs"></td>
<td class="hidden-xs text-center"><strong>Total ${{ $total }}</strong></td>
</tr>
</tfoot>
</table>
#endsection
This is the Foods controller and function addToCart which adds items to cart
public function addToCart($id){
$food = Food::find($id);
if(!$food) {
abort(404);
}
$cart = session()->get('cart');
// if cart is empty then this the first product
if(!$cart) {
$cart = [
$id => [
"name" => $food->food_item,
"quantity" => 1,
"price" => $food->price,
]
];
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
// if cart not empty then check if this product exist then increment quantity
if(isset($cart[$id])) {
$cart[$id]['quantity']++;
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
// if item not exist in cart then add to cart with quantity = 1
$cart[$id] = [
"name" => $food->food_item,
"quantity" => 1,
"price" => $food->price,
];
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
}

Selecting the Parent of the Parent element. Tables/Watir/Ruby

Hey i am trying to select the parent of the parent element i suppose. I have a table in which i am trying to use Watir/Ruby to select the edit or delete button from the same row but in a different coloumn, example.
Name 1 -> Edit Icon -> Delete Icon
Name 2 -> Edit Icon -> Delete Icon
Example code below:
<html>
<body>
<table class="table-responsive">
<thead>...</thead>
<tbody>
<tr>
<td class="col-name">Name 1</td>
<td>
<a class="edit" href="/">
<span class="icon-edit"></span>
</a>
<a class="delete" href="/">
<span class="icon-delete"></span>
</a>
</td>
</tr>
<tr>
<td class="col-name">Name 2</td>
<td>
<a class="edit" href="/">
<span class="icon-edit"></span>
</a>
<a class="delete" href="/">
<span class="icon-delete"></span>
</a>
</td>
</tr>
<tr>
...
</tr>
<tbody>
</table>
</body>
</html>
So far i have tried this but it is not working. I get an error TypeError: can't convert Hash into an exact number
table = #browser.table.when_present(:class => "table-responsive")
iconrow = table.span(:text => "Name 1").parent
if iconrow.a(:class => "edit").exists?
iconrow.a(:class => "edit").click
end
There might be a couple issues with the code:
* The :class locator is being applied to when_present rather than the table itself.
* The element with "Name 1" is a td rather than a span.
Try:
table = #browser.table(:class => "table-responsive").when_present
iconrow = table.td(:text => "Name 1").parent
if iconrow.a(:class => "edit").exists?
iconrow.a(:class => "edit").click
end

Resources