I need to make a custom field just like checklist, but in a table and with a second field "order".
This is what I have:
Model 1: Conditions with relations "belongsToMany"
Model 2: SubServices
These two models are in relations with the table products_service that has the two foreign_keys plus the column "order"
What I can't understand is:
How could save the extra information with backpack.
I know that I can use something like this:
$user->roles()->updateExistingPivot($roleId, $attributes);
but where should I put it?
Here's my code:
class Condition extends Model
{
use CrudTrait;
use Searchable;
public function relService()
{
//dd($this->belongsToMany(SubService::class, 'conditions_service')->withPivot('weight')->withTimestamps());
return $this->belongsToMany(SubService::class, 'conditions_service')->withPivot('weight')->withTimestamps();
}
}
class SubService extends Model
{
use Searchable;
use CrudTrait;
public function conditions()
{
return $this->belongsToMany(Condition::class, 'conditions_service')->withPivot('weight')->withTimestamps();
}
}
Here's my Custom Field Type:
<!-- select2 -->
<div #include('crud::inc.field_wrapper_attributes') >
<label>{!! $field['label'] !!}</label>
#include('crud::inc.field_translatable_icon')
<?php $entity_model = $crud->getModel(); ?>
<div class="row">
<div class="col-sm-12">
<table id="crudTable" class="table table-bordered table-striped display">
<thead>
<tr>
#if ($crud->details_row)
<th></th> <!-- expand/minimize button column -->
#endif
{{-- Table columns --}}
<th>Seleziona</th>
<th>Ordine</th>
{{--<th>Ordine <i class="fa fa-arrow-up" aria-hidden="true"></i></th>
<th>Ordine <i class="fa fa-arrow-down" aria-hidden="true"></i></th>--}}
{{--$tst = $connected_entity_entry->relService->whereIn('id', $connected_entity_entry->id)--}}
</tr>
</thead>
<tbody>
#foreach ($field['model']::all() as $connected_entity_entry) {{--var_dump((empty($connected_entity_entry->conditions->toArray())?"puppa":(empty($connected_entity_entry->conditions->whereIn('id', $connected_entity_entry->id)->toArray())?"puppa uguale":$connected_entity_entry->conditions->whereIn('id', $connected_entity_entry->id)))) --}}
{{-- dump($connected_entity_entry->getPriority($connected_entity_entry->id)) --}}
<tr>
<th scope="row">
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox"
name="{{ $field['name'] }}[]"
value="{{ $connected_entity_entry->id }}"
#if( ( old( $field["name"] ) && in_array($connected_entity_entry->id, old( $field["name"])) ) || (isset($field['value']) && in_array($connected_entity_entry->id, $field['value']->pluck('id', 'id')->toArray())))
checked="checked"
#endif > {!! $connected_entity_entry->{$field['attribute']} !!}
</label>
</div>
</div>
</th>
<td>{{--#include('crud::fields.number')--}}
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
{{-- HINT --}}
#if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
#endif
</div>
</div>
Thank you for your help!
Dave
I found a solution thanks dense-team with his pull request (https://github.com/Laravel-Backpack/CRUD/pull/351)
Here's my code updated:
CrudController:
$this->crud->addField([
'label' => 'Servizi legati',
'type' => 'checklist_ordered',
'name' => 'relService',
'entity' => 'relService',
'attribute' => 'title',
'model' => "App\Models\SubService",
'pivot' => true,
'pivotFields' => [
'weight' => 'Ordinamento',
],
], 'update/create/both');
Here's my Custom Field Type:
<!-- select2 -->
<div #include('crud::inc.field_wrapper_attributes') >
<label>{!! $field['label'] !!}</label>
#include('crud::inc.field_translatable_icon')
#if (isset($field['model']))
<?php $entity_model = $crud->getModel();
$pivot_entries = null;
if (isset($entry)) {
$pivot_entries = $entry->{$field['entity']}->keyBy(function ($item) {
return $item->getKey();
});
}
?>
<div class="row">
<div class="col-sm-12">
<table id="crudTable" class="table table-bordered table-striped display">
<thead>
<tr>
#if ($crud->details_row)
<th></th> <!-- expand/minimize button column -->
#endif
{{-- Table columns --}}
<th>Seleziona</th>
#foreach($field['pivotFields'] as $pivot_chunk)
<th>{{$pivot_chunk}}</th>
#endforeach
</tr>
</thead>
<tbody>
#foreach ($field['model']::all() as $connected_entity_entry)
<tr>
<th scope="row">
<div class="col-sm-4">
<div class="checkbox">
<label>
<input type="checkbox"
name="{{ $field['name'] }}[]"
value="{{ $connected_entity_entry->id }}"
#if( ( old( $field["name"] ) && in_array($connected_entity_entry->id, old( $field["name"])) ) || (isset($field['value']) && in_array($connected_entity_entry->id, $field['value']->pluck('id', 'id')->toArray())))
checked="checked"
#endif > {!! $connected_entity_entry->{$field['attribute']} !!}
</label>
</div>
</div>
</th>
<td>
#foreach(array_chunk($field['pivotFields'], 2, true) as $pivot_chunk)
#foreach ($pivot_chunk as $pivot_field => $pivot_name)
<?php
$pivot_attr = null;
if ($pivot_entries) {
if ($pivot_entries->has($connected_entity_entry->getKey())) {
$pivot = $pivot_entries->get($connected_entity_entry->getKey())->pivot;
$pivot_attr = $pivot->getAttribute($pivot_field);
}
}
?>
<input type="number"
name="{!! $pivot_field !!}[{{ $connected_entity_entry->getKey() }}]"
value="{{ $pivot_attr }}" #include('crud::inc.field_attributes') />
#endforeach
#endforeach
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endif
{{-- HINT --}}
#if (isset($field['hint']))
<p class="help-block">{!! $field['hint'] !!}</p>
#endif
</div>
</div>
Related
I have tried various alignment settings, but nothing is making a difference. Please have a look at the far right column in the image below and notice that the price is shifted down compared with the columns to the left.
Note that this is the print preview
This is what the same table looks like on the web page when not printing.
You can see that in the web page, I have set the margin for the last column to mt-0.
Here is my code:
<div class="row">
<div class="col-4">
<button class="btn btn-primary" onclick="printDiv()">Print</button>
</div>
</div>
<div class="row" id="PrintDiv">
<div class="col-md-8 offset-2">
<div class="row d-flex">
<div class="col-8">
<p>
<h2>#ViewBag.FullName</h2>
<h4>Order History</h4>
</p>
</div>
<div class="col me-1">
<img src="#(Configuration.GetValue<string>("StorageContainerURL"))/store-logo.png" )
class="img-fluid " style="max-height:75px;width:auto" alt="Alternate Text" />
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Order ID</th>
<th>Items</th>
<th>Total</th>
</tr>
</thead>
<tbody>
#foreach (var order in Model)
{
<tr>
<td class="align-middle">#order.OrderDate.ToLocalTime().ToShortDateString()</td>
<td class="align-middle">#order.Id</td>
<td class="align-middle">
<ul style="list-style-type:none">
#foreach (var item in order.OrderItems)
{
<li>
<div class="alert alert-info" role="alert">
<span class="badge bg-success">#item.Amount</span> [#item.Price.ToString("c")] - #item.Product.Name
</div>
</li>
}
</ul>
</td>
<td class="mt-0">#order.OrderItems.Select(m => m.Product.Price * m.Amount).Sum().ToString("c")</td>
</tr>
}
</tbody>
</table>
</div>
</div>
#section Scripts{
<script type="text/javascript">
function printDiv() {
var divContents = document.getElementById("PrintDiv").innerHTML;
var a = window.open('', '', 'height=500, width=500');
a.document.write('<html>');
a.document.write('<body > <br>');
a.document.write(divContents);
a.document.write('</body></html>');
a.document.close();
a.print();
}
</script>
}
Does anyone have any suggestions to make Total column align properly with the other columns?
I figured out the problem shortly after I posted the question. I realized that the Printed Version of the page would not recognize the Bootstrap classes. So instead, I changed all columns to use inline styles for alignment.
<tbody>
#foreach (var order in Model)
{
<tr>
<td style="vertical-align:text-top">#order.OrderDate.ToLocalTime().ToShortDateString()</td>
<td style="vertical-align:text-top">#order.Id</td>
<td style="vertical-align:text-top">
<ul style="list-style-type:none">
#foreach (var item in order.OrderItems)
{
<li>
<div class="alert alert-info" role="alert">
<span class="badge bg-success">#item.Amount</span> [#item.Price.ToString("c")] - #item.Product.Name
</div>
</li>
}
</ul>
</td>
<td style="vertical-align:text-top">#order.OrderItems.Select(m => m.Product.Price * m.Amount).Sum().ToString("c")</td>
</tr>
}
</tbody>
I'm trying to calculate the quantity of items in my vue. The problem I'm having is that my computed property isn't picking up my object, because my thinking was as you can see with the commented out section is that I was going to loop through it and calculate the quantity, but since I'm not able to grab productItems I'm not able to loop through it.
Here is my code
<template>
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr v-for="item in products">
<td>
{{ item['name'] }}
</td>
<td>
<input style="width: 100px; margin-left: 0; display: inline"
type="number" class="form-control"
v-model="productItems[item['name']]['unit']"
>
</td>
</tr>
<tr>
<td></td>
<td>
Consumption total: {{ consumptionTotal }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
props: [],
data(){
return {
productItems: {}
},
computed:{
consumptionTotal(){
console.log(this.productItems);
// return Object.keys(this.productItems).reduce((carry, item) => {
// carry += Number(this.productItems[item]['unit'])
// return carry;
// }, Number(0));
},
},
watch: {
},
methods: {
},
mounted() {
}
}
</script>
Try below steps. Hopefully it will helps you.
Step 1: productItems should be an array
Step 2: Calculate functions be like
computed: {
consumptionTotal () {
return this.productItems.reduce((total, item) => {
total += item.unit
return total
}, Number(0))
}
}
Step 3: HTML template will be like
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr v-for="item in productItems" :key="item.id">
<td>{{item.id}}</td>
<td>
{{item.name}}
</td>
<td>
<input style="width: 100px; margin-left: 0; display: inline" type="number" class="form-control" :value="item.unit">
</td>
</tr>
<tr>
<td></td>
<td>
Consumption total: {{ consumptionTotal }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
DEMO
I am using dompdf to generate a downloadable pdf from my multi-vendor eCommerce shopping cart and I am encountering this error even after defining $cartItems in QuotationController. $cartItems is defined in CartController I intend to fetch the items of CartController to the pdf
Here is the error:
Undefined variable: cartItems (View: C:\laragon\www\procure\resources\views\cart\quote.blade.php)
Here is QuoteController code:
<?php
namespace App\Http\Controllers;
use Barryvdh\DomPDF\PDF;
use Darryldecode\Cart\Cart;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class QuotationController extends Controller
{
public function quote(Request $request)
{
$product = DB::table('products')->get();
$cartItems = \Cart::session(auth()->id())->getContent();
$pdf = \PDF::loadView('cart.quote');
return $pdf->download('quotation.pdf');
//return view('cart.quote');
}
}
Heres is CartController:
<?php
namespace App\Http\Controllers;
use App\Product;
use Darryldecode\Cart\Cart;
class CartController extends Controller
{
public function add(Product $product)
{
// add the product to cart
\Cart::session(auth()->id())->add(array(
'id' => $product->id,
// 'img' => $product->cover_img,
'name' => $product->name,
'price' => $product->price,
'quantity' => 1,
'attributes' => array(),
'associatedModel' => $product,
));
return redirect()->route('cart.index');
}
public function index()
{
$cartItems = \Cart::session(auth()->id())->getContent();
view()->share('cartItems', $cartItems);
return view('cart.index', compact('cartItems'));
}
public function destroy($itemId)
{
\Cart::session(auth()->id())->remove($itemId);
return back();
}
public function update($rowId)
{
\Cart::session(auth()->id())->update($rowId, [
'quantity' => [
'relative' => false,
'value' => request('quantity'),
],
]);
return back();
}
public function checkout()
{
return view('cart.checkout');
}
}
And finally the blade file(quote.blade.php):
<section class="shopping-cart">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="cart-table table-responsive">
<table class="table">
<thead>
<tr>
<th class="t-pro">Product</th>
<th class="t-price">Price</th>
<th class="t-qty">Quantity</th>
<th class="t-total">Total</th>
<th class="t-rem"></th>
</tr>
</thead>
<tbody>
#foreach ($cartItems as $item)
<tr>
<td class="t-pro d-flex">
<div class="t-content">
<p class="t-heading">{{ $item->name }}</p>
</div>
</td>
<td class="t-price">KES {{ $item->price }} </td>
<td class="t-qty">
<div class="qty-box">
<div class="quantity buttons_added">
<form action="{{route('cart.update', $item->id)}}" method="get">
<input name="quantity" type="number" value="{{ $item->quantity }}">
<input class="button" type="submit" value="save">
</form>
</div>
</div>
</td>
<td class="t-total">{{Cart::session(auth()->id())->get($item->id)->getPriceSum()}}</td>
<td class="t-rem"><i class="far fa-trash-alt"></i></td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<div class="coupon">
<h6>Discount Coupon</h6>
<p>Enter your coupon code if you have one</p>
<form action="#">
<input type="text" name="zip" value="" placeholder="Your Coupon">
<button type="button">Apply Code</button>
</form>
Print Quotation
</div>
</div>
<div class="col-md-4">
<div class="crt-sumry">
<h5>Cart Summery</h5>
<ul class="list-unstyled">
<li>Subtotal <span>KES {{\Cart::session(auth()->id())->getTotal()}}</span></li>
<li>Shipping & Tax <span>0.00</span></li>
<li>Grand Total <span>KES {{\Cart::session(auth()->id())->getTotal()}}</span></li>
</ul>
<div class="cart-btns text-right">
<button onclick="location.href='{{route('home')}}'" class="up-cart">Update Cart</button>
<button onclick="location.href='{{route('cart.checkout')}}'" class="chq-out ">Checkout</button>
</div>
</div>
</div>
</div>
</div>
</section>
Just visit this https://github.com/arafkarim/HTML-to-PDF i have just applied this thing in my similar project.
I have a form which has checkbox and dropdowns and the data which is present in dropdowns is fetched from json. I have to select the dropdowns option , text written in text box on click of submit i have to filter and show the filtered data in table.
<form [formGroup]="reportsForm" (ngSubmit)=onSubmit(reportsForm.value)>
<label> Task Status</label>
<div>
<label class="checkbox-inline"></label>
<input type="checkbox" formControlName="whole" id="whole" value="whole"> a
<label class="checkbox-inline"></label>
<input type="checkbox" formControlName = "progress" id= "progress" value="progress"> b
</div>
<label>Date Time (GMT)</label>
<div class="">
<div class="col-md-6">
<label>FROM</label>
<input type="date" formControlName = "bfrom" id= "from" class="form-control">
</div>
<div class="col-md-6">
<label>TO</label>
<input type="date" formControlName = "to" id= "to" class="form-control">
</div>
</div>
<label>Group Name</label>
<div class="input-group-btn">
<select class="form-control" formControlName="groupname" id="groupname">
<option>Select</option>
<option *ngFor="let x of y" >{{x.grouping}}</option>
</select>
</div>
<label>Task Name</label>
<div class="input-group-btn">
<input type="text" formControlName="taskname" id="taskname" class="form-control">
</div>
<label>ASSIGNEE</label>
<div class="input-group-btn">
<select class="form-control" formControlName="assignee" id="assignee">
<option>Select</option>
<option *ngFor="let x of y" >{{x.assignee}}</option>
</select>
</div>
<label>Frequency</label>
<div class="input-group-btn">
<select class="form-control" formControlName="frequency" id= "frequency">
<option>Select</option>
<option *ngFor="let x of y">{{x.frequency}}</option>
</select>
</div>
<div class="buttons">
<button type="submit" class="btn">Submit</button>
</div>
</form>
<table class="table table table-bordered">
<thead>
<tr>
<th scope="col ">GroupName</th>
<th scope="col ">Assignee</th>
<th scope="col ">frequency</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let x of y">
<td scope="col">{{x.grouping}}</td>
<td scope="col">{{x.assignee}}</td>
<td scope="col">{{x.frequency}}</td>
</tr>
</tbody>
</table>
I have created a form in my component I have created all form data which is populating on submit of my form based on my selections of dropdowns and checkbox. And I have to filter those data and display on the table on form submit
#Component({
selector: 'app-rep',
templateUrl: './rep.component.html',
styleUrls: ['./rep.component.css']
})
export class RepComponent implements OnInit {
y;
users;
reportsForm: FormGroup;
constructor(private service: RepositoryService) { }
ngOnInit() {
this.reportsForm = new FormGroup({
whole: new FormControl(''),
progress: new FormControl(''),
bfrom: new FormControl(''),
to: new FormControl(''),
groupname: new FormControl(''),
taskname: new FormControl(''),
assignee: new FormControl(''),
frequency: new FormControl(''),
});
this.getTasks();
this.getUsers();
}
public getUsers() {
this.service.getData(usersUrl).subscribe(res =>{this.users = res.data.items});
}
public getTasks() {
this.service.getData(reportsUrl).subscribe(res =>{this.y= res.data.items});
}
onSubmit(filterValue:any) {
console.log(this.reportsForm);
}
}
Finally I came up with one solution which is working for multiple filters and on submit data should be filtered in a table. But it needs optimization if you have many conditions.
onSubmit() {
this.filteredtasks=[];
let grp = this.reportsForm.value.groupname;
let fre = this.reportsForm.value.frequency;
let as= this.reportsForm.value.assignee;
let tsknm = this.reportsForm.value.taskname;
for(let i=0; i< this.y.length; i++) {
if(
(grp == "" || grp == this.tasks[i].groupname) &&
(fre == "" || fre == this.tasks[i].frequency) &&
(as== "" || as== this.tasks[i].assignee) &&
(tsknm == "" || tsknm == this.tasks[i].taskname)
) {
this.filteredtasks.push(this.y[i]);
}
}
The filteredtasks array is having the filtered list..
<table class="table table table-bordered">
<thead>
<tr>
<th scope="col ">GroupName</th>
<th scope="col ">Assignee</th>
<th scope="col ">frequency</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let x of filteredtasks">
<td scope="col">{{x.groupname}}</td>
<td scope="col">{{x.assignee}}</td>
<td scope="col">{{x.frequency}}</td>
</tr>
</tbody>
</table>
The current default view for the wish list module shows the product but not the options that were selected.
How can this be changed so that the option label and selected value are displayed as well?
I'm going to make an assumption that you're using Hotcakes 1.xx and not version 2.xx for this, but the code should be the same for both. I just only tested it in 01.10.04.
I've built an example of how to do this based upon the Cart view you'll find in the viewset already.
The original Wish List view looks like this:
#model IEnumerable<Hotcakes.Modules.Core.Areas.Account.Models.SavedItemViewModel>
<h2>#Localization.GetString("SavedItems")</h2>
#Html.Raw((string)TempData["messages"])
<div class="hc-record-list hc-wishlist clearfix">
#foreach (var item in Model)
{
<div class="hc-record">
<div class="hc-recimage">
<a href="#item.FullProduct.ProductLink">
<img src="#item.FullProduct.ImageUrls.SmallUrl" border="0" alt="#item.FullProduct.ImageUrls.SmallAltText" />
</a>
</div>
<div class="hc-recname">
<h2>#item.FullProduct.Item.ProductName</h2>
<div class="hc-recdescription">
#Html.Raw(item.FullProduct.Item.LongDescription)
</div>
</div>
<div class="hc-reccontrols">
<table class="dnnFormItem">
<tr>
<td class="hc-recprice">
#Html.Raw(item.FullProduct.UserPrice.DisplayPrice(true))
</td>
<td>
#if(!item.FullProduct.Item.IsGiftCard && !item.FullProduct.Item.IsUserSuppliedPrice)
{
using (Html.BeginHccRouteForm(HccRoute.WishList, new { action = "addtocart" }, FormMethod.Post))
{
<input type="hidden" name="itemid" value="#item.SavedItem.Id" />
<input class="dnnPrimaryAction" type="submit" value="#Localization.GetString("AddToCart")" />
}
}
</td>
<td>
#using (Html.BeginHccRouteForm(HccRouteNames.WishList, new { action = "delete" }, FormMethod.Post))
{
<input type="hidden" name="itemid" value="#item.SavedItem.Id" />
<input type="submit" class="hc-delete" value="#Localization.GetString("RemoveSavedItem")" />
}
</td>
</tr>
</table>
</div>
</div>
}
</div>
Below the description of the product, I added the following snippet:
#using Hotcakes.Commerce.Catalog
#if (item.SavedItem.SelectionData != null && item.SavedItem.SelectionData.OptionSelectionList != null && item.SavedItem.SelectionData.OptionSelectionList.Count > 0)
{
<div class="clearfix">
#Html.Raw(item.FullProduct.Item.Options.CartDescription(item.SavedItem.SelectionData.OptionSelectionList))
</div>
}
That makes the entire view look like this:
#using Hotcakes.Commerce.Catalog
#model IEnumerable<Hotcakes.Modules.Core.Areas.Account.Models.SavedItemViewModel>
<h2>#Localization.GetString("SavedItems")</h2>
#Html.Raw((string)TempData["messages"])
<div class="hc-record-list hc-wishlist clearfix">
#foreach (var item in Model)
{
<div class="hc-record">
<div class="hc-recimage">
<a href="#item.FullProduct.ProductLink">
<img src="#item.FullProduct.ImageUrls.SmallUrl" border="0" alt="#item.FullProduct.ImageUrls.SmallAltText" />
</a>
</div>
<div class="hc-recname">
<h2>#item.FullProduct.Item.ProductName</h2>
<div class="hc-recdescription">
#Html.Raw(item.FullProduct.Item.LongDescription)
</div>
#if (item.SavedItem.SelectionData != null && item.SavedItem.SelectionData.OptionSelectionList != null && item.SavedItem.SelectionData.OptionSelectionList.Count > 0)
{
<div class="clearfix">
#Html.Raw(item.FullProduct.Item.Options.CartDescription(item.SavedItem.SelectionData.OptionSelectionList))
</div>
}
</div>
<div class="hc-reccontrols">
<table class="dnnFormItem">
<tr>
<td class="hc-recprice">
#Html.Raw(item.FullProduct.UserPrice.DisplayPrice(true))
</td>
<td>
#if(!item.FullProduct.Item.IsGiftCard && !item.FullProduct.Item.IsUserSuppliedPrice)
{
using (Html.BeginHccRouteForm(HccRoute.WishList, new { action = "addtocart" }, FormMethod.Post))
{
<input type="hidden" name="itemid" value="#item.SavedItem.Id" />
<input class="dnnPrimaryAction" type="submit" value="#Localization.GetString("AddToCart")" />
}
}
</td>
<td>
#using (Html.BeginHccRouteForm(HccRouteNames.WishList, new { action = "delete" }, FormMethod.Post))
{
<input type="hidden" name="itemid" value="#item.SavedItem.Id" />
<input type="submit" class="hc-delete" value="#Localization.GetString("RemoveSavedItem")" />
}
</td>
</tr>
</table>
</div>
</div>
}
</div>