mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 10:14:36 -04:00
Create client (#2543)
* Fix for comparing delete contacts change diffKeys to diff() * Client create * Create client * Create client
This commit is contained in:
parent
7ee295ec44
commit
17a7f0564e
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Client\EditClientRequest;
|
||||
use App\Http\Requests\Client\StoreClientRequest;
|
||||
use App\Http\Requests\Client\UpdateClientRequest;
|
||||
use App\Jobs\Client\StoreClient;
|
||||
use App\Jobs\Client\UpdateClient;
|
||||
@ -12,6 +13,7 @@ use App\Repositories\ClientRepository;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Utils\Traits\UserSessionAttributes;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
use Yajra\DataTables\Html\Builder;
|
||||
|
||||
@ -101,8 +103,11 @@ class ClientController extends Controller
|
||||
public function create()
|
||||
{
|
||||
$client = new Client;
|
||||
$client->name = '';
|
||||
$client->company_id = $this->getCurrentCompanyId();
|
||||
$client_contact = new ClientContact;
|
||||
$client_contact->first_name = "";
|
||||
$client_contact->id = 0;
|
||||
|
||||
$client->contacts->add($client_contact);
|
||||
|
||||
@ -120,16 +125,22 @@ class ClientController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(StoreClientRequest $request)
|
||||
{
|
||||
$client = StoreClient::dispatchNow($request, new Client);
|
||||
$client->load('contacts', 'primary_contact');
|
||||
|
||||
$client->hashed_id = $this->encodePrimarykey($client->id);
|
||||
|
||||
/*
|
||||
$data = [
|
||||
'client' => $client,
|
||||
'hashed_id' => $this->encodePrimarykey($client->id)
|
||||
];
|
||||
*/
|
||||
Log::error(print_r($client,1));
|
||||
return response()->json($client, 200);
|
||||
|
||||
return view('client.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,12 +19,27 @@ class StoreClientRequest extends Request
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
$rules['name'] = 'required';
|
||||
|
||||
$contacts = request('contacts');
|
||||
|
||||
for ($i = 0; $i < count($contacts); $i++) {
|
||||
$rules['contacts.' . $i . '.email'] = 'required|email|unique:client_contacts,email,' . isset($contacts[$i]['id']);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
'contacts.*.email' => 'email|unique:client_contacts,email'
|
||||
|
||||
'unique' => trans('validation.unique', ['attribute' => 'email']),
|
||||
//'required' => trans('validation.required', ['attribute' => 'email']),
|
||||
'contacts.*.email.required' => trans('validation.email', ['attribute' => 'email']),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,7 @@ class UpdateClientRequest extends Request
|
||||
|
||||
public function rules()
|
||||
{
|
||||
|
||||
/* Ensure we have a client name, and that all emails are unique!!!!!*/
|
||||
/* Ensure we have a client name, and that all emails are unique*/
|
||||
$rules['name'] = 'required';
|
||||
|
||||
$contacts = request('contacts');
|
||||
|
@ -19,7 +19,7 @@ class ClientContactRepository extends BaseRepository
|
||||
$contacts = collect($contacts);
|
||||
|
||||
/* Get array of IDs which have been removed from the contacts array and soft delete each contact */
|
||||
collect($client->contacts->pluck('id'))->diffKeys($contacts->pluck('id'))->each(function($contact){
|
||||
collect($client->contacts->pluck('id'))->diff($contacts->pluck('id'))->each(function($contact){
|
||||
ClientContact::destroy($contact);
|
||||
});
|
||||
|
||||
|
2119
public/js/client_create.js
vendored
2119
public/js/client_create.js
vendored
File diff suppressed because one or more lines are too long
2119
public/js/client_create.min.js
vendored
2119
public/js/client_create.min.js
vendored
File diff suppressed because one or more lines are too long
25
public/js/client_edit.js
vendored
25
public/js/client_edit.js
vendored
@ -14972,8 +14972,6 @@ var vue_toastr_1 = __importDefault(__webpack_require__("./node_modules/vue-toast
|
||||
__webpack_require__("./node_modules/vue-toastr/src/vue-toastr.scss");
|
||||
// Register vue component
|
||||
vue_1.default.component('vue-toastr', vue_toastr_1.default);
|
||||
//declare var axios: any;
|
||||
//declare var Vue: any;
|
||||
new vue_1.default({
|
||||
el: '#client_edit',
|
||||
data: function () {
|
||||
@ -14982,16 +14980,16 @@ new vue_1.default({
|
||||
};
|
||||
},
|
||||
mounted: function () {
|
||||
console.log('mounted');
|
||||
//console.log('mounted')
|
||||
},
|
||||
beforeMount: function () {
|
||||
console.log('before mount');
|
||||
//console.log('before mount')
|
||||
},
|
||||
created: function () {
|
||||
console.dir('created');
|
||||
//console.dir('created')
|
||||
},
|
||||
updated: function () {
|
||||
console.dir('updated');
|
||||
//console.dir('updated')
|
||||
},
|
||||
methods: {
|
||||
remove: function (contact) {
|
||||
@ -15000,8 +14998,7 @@ new vue_1.default({
|
||||
},
|
||||
add: function () {
|
||||
var _this = this;
|
||||
console.dir('i will add a contact here');
|
||||
this.form.contacts.push({ first_name: '', last_name: '', email: '', phone: '', id: -1 });
|
||||
this.form.contacts.push({ first_name: '', last_name: '', email: '', phone: '', id: 0 });
|
||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
||||
this.$nextTick(function () {
|
||||
var index = _this.form.contacts.length - 1;
|
||||
@ -15209,12 +15206,24 @@ var Form = /** @class */ (function () {
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Update form data on success
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
Form.prototype.update = function (data) {
|
||||
this.originalData = data;
|
||||
for (var field in data) {
|
||||
this[field] = data[field];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Handle a successful form submission.
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
Form.prototype.onSuccess = function (data) {
|
||||
this.update(data);
|
||||
this.errors.clear();
|
||||
};
|
||||
/**
|
||||
|
25
public/js/client_edit.min.js
vendored
25
public/js/client_edit.min.js
vendored
@ -14972,8 +14972,6 @@ var vue_toastr_1 = __importDefault(__webpack_require__("./node_modules/vue-toast
|
||||
__webpack_require__("./node_modules/vue-toastr/src/vue-toastr.scss");
|
||||
// Register vue component
|
||||
vue_1.default.component('vue-toastr', vue_toastr_1.default);
|
||||
//declare var axios: any;
|
||||
//declare var Vue: any;
|
||||
new vue_1.default({
|
||||
el: '#client_edit',
|
||||
data: function () {
|
||||
@ -14982,16 +14980,16 @@ new vue_1.default({
|
||||
};
|
||||
},
|
||||
mounted: function () {
|
||||
console.log('mounted');
|
||||
//console.log('mounted')
|
||||
},
|
||||
beforeMount: function () {
|
||||
console.log('before mount');
|
||||
//console.log('before mount')
|
||||
},
|
||||
created: function () {
|
||||
console.dir('created');
|
||||
//console.dir('created')
|
||||
},
|
||||
updated: function () {
|
||||
console.dir('updated');
|
||||
//console.dir('updated')
|
||||
},
|
||||
methods: {
|
||||
remove: function (contact) {
|
||||
@ -15000,8 +14998,7 @@ new vue_1.default({
|
||||
},
|
||||
add: function () {
|
||||
var _this = this;
|
||||
console.dir('i will add a contact here');
|
||||
this.form.contacts.push({ first_name: '', last_name: '', email: '', phone: '', id: -1 });
|
||||
this.form.contacts.push({ first_name: '', last_name: '', email: '', phone: '', id: 0 });
|
||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
||||
this.$nextTick(function () {
|
||||
var index = _this.form.contacts.length - 1;
|
||||
@ -15209,12 +15206,24 @@ var Form = /** @class */ (function () {
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Update form data on success
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
Form.prototype.update = function (data) {
|
||||
this.originalData = data;
|
||||
for (var field in data) {
|
||||
this[field] = data[field];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Handle a successful form submission.
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
Form.prototype.onSuccess = function (data) {
|
||||
this.update(data);
|
||||
this.errors.clear();
|
||||
};
|
||||
/**
|
||||
|
@ -1,76 +1,81 @@
|
||||
//import * as Vue from 'vue';
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
import Form from '../utils/form';
|
||||
import Client from '../models/client-model';
|
||||
|
||||
// import Toastr
|
||||
import Toastr from 'vue-toastr';
|
||||
// import toastr scss file: need webpack sass-loader
|
||||
require('vue-toastr/src/vue-toastr.scss');
|
||||
// Register vue component
|
||||
Vue.component('vue-toastr',Toastr);
|
||||
|
||||
declare var client_object: any;
|
||||
declare var hashed_id: string;
|
||||
|
||||
new Vue({
|
||||
el : '#client_create',
|
||||
data: function () {
|
||||
return {
|
||||
'client': [],
|
||||
'errors': [],
|
||||
form: new Form(<Client>client_object)
|
||||
}
|
||||
},
|
||||
mounted(this: any) {
|
||||
//this.client = {!! $client !!};
|
||||
this.client = client_object;
|
||||
console.dir(this.client);
|
||||
//console.log('mounted')
|
||||
},
|
||||
beforeMount: function () {
|
||||
console.log('before mount')
|
||||
//console.log('before mount')
|
||||
},
|
||||
created:function() {
|
||||
console.dir('created')
|
||||
//console.dir('created')
|
||||
},
|
||||
updated:function() {
|
||||
console.dir('updated')
|
||||
//console.dir('updated')
|
||||
},
|
||||
methods:{
|
||||
remove(this:any, contact:any){
|
||||
let index = this.client.contacts.indexOf(contact);
|
||||
this.client.contacts.splice(index, 1);
|
||||
let index = this.form.contacts.indexOf(contact);
|
||||
this.form.contacts.splice(index, 1);
|
||||
},
|
||||
add(this: any){
|
||||
console.dir('i will add a contact here')
|
||||
this.client.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: -1});
|
||||
this.form.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: 0});
|
||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
||||
this.$nextTick(() => {
|
||||
let index = this.client.contacts.length - 1;
|
||||
let index = this.form.contacts.length - 1;
|
||||
let input = this.$refs.first_name[index];
|
||||
input.focus();
|
||||
});
|
||||
},
|
||||
submit(this: any) {
|
||||
this.errors = {};
|
||||
onSubmit() {
|
||||
this.form.post('/clients/')
|
||||
.then(response => {
|
||||
this.$root.$refs.toastr.s("Created client"); //how are we going to handle translations here?
|
||||
|
||||
window.location.href = '/clients/' + this.form.hashed_id + '/edit';
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
this.$root.$refs.toastr.e("Error saving client");
|
||||
|
||||
axios.post('/clients/', this.client).then(response => {
|
||||
// axios.put('/clients/' + {{ $client->present()->id }}, this.client).then(response => {
|
||||
this.client = response.data;
|
||||
}).catch(error => {
|
||||
if (error.response.status === 422) {
|
||||
this.errors = error.response.data.errors || {};
|
||||
}
|
||||
else if(error.response.status === 419) {
|
||||
//csrf token has expired, we'll need to force a page reload
|
||||
}
|
||||
});
|
||||
},
|
||||
copy(type: any) {
|
||||
if(type.includes('copy_billing')){
|
||||
this.client.shipping_address1 = this.client.address1;
|
||||
this.client.shipping_address2 = this.client.address2;
|
||||
this.client.shipping_city = this.client.city;
|
||||
this.client.shipping_state = this.client.state;
|
||||
this.client.shipping_postal_code = this.client.postal_code;
|
||||
this.client.shipping_country_id = this.client.country_id;
|
||||
this.form.shipping_address1 = this.form.address1;
|
||||
this.form.shipping_address2 = this.form.address2;
|
||||
this.form.shipping_city = this.form.city;
|
||||
this.form.shipping_state = this.form.state;
|
||||
this.form.shipping_postal_code = this.form.postal_code;
|
||||
this.form.shipping_country_id = this.form.country_id;
|
||||
}else {
|
||||
this.client.address1 = this.client.shipping_address1;
|
||||
this.client.address2 = this.client.shipping_address2;
|
||||
this.client.city = this.client.shipping_city;
|
||||
this.client.state = this.client.shipping_state;
|
||||
this.client.postal_code = this.client.shipping_postal_code;
|
||||
this.client.country_id = this.client.shipping_country_id;
|
||||
this.form.address1 = this.form.shipping_address1;
|
||||
this.form.address2 = this.form.shipping_address2;
|
||||
this.form.city = this.form.shipping_city;
|
||||
this.form.state = this.form.shipping_state;
|
||||
this.form.postal_code = this.form.shipping_postal_code;
|
||||
this.form.country_id = this.form.shipping_country_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
import Form from '../utils/form';
|
||||
import Client from '../models/client-model';
|
||||
|
||||
// import Toastr
|
||||
import Toastr from 'vue-toastr';
|
||||
// import toastr scss file: need webpack sass-loader
|
||||
@ -11,27 +13,26 @@ Vue.component('vue-toastr',Toastr);
|
||||
|
||||
declare var client_object: any;
|
||||
declare var hashed_id: string;
|
||||
//declare var axios: any;
|
||||
//declare var Vue: any;
|
||||
|
||||
|
||||
new Vue({
|
||||
el : '#client_edit',
|
||||
data: function () {
|
||||
return {
|
||||
form: new Form(client_object)
|
||||
form: new Form(<Client>client_object)
|
||||
}
|
||||
},
|
||||
mounted(this: any) {
|
||||
console.log('mounted')
|
||||
//console.log('mounted')
|
||||
},
|
||||
beforeMount: function () {
|
||||
console.log('before mount')
|
||||
//console.log('before mount')
|
||||
},
|
||||
created:function() {
|
||||
console.dir('created')
|
||||
//console.dir('created')
|
||||
},
|
||||
updated:function() {
|
||||
console.dir('updated')
|
||||
//console.dir('updated')
|
||||
},
|
||||
methods:{
|
||||
remove(this:any, contact:any){
|
||||
@ -39,8 +40,7 @@ declare var hashed_id: string;
|
||||
this.form.contacts.splice(index, 1);
|
||||
},
|
||||
add(this: any){
|
||||
console.dir('i will add a contact here')
|
||||
this.form.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: -1});
|
||||
this.form.contacts.push({first_name: '', last_name: '', email: '', phone: '', id: 0});
|
||||
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
|
||||
this.$nextTick(() => {
|
||||
let index = this.form.contacts.length - 1;
|
||||
|
@ -136,13 +136,27 @@ export default class Form {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update form data on success
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
update(data)
|
||||
{
|
||||
this.originalData = data;
|
||||
|
||||
for (let field in data) {
|
||||
this[field] = data[field];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a successful form submission.
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
onSuccess(data) {
|
||||
|
||||
this.update(data);
|
||||
this.errors.clear();
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,11 @@
|
||||
<!-- Breadcrumb-->
|
||||
{{ Breadcrumbs::render('clients.create') }}
|
||||
|
||||
<form @submit.prevent="submit">
|
||||
<form @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
|
||||
<div class="container-fluid">
|
||||
|
||||
<vue-toastr ref="toastr"></vue-toastr>
|
||||
|
||||
<div class="row">
|
||||
<!-- Client Details and Address Column -->
|
||||
<div class="col-md-6">
|
||||
@ -29,7 +31,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<template v-for="contact in client.contacts">
|
||||
<template v-for="(contact, key, index) in form.contacts">
|
||||
@include('client.partial.contact_details')
|
||||
</template>
|
||||
|
||||
@ -40,7 +42,7 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-center">
|
||||
<button class="btn btn-lg btn-success" type="button" @click="submit"><i class="fa fa-save"></i> {{ trans('texts.save') }}</button>
|
||||
<button class="btn btn-lg btn-success" type="button" @click="onSubmit"><i class="fa fa-save"></i> {{ trans('texts.save') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -51,6 +53,7 @@
|
||||
</main>
|
||||
<script>
|
||||
var client_object = {!! $client !!};
|
||||
var hashed_id = '';
|
||||
</script>
|
||||
|
||||
<script defer src=" {{ mix('/js/client_create.min.js') }}"></script>
|
||||
|
@ -6,10 +6,26 @@
|
||||
<!-- Breadcrumb-->
|
||||
{{ Breadcrumbs::render('clients.edit', $client) }}
|
||||
|
||||
<form @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
|
||||
<vue-toastr ref="toastr"></vue-toastr>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<vue-toastr ref="toastr"></vue-toastr>
|
||||
<div class="col" style="padding: 0px;">
|
||||
<ul class="nav nav-pills mb-1" id="pills-tab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active show" id="pills-home-tab" data-toggle="pill" href="#pills-home" role="tab" aria-controls="pills-home" aria-selected="true"><i class="icon-user"></i> Client</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false"><i class="icon-settings"></i> Settings</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="pills-tabContent">
|
||||
|
||||
<div class="tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab" style="background-color: #e4e5e6; padding: 0px;">
|
||||
|
||||
<form @submit.prevent="onSubmit" @keydown="form.errors.clear($event.target.name)">
|
||||
|
||||
<div class="row">
|
||||
<!-- Client Details and Address Column -->
|
||||
@ -24,33 +40,59 @@
|
||||
|
||||
<!-- Contact Details Column -->
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="card">
|
||||
|
||||
<div class="card-header bg-primary2">{{ trans('texts.contact_information') }}
|
||||
|
||||
<span class="float-right">
|
||||
|
||||
<button type="button" class="btn btn-primary btn-sm" @click="add()"><i class="fa fa-plus-circle"></i> {{ trans('texts.add_contact') }}</button>
|
||||
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<template v-for="(contact, key, index) in form.contacts">
|
||||
|
||||
@include('client.partial.contact_details')
|
||||
|
||||
</template>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End Contact Details Column -->
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12 text-center">
|
||||
|
||||
<button class="btn btn-lg btn-success" type="button" @click="onSubmit"><i class="fa fa-save"></i> {{ trans('texts.save') }}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">
|
||||
|
||||
Etsy mixtape wayfarers, ethical wes anderson tofu before they sold out mcsweeney's organic lomo retro fanny pack lo-fi farm-to-table readymade. Messenger bag gentrify pitchfork tattooed craft beer, iphone skateboard locavore carles etsy salvia banksy
|
||||
hoodie helvetica. DIY synth PBR banksy irony. Leggings gentrify squid 8-bit cred pitchfork. Williamsburg banh mi whatever gluten-free, carles pitchfork biodiesel fixie etsy retro mlkshk vice blog. Scenester cred you probably haven't
|
||||
heard of them, vinyl craft beer blog stumptown. Pitchfork sustainable tofu synth chambray yr.
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<script>
|
||||
var client_object = {!! $client !!};
|
||||
var hashed_id = '{{ $hashed_id }}';
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="form-group row">
|
||||
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.client_name')</label>
|
||||
<div class="col-sm-9">
|
||||
<input name="name" placeholder="@lang('texts.name')" class="form-control" v-model="form.name" value="{{ $client->name }}">
|
||||
<input name="name" placeholder="@lang('texts.name')" class="form-control" v-model="form.name">
|
||||
<div v-if="form.errors.has('name')" class="text-danger" v-text="form.errors.get('name')"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
37
resources/views/vendor/datatables/print.blade.php
vendored
Normal file
37
resources/views/vendor/datatables/print.blade.php
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Print Table</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name=description content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
body {margin: 20px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="table table-bordered table-condensed table-striped">
|
||||
@foreach($data as $row)
|
||||
@if ($row == reset($data))
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
<th>{!! $key !!}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
@if(is_string($value) || is_numeric($value))
|
||||
<td>{!! $value !!}</td>
|
||||
@else
|
||||
<td></td>
|
||||
@endif
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
1
resources/views/vendor/datatables/script.blade.php
vendored
Normal file
1
resources/views/vendor/datatables/script.blade.php
vendored
Normal file
@ -0,0 +1 @@
|
||||
(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["%1$s"]=$("#%1$s").DataTable(%2$s);})(window,jQuery);
|
Loading…
x
Reference in New Issue
Block a user