Skip to content

Commit

Permalink
[Release V2.3]
Browse files Browse the repository at this point in the history
-- Fixed issue where you can't edit a listener field
-- Added Date Broadcaster field
-- Added Date Listener field
-- Added 'calculate' buttons to all visible Listener Fields
-- Added ability to turn of calculation on update forms.
-- Updated README.md
  • Loading branch information
gldrenthe89 committed Apr 1, 2021
1 parent a4435eb commit d3083b0
Show file tree
Hide file tree
Showing 19 changed files with 638 additions and 145 deletions.
129 changes: 27 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,111 +1,35 @@
This packages was originaly created by [codebykyle](https://github.com/codebykyle/calculated-field) But after an extensive refactor and updating a lot of VueJS code to latest Laravel Nova code i made this in to a new package.
This packages is created after the package from [codebykyle](https://github.com/codebykyle/calculated-field) But after an extensive refactor and updating a lot of VueJS code to the latest Laravel Nova code I made this in to a new package.

## New features
-- BelongsTo Broadcaster field
-- MorphTo Broadcaster field
-- Currency Listener Field
-- Hidden Listener Field
-- Code has been completely updated to latest Nova (2021-03-18)
# New features

Below the old Documentation from [codebykyle](https://github.com/codebykyle)
[Release V2.3]<br>
-- Fixed issue where you can't edit a listener field <br>
-- Added Date Broadcaster field <br>
-- Added Date Listener field <br>
-- Added 'calculate' buttons to all visible Listener Fields <br>
-- Added ability to turn of calculation on update forms. <br>

## Installation
[changes up to V2.2]<br>
-- BelongsTo Broadcaster field <br>
-- MorphTo Broadcaster field <br>
-- Currency Listener Field <br>
-- Hidden Listener Field <br>
-- Code has been completely updated to latest Nova (2021-03-18) <br>

Install the package via composer:
Below pieces of the old Documentation from [codebykyle](https://github.com/codebykyle)
I'm not really good at writing documentation. So please feel free to creat a PR for it.

`composer require gldrenthe89/nove-calculated-field`
# Installation

Install the package via composer:

`composer require gldrenthe89/nove-calculated-field`


# Original how-to from [codebykyle](https://github.com/codebykyle)
## Example

### Example
For example:
#### As a number
![Calculated Number Field](https://cbk-website.s3.amazonaws.com/calculated-field/number_calc_field.gif "Calculated Number Field")

#### As a string:
![Calculated String Field](https://cbk-website.s3.amazonaws.com/calculated-field/string_calc_field.gif "Calculated String Field")

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

### Usage
```php
<?php

use Gldrenthe89\NovaCalculatedField\BroadcasterField;
use Gldrenthe89\NovaCalculatedField\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

<?php
use Gldrenthe89\NovaCalculatedField\BroadcasterField;
use Gldrenthe89\NovaCalculatedField\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

<?php
use Gldrenthe89\NovaCalculatedField\BroadcasterField;
use Gldrenthe89\NovaCalculatedField\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

<?php
Expand All @@ -117,13 +41,13 @@ class MyResource extends Resource
public function fields(Request $request) {
return [
BroadcasterField::make('Sub Total', 'sub_total')
->broadcastTo('total'),
->broadcastTo('total'), // can either be a String or an Array

BroadcasterField::make('Tax', 'tax')
->broadcastTo('total'),
->broadcastTo('total'), // can either be a String or an Array

ListenerField::make('Total Field', 'total_field')
->listensTo('total')
->listensTo('total') // can either be a String or an Array
->calculateWith(function (Collection $values) {
$subtotal = $values->get('sub_total');
$tax = $values->get('tax');
Expand All @@ -132,13 +56,14 @@ class MyResource extends Resource


BroadcasterField::make('Senior Discount', 'senior_discount')
->broadcastTo('discount'),
->broadcastTo('discount'), // can either be a String or an Array

BroadcasterField::make('Coupon Discount', 'coupon_amount')
->broadcastTo('discount'),
->broadcastTo('discount'), // can either be a String or an Array

ListenerField::make('Total Discount', 'total_discount')
->listensTo('discount')
->listensTo('discount') // can either be a String or an Array
->disableCalculationOnUpdate() // Only when to disable on Update forms
->calculateWith(function (Collection $values) {
$seniorDiscount = $values->get('senior_discount');
$couponAmount = $values->get('coupon_amount');
Expand Down
2 changes: 1 addition & 1 deletion dist/js/field.js

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions resources/js/components/Detail/BroadcasterDateField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<panel-item :field="field">
<template slot="value">
<p v-if="field.value" class="text-90">{{ formattedDate }}</p>
<p v-else>&mdash;</p>
</template>
</panel-item>
</template>

<script>
export default {
props: ['resource', 'resourceName', 'resourceId', 'field'],
computed: {
formattedDate() {
if (this.field.format) {
return moment(this.field.value).format(this.field.format)
}
return this.field.value
},
},
}
</script>
24 changes: 24 additions & 0 deletions resources/js/components/Detail/ListenerDateField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<panel-item :field="field">
<template slot="value">
<p v-if="field.value" class="text-90">{{ formattedDate }}</p>
<p v-else>&mdash;</p>
</template>
</panel-item>
</template>

<script>
export default {
props: ['resource', 'resourceName', 'resourceId', 'field'],
computed: {
formattedDate() {
if (this.field.format) {
return moment(this.field.value).format(this.field.format)
}
return this.field.value
},
},
}
</script>
105 changes: 105 additions & 0 deletions resources/js/components/Form/BroadcasterDateField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<default-field :field="field" :errors="errors" :show-help-text="showHelpText">
<template slot="field">
<div class="flex items-center">
<date-time-picker
class="w-full form-control form-input form-input-bordered"
ref="dateTimePicker"
:dusk="field.attribute"
:name="field.name"
:value="value"
:dateFormat="pickerFormat"
:alt-format="pickerDisplayFormat"
:placeholder="placeholder"
:enable-time="false"
:enable-seconds="false"
:first-day-of-week="firstDayOfWeek"
:class="errorClasses"
@change="setFieldAndMessage"
:disabled="isReadonly"
/>

<a
v-if="field.nullable"
@click.prevent="$refs.dateTimePicker.clear()"
href="#"
:title="__('Clear value')"
tabindex="-1"
class="p-1 px-2 cursor-pointer leading-none focus:outline-none"
:class="{
'text-50': !value.length,
'text-black hover:text-danger': value.length,
}"
>
<icon type="x-circle" width="22" height="22" viewBox="0 0 22 22" />
</a>
</div>
</template>
</default-field>
</template>

<script>
import {
FormField,
HandlesValidationErrors,
InteractsWithDates,
} from 'laravel-nova'
export default {
mixins: [HandlesValidationErrors, FormField, InteractsWithDates],
props: ['resourceName', 'resourceId', 'field'],
methods: {
setFieldAndMessage(value) {
let parsedValue = value;
let attribute = this.field.attribute
if (Array.isArray(this.field.broadcastTo)) {
this.field.broadcastTo.forEach(function (broadcastChannel) {
Nova.$emit(broadcastChannel, {
'field_name': attribute,
'value': parsedValue
})
});
} else {
Nova.$emit(this.field.broadcastTo, {
'field_name': attribute,
'value': parsedValue
})
}
this.value = parsedValue;
},
/**
* Update the field's internal value when it's value changes
*/
handleChange(value) {
this.value = value;
},
},
computed: {
firstDayOfWeek() {
return this.field.firstDayOfWeek || 0
},
placeholder() {
return this.field.placeholder || moment().format(this.format)
},
format() {
return this.field.format || 'YYYY-MM-DD'
},
pickerFormat() {
return this.field.pickerFormat || 'Y-m-d'
},
pickerDisplayFormat() {
return this.field.pickerDisplayFormat || 'Y-m-d'
},
},
}
</script>
19 changes: 10 additions & 9 deletions resources/js/components/Form/ListenerCurrencyField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
@input="handleChange"
:value="value"
/>
<input type="button" class="btn btn-default btn-primary ml-3 cursor-pointer" value="Calculate" :id="field.attribute.concat('CalculateButton')" v-on:click="calculateValue(true);">

</div>
</template>
</default-field>
Expand Down Expand Up @@ -62,14 +64,20 @@ export default {
this.calculateValue()
},
calculateValue: _.debounce(function () {
calculateValue: _.debounce(function (force = false) {
this.calculating = true;
Nova.request().post(
`/gldrenthe89/nova-calculated-field/calculate/${this.resourceName}/${this.field.attribute}`,
this.field_values
).then((response) => {
this.value = response.data.value;
if (
!(response.data.disabled && this.field.isUpdating)
||
force
) {
this.value = response.data.value
}
this.calculating = false;
}).catch(() => {
this.calculating = false;
Expand All @@ -89,13 +97,6 @@ export default {
fill(formData) {
formData.append(this.field.attribute, this.value || '')
},
/**
* Update the field's internal value.
*/
handleChange(value) {
this.value = value
},
},
computed: {
Expand Down
Loading

0 comments on commit d3083b0

Please sign in to comment.