In a previous tutorial, I talked about the CrudField JavaScript Library. I presented an example on how to change one field as the user...
In a previous tutorial, I talked about the CrudField JavaScript Library. I presented an example on how to change one field as the user types in another field - live, as they do it.
In this tutorial, I will show another frequent use case, asked by a Backpack user: How do you create a total field, thats sums up inputs in the repeatable? In order to do that, you need to learn:
Let's find the answer of these questions. There's no better way than an example - let's see some code!
Our user loved that in our demo, we have an Invoice CRUD. Great for adding multiple items to the invoice. But something is missing here - it does not show live subtotal and total while the user makes inputs. The user expects to see the subtotal and total before saving.
You got the idea now! Let's change the CRUD a bit to get it to function like this.
+CRUD::field('total')
+ ->size(2)
+ ->attributes(['readonly' => 'readonly', 'disabled' => 'disabled'])
+ ->prefix('$');
CRUD::field('items')
->subfields([
[
'name' => 'description',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-7',
],
],
[
'name' => 'quantity',
'type' => 'number',
'attributes' => ['step' => 'any', 'min' => 0],
'wrapper' => [
'class' => 'form-group col-md-1',
],
],
[
'name' => 'unit_price',
'type' => 'number',
'prefix' => '$',
'attributes' => ['step' => 'any', 'min' => 0],
'wrapper' => [
'class' => 'form-group col-md-2',
],
],
+ [
+ 'name' => 'subtotal',
+ 'type' => 'number',
+ 'prefix' => '$',
+ 'wrapper' => ['class' => 'form-group col-md-2'],
+ 'attributes' => ['readonly' => 'readonly', 'disabled' => 'disabled'],
+ ],
])
->reorder('order');
public/assets/js/admin/forms/invoice.js
to put the form related javascript code. I use Script Widget to include the javascript file to the CRUD form;+ use Backpack\CRUD\app\Library\Widget;
protected function setupCreateOperation()
{
+ Widget::add()
+ ->type('script')
+ ->content(asset('assets/js/admin/forms/invoice.js'));
// Reset of the code
}
Yes, the invoice.js
code.
onChange
event of quantity
and unit_price
field. This updates the subtotal on the row:['quantity', 'unit_price'].forEach((name) => {
crud.field('items').subfield(name).onChange(updateSubTotal);
});
function updateSubTotal(current_field) {
const other_field = current_field.name === 'quantity' ? 'unit_price' : 'quantity';
// Get the current rowNumber
// and the value of the other field from the row
const other_field_value = crud.field('items').subfield(other_field, current_field.rowNumber).input.value;
// Calculate and update the subtotal field of the row
var subtotal = current_field.input.value * other_field_value;
crud.field('items').subfield('subtotal', current_field.rowNumber).input.value = subtotal;
// Finaly update the total field
updateTotal();
}
// Attach event to 'items' row addition or removal
crud.field('items').onChange(function (field) {
updateTotal();
});
function updateTotal() {
var total = 0;
$total_rows = crud.field('items').wrapper.find('.repeatable-element').length;
for (var row = 1; row <= $total_rows; row++) {
var subtotal = parseFloat(crud.field('items').subfield('subtotal', row).input.value);
total += subtotal;
}
crud.field('total').input.value = total;
}
Thats it! You can see it working now.
I hope you find this tutorial easy and helpful. CrudField JavaScript Library helps you build complex features like this one, without writing all the Javascript yourself. Let me know if there is something on which you want to see a guide. I'll try to come up with that!
Thanks for reading and using Backpack :)
Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.
What do you think about this?
Wondering what our community has been up to?