Git Product home page Git Product logo

calculated-field's Introduction

A Server-Side Calculated Field For Laravel Nova

This package contains two Nova fields required to do server-side calculations from the Nova client. The user can optionally override the calculated value on the form.

For a detailed write-up of the how-and-why of this field, please visit:

https://codebykyle.com/blog/laravel-nova-custom-calculated-field

Installation

Install the package via composer:

composer require codebykyle/calculated-field

Example

For example:

As a number

Calculated Number Field

As a string:

Calculated String Field

Default

The Listener field will by default sum all numbers passed to it

Usage

<?php

use Codebykyle\CalculatedField\BroadcasterField;
use Codebykyle\CalculatedField\ListenerField;

class MyResource extends Resource
{
    public function fields(Request $request) {
        return [    
            BroadcasterField::make('Sub Total', 'sub_total'),
            BroadcasterField::make('Tax', 'tax'),
            ListenerField::make('Total Field', 'total_field')
        ];
    }
}

Overriding the Callback

<?php
use Codebykyle\CalculatedField\BroadcasterField;
use Codebykyle\CalculatedField\ListenerField;

class MyResource extends Resource
{
    public function fields(Request $request) {
        return [    
            BroadcasterField::make('Sub Total', 'sub_total'),
            BroadcasterField::make('Tax', 'tax'),

            ListenerField::make('Total Field', 'total_field')
                ->calculateWith(function (Collection $values) {
                    $subtotal = $values->get('sub_total');
                    $tax = $values->get('tax');
                    return $subtotal + $tax;
                }),
        ];
    }
}

String Fields

<?php
use Codebykyle\CalculatedField\BroadcasterField;
use Codebykyle\CalculatedField\ListenerField;

class MyResource extends Resource
{
    public function fields(Request $request) {
        return [    
            BroadcasterField::make('First Name', 'first_name')
                ->setType('string'),

            BroadcasterField::make('Last Name', 'last_name')
                ->setType('string'),

            ListenerField::make('Full Name', 'full_name')
                ->calculateWith(function (Collection $values) {
                    return $values->values()->join(' ');
                }),
        ];
    }
}

Multiple Calculated Fields

<?php
use Codebykyle\CalculatedField\BroadcasterField;
use Codebykyle\CalculatedField\ListenerField;

class MyResource extends Resource
{
    public function fields(Request $request) {
        return [    
            BroadcasterField::make('Sub Total', 'sub_total')
                ->broadcastTo('total'),

            BroadcasterField::make('Tax', 'tax')
                ->broadcastTo('total'),

            ListenerField::make('Total Field', 'total_field')
                ->listensTo('total')
                ->calculateWith(function (Collection $values) {
                    $subtotal = $values->get('sub_total');
                    $tax = $values->get('tax');
                    return $subtotal + $tax;
                }),


            BroadcasterField::make('Senior Discount', 'senior_discount')
                ->broadcastTo('discount'),
    
            BroadcasterField::make('Coupon Discount', 'coupon_amount')
                ->broadcastTo('discount'),
    
            ListenerField::make('Total Discount', 'total_discount')
                ->listensTo('discount')
                ->calculateWith(function (Collection $values) {
                    $seniorDiscount = $values->get('senior_discount');
                    $couponAmount = $values->get('coupon_amount');
    
                    return $seniorDiscount + $couponAmount;
                })
        ];
    }
}

calculated-field's People

Contributors

codebykyle avatar marcuschristiansen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

calculated-field's Issues

Abandoned project

I think this is an abandoned project. Last commit was 5 month ago, currently there are 6 issues and 2 open pullrequest. Any chance to update this project? @codebykyle

Getting error when trying Overriding the Callback

Hi,

I am getting this error when I try to overwriting the callback like shown in the examples:

<?php
use Codebykyle\CalculatedField\BroadcasterField;
use Codebykyle\CalculatedField\ListenerField;

class MyResource extends Resource
{
    public function fields(Request $request) {
        return [    
            BroadcasterField::make('Sub Total', 'sub_total'),
            BroadcasterField::make('Tax', 'tax'),

            ListenerField::make('Total Field', 'total_field')
                ->calculateWith(function (Collection $values) {
                    $subtotal = $values->get('sub_total');
                    $tax = $values->get('tax');
                    return $subtotal + $tax;
                }),
        ];
    }
}

