resq/templates/vehicle/form.html.twig
2023-02-02 09:09:44 +00:00

400 lines
16 KiB
Twig

{% extends 'base.html.twig' %}
{% block body %}
<!-- BEGIN: Subheader -->
<div class="m-subheader">
<div class="d-flex align-items-center">
<div class="mr-auto">
<h3 class="m-subheader__title">Vehicles</h3>
</div>
</div>
</div>
<!-- END: Subheader -->
<div class="m-content">
<!--Begin::Section-->
<div class="row">
<div class="col-xl-10">
<div class="m-portlet m-portlet--mobile">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<span class="m-portlet__head-icon">
<i class="fa fa-car"></i>
</span>
<h3 class="m-portlet__head-text">
{% if mode == 'update' %}
Edit Vehicle
<small>{{ obj.getManufacturer().getName() ~ ' ' ~ obj.getMake() ~ ' ' ~ obj.getModelYearFrom() ~ '-' ~ obj.getModelYearTo() }}</small>
{% else %}
New Vehicle
{% endif %}
</h3>
</div>
</div>
</div>
<form id="row-form" class="m-form m-form--fit m-form--label-align-right m-form--group-seperator-dashed" method="post" action="{{ mode == 'update' ? url('vehicle_update_submit', {'id': obj.getId()}) : url('vehicle_create_submit') }}">
<div class="m-portlet__body">
<div class="form-group m-form__group row no-border">
<label class="col-lg-3 col-form-label" data-field="manufacturer">
Manufacturer:
</label>
<div class="col-lg-9">
<select class="form-control m-input" id="manufacturer" name="manufacturer">
<option value=""></option>
{% for manufacturer in manufacturers %}
<option value="{{ manufacturer.getID() }}"{{ obj.Manufacturer() and manufacturer.getID() == obj.getManufacturer().getID() ? ' selected' }}>{{ manufacturer.getName() }}</option>
{% endfor %}
</select>
<div class="form-control-feedback hide" data-field="manufacturer"></div>
</div>
</div>
<div class="form-group m-form__group row no-border">
<label class="col-lg-3 col-form-label" data-field="make">
Make:
</label>
<div class="col-lg-9">
<input type="text" name="make" class="form-control m-input" value="{{ obj.getMake() }}">
<div class="form-control-feedback hide" data-field="make"></div>
</div>
</div>
<div class="form-group m-form__group row">
<label class="col-lg-3 col-form-label" data-field="model_year_from">
Year:
</label>
<div class="col-lg-9 flex-row">
<select class="form-control m-input" id="model_year_to" name="model_year_from">
<option value=""></option>
{% for year in years %}
<option value="{{ year }}"{{ obj.getModelYearFrom() == year ? ' selected' }}>{{ year }}</option>
{% endfor %}
</select>
<label class="col-form-label text-center">
to
</label>
<select class="form-control m-input" id="model_year_from" name="model_year_to">
<option value=""></option>
{% for year in years %}
<option value="{{ year }}"{{ obj.getModelYearTo() == year ? ' selected' }}>{{ year }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group m-form__group row">
<label class="col-3 col-form-label">
In Mobile App:
</label>
<div class="col-3">
<span class="m-switch m-switch--icon">
<label>
<input type="checkbox" name="flag_mobile" id="flag_mobile" value="1"{{ obj.shouldDisplayMobile() ? ' checked' }}>
<span></span>
</label>
</span>
</div>
</div>
{% if mode == 'update' %}
<div class="m-form__seperator m-form__seperator--dashed"></div>
<div class="m-form__section m-form__section--last">
<div class="m-form__heading">
<h3 class="m-form__heading-title">
Compatible Batteries
</h3>
</div>
<div class="form-group m-form__group row">
<div class="col-lg-12">
<div class="m_datatable" id="data-batts"></div>
</div>
</div>
<div class="form-group m-form__group row">
<label class="col-lg-1 col-form-label" data-field="battery_list">
Add Battery:
</label>
<div class="col-lg-3">
<select name="bmfg_list" class="form-control m-input" id="bmfg">
{% for bmfg in bmfgs %}
<option value="{{ bmfg.getID }}">{{ bmfg.getName }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<select name="bmodel_list" class="form-control m-input" id="bmodel">
{% for bmodel in bmodels %}
<option value="{{ bmodel.getID }}">{{ bmodel.getName }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<select name="bsize_list" class="form-control m-input" id="bsize">
{% for bsize in bsizes %}
<option value="{{ bsize.getID }}">{{ bsize.getName }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<button type="button" class="btn btn-primary" id="btn-add-battery" >Add to List</button>
</div>
</div>
</div>
{% endif %}
</div>
<div class="m-portlet__foot m-portlet__foot--fit">
<div class="m-form__actions m-form__actions--solid m-form__actions--right">
<div class="row">
<div class="col-lg-12">
<button type="submit" class="btn btn-success">Submit</button>
<a href="{{ url('vehicle_list') }}" class="btn btn-secondary">Back</a>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
$(function() {
$("#row-form").submit(function(e) {
var form = $(this);
var formdata = form.serialize();
e.preventDefault();
// add battery data
bdata = '';
$.each(battRows, function(index, battery) {
bdata += "&batteries%5B%5D=" + battery.id;
});
// append to form data
formdata += bdata;
$.ajax({
method: "POST",
url: form.prop('action'),
data: formdata
}).done(function(response) {
// remove all error classes
removeErrors();
swal({
title: 'Done!',
text: 'Your changes have been saved!',
type: 'success',
onClose: function() {
window.location.href = "{{ url('vehicle_list') }}";
}
});
}).fail(function(response) {
if (response.status == 422) {
var errors = response.responseJSON.errors;
var firstfield = false;
// remove all error classes first
removeErrors();
// display errors contextually
$.each(errors, function(field, msg) {
var formfield = $("[name='" + field + "']");
var label = $("label[data-field='" + field + "']");
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
// add error classes to bad fields
formfield.addClass('form-control-danger');
label.addClass('has-danger');
msgbox.html(msg).addClass('has-danger').removeClass('hide');
// check if this field comes first in DOM
var domfield = formfield.get(0);
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
firstfield = domfield;
}
});
// focus on first bad field
firstfield.focus();
// scroll to above that field to make it visible
$('html, body').animate({
scrollTop: $(firstfield).offset().top - 200
}, 100);
}
});
});
// initialize battery arrays
var battRows = [];
var batteryIds = [];
var battMfgModelSize = []
{% for batt in obj.getBatteries %}
trow = {
id: "{{ batt.getID }}",
manufacturer: "{{ batt.getManufacturer.getName|default('') }} ",
model: "{{ batt.getModel.getName|default('') }}",
size: "{{ batt.getSize.getName|default('') }}",
sell_price: "{{ batt.getSellingPrice }}",
flag_active: "{{ batt.isActive }}"
};
battRows.push(trow);
batteryIds.push({{ batt.getID }});
battMfgModelSize.push({{ batt.getManufacturer.getID }} + ' ' + {{ batt.getModel.getID }} + ' ' + {{ batt.getSize.getID }});
{% endfor %}
// remove battery from table
$(document).on('click', '.btn-delete', function(e) {
var btn = $(this);
var id = $(this).data('id');
$.each(battRows, function(index, battery) {
if (battery.id == id) {
battRows.splice(index, 1);
return false;
}
});
// remove from battery ids
batteryIds.splice(batteryIds.indexOf(id), 1);
// reload table
battTable.row(btn.parents('tr')).remove();
battTable.originalDataSet = battRows;
battTable.reload();
});
// add a battery to the table
$("#btn-add-battery").click(function() {
var bmfg_id = $("#bmfg").val();
var bmodel_id = $("#bmodel").val();
var bsize_id = $("#bsize").val();
var batt_key = (bmfg_id + ' ' + bmodel_id + ' ' + bsize_id);
if (battMfgModelSize.indexOf(batt_key) !== -1) {
swal({
title: 'Whoops',
text: 'This battery is already on the list.',
type: 'warning'
});
return true;
}
// get the battery given the model and size
$.ajax({
method: "GET",
url: "{{ url('battery_ajax_get') }}",
data: {mfg_id: bmfg_id, model_id: bmodel_id, size_id: bsize_id}
}).done(function(response) {
if (response.data.length > 0) {
var batt = response.data[0];
batteryIds.push(batt.id);
brow = {
id: batt.id,
manufacturer: batt.manufacturer,
model: batt.model,
size: batt.size,
sell_price: batt.price
};
battRows.push(brow);
// add battery to arrays
battMfgModelSize.push(batt_key);
// refresh the data table
battTable.originalDataSet = battRows;
battTable.reload();
}
}).fail(function(response) {
// TODO: change response status to 404. For some strange reason,
// if status is set to 422, the swal does not display.
// Instead, we get the technical error box.
if (response.status == 422) {
swal({
title: 'Whoops',
text: 'This battery does not exist.',
type: 'warning'
});
return true;
}
});
});
// battery data table
var battOptions = {
data: {
type: 'local',
source: battRows,
saveState: {
cookie: false,
webstorage: false
}
},
layout: {
scroll: true
},
rows: {
beforeTemplate: function(row, data, index) {
var is_active = data.flag_active;
if (is_active == false) {
$(row).addClass('hide');
}
}
},
columns: [
{
field: 'id',
title: 'ID',
width: 50
},
{
field: 'manufacturer',
title: 'Manufacturer',
},
{
field: 'size',
title: 'Size'
},
{
field: 'model',
title: 'Model',
width: 150
},
{
field: 'sell_price',
title: 'Price'
},
{
field: 'Actions',
width: 70,
title: 'Actions',
sortable: false,
overflow: 'visible',
template: function (row, index, datatable) {
return '<button data-id="' + row.id + '" type="button" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" title="Delete"><i class="la la-trash"></i></button>';
},
}
],
pagination: false
};
var battTable = $("#data-batts").mDatatable(battOptions);
// remove all error classes
function removeErrors() {
$(".form-control-danger").removeClass('form-control-danger');
$("[data-field]").removeClass('has-danger');
$(".form-control-feedback[data-field]").addClass('hide');
}
});
</script>
{% endblock %}