A ton of progress, search start
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
22
resources/assets/js/app.js
vendored
22
resources/assets/js/app.js
vendored
@ -1,22 +0,0 @@
|
||||
|
||||
/**
|
||||
* First we will load all of this project's JavaScript dependencies which
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
|
||||
require('./bootstrap');
|
||||
|
||||
window.Vue = require('vue');
|
||||
|
||||
/**
|
||||
* Next, we will create a fresh Vue application instance and attach it to
|
||||
* the page. Then, you may begin adding components to this application
|
||||
* or customize the JavaScript scaffolding to fit your unique needs.
|
||||
*/
|
||||
|
||||
Vue.component('example-component', require('./components/ExampleComponent.vue'));
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app'
|
||||
});
|
@ -1,23 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Example Component</div>
|
||||
|
||||
<div class="panel-body">
|
||||
I'm an example component!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
console.log('Component mounted.')
|
||||
}
|
||||
}
|
||||
</script>
|
38
resources/assets/sass/_variables.scss
vendored
38
resources/assets/sass/_variables.scss
vendored
@ -1,38 +0,0 @@
|
||||
|
||||
// Body
|
||||
$body-bg: #f5f8fa;
|
||||
|
||||
// Borders
|
||||
$laravel-border-color: darken($body-bg, 10%);
|
||||
$list-group-border: $laravel-border-color;
|
||||
$navbar-default-border: $laravel-border-color;
|
||||
$panel-default-border: $laravel-border-color;
|
||||
$panel-inner-border: $laravel-border-color;
|
||||
|
||||
// Brands
|
||||
$brand-primary: #3097D1;
|
||||
$brand-info: #8eb4cb;
|
||||
$brand-success: #2ab27b;
|
||||
$brand-warning: #cbb956;
|
||||
$brand-danger: #bf5329;
|
||||
|
||||
// Typography
|
||||
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
|
||||
$font-family-sans-serif: "Raleway", sans-serif;
|
||||
$font-size-base: 14px;
|
||||
$line-height-base: 1.6;
|
||||
$text-color: #636b6f;
|
||||
|
||||
// Navbar
|
||||
$navbar-default-bg: #fff;
|
||||
|
||||
// Buttons
|
||||
$btn-default-color: $text-color;
|
||||
|
||||
// Inputs
|
||||
$input-border: lighten($text-color, 40%);
|
||||
$input-border-focus: lighten($brand-primary, 25%);
|
||||
$input-color-placeholder: lighten($text-color, 30%);
|
||||
|
||||
// Panels
|
||||
$panel-default-heading-bg: #fff;
|
9
resources/assets/sass/app.scss
vendored
9
resources/assets/sass/app.scss
vendored
@ -1,9 +0,0 @@
|
||||
|
||||
// Fonts
|
||||
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
|
||||
|
||||
// Variables
|
||||
@import "variables";
|
||||
|
||||
// Bootstrap
|
||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap";
|
133
resources/js/app.js
vendored
Normal file
133
resources/js/app.js
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
|
||||
/**
|
||||
* First we will load all of this project's JavaScript dependencies which
|
||||
* includes Vue and other libraries. It is a great starting point when
|
||||
* building robust, powerful web applications using Vue and Laravel.
|
||||
*/
|
||||
|
||||
require('./bootstrap');
|
||||
|
||||
$(document).ready(function(e) {
|
||||
|
||||
$.fn.dataTable.render.authorValue = function(_, context, book) {
|
||||
let authors = [];
|
||||
|
||||
console.log(book);
|
||||
for (let author of book.authors) {
|
||||
authors.push(author.name);
|
||||
}
|
||||
|
||||
return authors.join(', ');
|
||||
};
|
||||
|
||||
var authorOptions = {
|
||||
placeholder: 'Authors',
|
||||
tags: true,
|
||||
ajax: {
|
||||
url: '/authors/search',
|
||||
dataType: 'json'
|
||||
}
|
||||
};
|
||||
|
||||
var locationOptions = {
|
||||
placeholder: 'Location',
|
||||
tags: true
|
||||
};
|
||||
|
||||
$('#add-form .select2-author').select2(authorOptions);
|
||||
|
||||
$('#add-form .select2-location').select2(locationOptions);
|
||||
|
||||
$('#add-form').on('click', '.remove-row', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
$(this).closest('.form-row').remove();
|
||||
});
|
||||
|
||||
$('#add-form').on('keydown', '.barcode_input', function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
$('#add-form').on('keyup', '.barcode_input', function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
// Do something
|
||||
e.preventDefault();
|
||||
|
||||
var $this = $(this),
|
||||
$row = $this.closest('.form-row'),
|
||||
barcodeValue = $this.val();
|
||||
|
||||
if (barcodeValue === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$.get('/lookup/' + barcodeValue, function(res) {
|
||||
$row.find('input[name*=name]').val(res.title);
|
||||
|
||||
var $authors = $row.find('.select2-author');
|
||||
|
||||
$authors.children('option').remove();
|
||||
|
||||
for (var i = 0; i < res.authors.length; i++) {
|
||||
$authors.append($('<option>', {value: res.authors[i], text: res.authors[i], selected: 'selected'}));
|
||||
}
|
||||
|
||||
$authors.trigger('change');
|
||||
}, 'json');
|
||||
|
||||
var count = emptyRowCount();
|
||||
|
||||
console.log('Empty rows:', count);
|
||||
|
||||
if (count < 1) {
|
||||
var firstIndex = 0,
|
||||
$container = $row.closest('.row-container');
|
||||
|
||||
|
||||
for (var i = 0; i < 200; i++) {
|
||||
if ($container.find('.form-row[data-index=' + i + ']').length < 1) {
|
||||
firstIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var $template = $('#add-template'),
|
||||
$clone = $template.clone();
|
||||
|
||||
$clone.attr('data-index', firstIndex);
|
||||
|
||||
$clone.find('input, select').each(function() {
|
||||
$(this).attr('name', $(this).attr('name').replace('__INDEX__', firstIndex));
|
||||
});
|
||||
|
||||
$clone.removeAttr('id');
|
||||
$clone.find('input[type=text]').val('');
|
||||
|
||||
$clone.removeClass('invisible').addClass('form-row');
|
||||
|
||||
$container.append($clone);
|
||||
|
||||
setTimeout(function() {
|
||||
$clone.find('.barcode_input').focus();
|
||||
$clone.find('.select2-author').select2(authorOptions);
|
||||
}, 150);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function emptyRowCount() {
|
||||
var $barcodes = $('#add-form .barcode_input');
|
||||
|
||||
var count = 0;
|
||||
|
||||
$barcodes.each(function() {
|
||||
if ($(this).val() == '') {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
|
||||
window._ = require('lodash');
|
||||
|
||||
/**
|
||||
@ -8,9 +7,13 @@ window._ = require('lodash');
|
||||
*/
|
||||
|
||||
try {
|
||||
window.Popper = require('popper.js').default;
|
||||
window.$ = window.jQuery = require('jquery');
|
||||
|
||||
require('bootstrap-sass');
|
||||
require('bootstrap');
|
||||
require('select2');
|
||||
require('datatables.net-bs4');
|
||||
require('datatables.net-buttons-bs4');
|
||||
} catch (e) {}
|
||||
|
||||
/**
|
||||
@ -23,31 +26,19 @@ window.axios = require('axios');
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Next we will register the CSRF Token as a common header with Axios so that
|
||||
* all outgoing HTTP requests automatically have it attached. This is just
|
||||
* a simple convenience so we don't have to attach every token manually.
|
||||
*/
|
||||
|
||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
||||
|
||||
if (token) {
|
||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
||||
} else {
|
||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Echo exposes an expressive API for subscribing to channels and listening
|
||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo'
|
||||
// import Echo from 'laravel-echo';
|
||||
|
||||
// window.Pusher = require('pusher-js');
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: 'your-pusher-key'
|
||||
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||
// forceTLS: true
|
||||
// });
|
14
resources/sass/app.scss
vendored
Normal file
14
resources/sass/app.scss
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// Bootstrap
|
||||
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||
|
||||
// DataTables
|
||||
@import "../../node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css";
|
||||
@import "../../node_modules/datatables.net-buttons-bs4/css/buttons.bootstrap4.css";
|
||||
|
||||
body {
|
||||
padding-top: 5rem;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
padding-bottom: 6px;
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
<form id="add-form">
|
||||
<form id="add-form" method="POST" action="{{ route('save') }}">
|
||||
{{ csrf_field() }}
|
||||
<div class="form-row justify-content-md-center">
|
||||
<div class="col-4">
|
||||
<select name="location" class="form-control select2-location">
|
||||
@ -9,29 +10,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-row">
|
||||
<div class="col">
|
||||
<input name="books[][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input name="books[][name]" type="text" class="form-control" placeholder="Name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<select name="books[][authors]" class="form-control select2-author" multiple="multiple">
|
||||
</select>
|
||||
</div>
|
||||
<div class="row-container">
|
||||
@if (!empty($old))
|
||||
@foreach ($old as $index => $item)
|
||||
@include('partials/row', [ 'index' => $index, 'item' => $item ])
|
||||
@endforeach
|
||||
@include('partials/row', [ 'index' => count($old), 'item' => [] ])
|
||||
@else
|
||||
@include('partials/row', [ 'index' => 0])
|
||||
@endif
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="btn btn-primary" name="save" type="submit">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div id="add-template" class="invisible">
|
||||
<div class="col">
|
||||
<input name="books[][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input name="books[][name]" type="text" class="form-control" placeholder="Name">
|
||||
</div>
|
||||
<div class="col">
|
||||
<select name="books[][authors]" class="form-control select2-author" multiple="multiple">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@include('partials/row', [ 'id' => 'add-template', 'htmlClass' => 'invisible' ])
|
||||
@endsection
|
21
resources/views/index.blade.php
Normal file
21
resources/views/index.blade.php
Normal file
@ -0,0 +1,21 @@
|
||||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
<table class="table table-compact">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Authors</th>
|
||||
<th>Location</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($rows as $row)
|
||||
<tr>
|
||||
<td>{{ $row->name }}</td>
|
||||
<td>{{ $row->authors->pluck('name')->join(', ') }}</td>
|
||||
<td>{{ $row->location->name }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $rows->links() }}
|
||||
@endsection
|
@ -8,49 +8,20 @@
|
||||
|
||||
<title>{{ config('app.name') }}</title>
|
||||
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="{{ url('css/bootstrap.min.css') }}" rel="stylesheet">
|
||||
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
|
||||
<link href="{{ url('css/select2-bs4.css') }}" rel="stylesheet">
|
||||
<link href="{{ url('css/app.css') }}" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||
<a class="navbar-brand" href="#">{{ config('app.name') }}</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
||||
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/add">Add</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0">
|
||||
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
@include('partials/navbar')
|
||||
|
||||
<main role="main" class="container">
|
||||
@yield('content')
|
||||
</main><!-- /.container -->
|
||||
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.2.1.min.js"
|
||||
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
|
||||
<script src="{{ url('js/bootstrap.min.js') }}"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
|
||||
<script src="{{ url('js/app.js') }}"></script>
|
||||
<script src="{{ mix('js/app.js') }}"></script>
|
||||
<script src="{{ asset('vendor/datatables/buttons.server-side.js') }}"></script>
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
||||
|
22
resources/views/partials/navbar.blade.php
Normal file
22
resources/views/partials/navbar.blade.php
Normal file
@ -0,0 +1,22 @@
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||
<a class="navbar-brand" href="#">{{ config('app.name') }}</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
||||
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/add">Add</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" action="{{ route('search') }}">
|
||||
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" />
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
20
resources/views/partials/row.blade.php
Normal file
20
resources/views/partials/row.blade.php
Normal file
@ -0,0 +1,20 @@
|
||||
<div {!! !empty($id) ? 'id="' . $id . '" ' : '' !!}class="form-row {{ $htmlClass ?? '' }}" data-index="{{ $index ?? '__INDEX__' }}">
|
||||
<div class="col">
|
||||
<input name="books[{{ $index ?? '__INDEX__' }}][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode" value="{{ $item['barcode'] ?? '' }}">
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<input name="books[{{ $index ?? '__INDEX__' }}][name]" type="text" class="form-control" placeholder="Name" value="{{ $item['name'] ?? '' }}">
|
||||
</div>
|
||||
<div class="col">
|
||||
<select name="books[{{ $index ?? '__INDEX__' }}][authors][]" class="form-control select2-author" multiple="multiple">
|
||||
@if(!empty($item['authors']))
|
||||
@foreach($item['authors'] as $author)
|
||||
<option value="{{ $author }}" selected="selected">{{ $author }}</option>
|
||||
@endforeach
|
||||
@endif
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<button class="remove-row btn btn-danger">Remove</button>
|
||||
</div>
|
||||
</div>
|
@ -1 +0,0 @@
|
||||
@extends('layouts.main')
|
Reference in New Issue
Block a user