Argument 1 passed to App\Nova\Order::App\Nova\{closure}() must be an instance of App\Nova\Collection, instance of Illuminate\Support\Collection given

any thoughts?

Does not work with existing db values

If the BroadcasterFields have existing values in db.
Those field values are not accounted for when an update form is loaded.
Which makes the User think that the calculation is incorrect.

For better usability it would be best if the initial values of all BroadcasterFields are emitted to the listeners when they are mounted.

Example screen recording
https://www.dropbox.com/s/6izb4h2dxkp8x00/Sk%C3%A4rminspelning%202019-10-14%20kl.%2018.55.21.mov?dl=0

BroadcasterField::make(__('Gross'),  'gross')
                ->broadcastTo('discount')
                ->hideFromIndex(),
BroadcasterField::make(__('Disc Percent'),  'disc_percent')
                ->broadcastTo('discount')
                ->hideFromIndex(),
BroadcasterField::make(__('Disc Amount'),  'disc_amount')
                ->broadcastTo('discount')
                ->hideFromIndex(),
ListenerField::make(__('Discounted Gross'),  'discounted_gross')
                ->listensTo('discount')
                ->hideFromIndex()
                ->calculateWith(function (Collection $values) {
                    $gross = $values->get('gross');
                    $disc_percent = $values->get('disc_percent') / 100;
                    $disc_amount = $values->get('disc_amount');
                    $disc_sum = ($gross * $disc_percent) + $disc_amount;
                    $disc_gross = $gross - $disc_sum;
                    return $disc_gross;
}),

Multiple Listeners on the same event

Is it not possible to have multiple listeners on the same event?

Each of these listeners work on their own but if I add them all, only the last is updated

BroadcasterField::make(__('Gross'),  'gross')
                ->broadcastTo('discount')
                ->hideFromIndex(),
BroadcasterField::make(__('Disc Percent'),  'disc_percent')
                ->broadcastTo('discount')
                ->hideFromIndex(),
BroadcasterField::make(__('Disc Amount'),  'disc_amount')
                ->broadcastTo('discount')
                ->hideFromIndex(),


ListenerField::make(__('Disc Sum'),  'disc_sum')
                ->listensTo('discount')
                ->hideFromIndex()
                ->calculateWith(function (Collection $values) {
                    // some calculations;
                    return $disc_sum;
                }),
ListenerField::make(__('Disc Sum Percent'),  'disc_sum_percent')
                ->listensTo('discount')
                ->hideFromIndex()
                ->calculateWith(function (Collection $values) {
                   // some calculations;
                    return $disc_sum_percent;
                }),
ListenerField::make(__('Discounted Gross'),  'discounted_gross')
                ->listensTo('discount')
                ->hideFromIndex()
                ->calculateWith(function (Collection $values) {
                    // some calculations;
                    return $disc_gross;
}),

Possible to use select as broadcast field?

Hi,

This package looks really useful, so thanks for the work put into it.

I have a situation where my "broadcast" field would be a form select rather than a text or number input. Is it correct that it's not currently possible to use a select field as the broadcast field?

If not, maybe this is something I can help contribute - not sure how feasible it is so I figured I'd ask first.

Thanks!

withMeta extraAttributes doesn't work

I have the following field:
ListenerField::make('Jóváírt kredit', 'new_credits') ->sortable() ->help('<b>Automatikusan kerül kiszámításra a fizetendő összegből!</b>') ->withMeta([ 'extraAttributes' => [ 'readonly' => 'readonly' ], ]) ->calculateWith(function (Collection $values) { $order_total = $values->get('order_total'); return (($order_total/100)*5); })->rules('required')

but unfortunately the withMeta not working, the readonly attribute not setting on input. How can I do this?

other fieldtypes

Hi,

It would be nice if other Fieldtypes had also a broadcast method..
something like.

Place::make()->broadcaster()

and so on...
do you thin this is possible?

thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.