Skip to content

Commit

Permalink
Merge pull request #14 from ItinerisLtd/Fix-Bugs
Browse files Browse the repository at this point in the history
Fix and Update!
  • Loading branch information
Barny-Thorpe committed Apr 2, 2024
2 parents be64c07 + bd90a07 commit b8f7dfe
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 47 deletions.
97 changes: 53 additions & 44 deletions public/js/gf-giftaid-field-frontend.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,66 @@
function gfGiftAidOnInputChange(elem) {
if (!(elem instanceof HTMLElement)) {
return;
}
document.addEventListener('DOMContentLoaded', initGiftAid);

if (! elem.classList.contains('ginput_total') && ! elem.classList.contains('ginput_amount')) {
/**
* Updates the gift aid display, based on a chosen field changing.
*/
function initGiftAid() {
const gravityForm = document.querySelector('.gform_wrapper');
if (!(gravityForm instanceof HTMLElement)) {
return;
}

const parentForm = elem.closest('form');
if (!(parentForm instanceof HTMLFormElement)) {
const totalSelector = totalFieldSelector(gravityForm, '.ginput_amount');
if (!totalSelector) {
return;
}
window.gform.addAction('gform_input_change', function (elem) {
const donationValue = parseFloat(elem.value);
const giftAidValue = donationValue * 1.25;
const donationRounded = donationValue.toFixed(2);
const giftAidRounded = giftAidValue.toFixed(2);
if (!donationRounded || !giftAidRounded) {
return;
}
updateGiftAidDisplay(gravityForm, donationRounded, giftAidRounded);
}, 10);
}

const totalEl = parentForm.querySelector('.ginput_total');
if (totalEl instanceof HTMLElement) {
elem = totalEl;
/**
* Gets the selector of the total field, selected in the gift aid field settings.
* Will be in the format 'field_<form_id>_<field_id>' and will be an id so the selector will be prefixed by #.
* @param {HTMLElement} gravityForm The form element.
* @param {string} fallback fallback selector if the field is not found.
* @returns {string} The class of the total field.
*/
function totalFieldSelector(gravityForm, fallback) {
const giftAidComponent = gravityForm.querySelector('.gift-box-wrapper');
if (!(giftAidComponent instanceof HTMLElement)) {
return fallback;
}
const selectedPriceFieldId = giftAidComponent.dataset.selectedPriceFieldId;
if (!selectedPriceFieldId) {
return fallback;
}
return `#${selectedPriceFieldId}`;
}

const spanTotal = parentForm.querySelectorAll('.gform_donation_total');
if (!(spanTotal instanceof NodeList) || 0 === spanTotal.length) {
/**
* Updates the gift aid display.
* @param {HTMLElement} gravityForm The form element.
* @param {object} The donation and gift aid total.
* @returns {void}
*/
function updateGiftAidDisplay(gravityform, donation, giftAidAmount) {
if (!donation || !giftAidAmount || !(gravityform instanceof HTMLElement)) {
return;
}

const spanTotalGift = parentForm.querySelectorAll(
'.gform_donation_gifttotal',
);
if (!(spanTotalGift instanceof NodeList) || 0 === spanTotalGift.length) {
const spanTotal = gravityform.querySelector('.gform_donation_total');
if (!(spanTotal instanceof HTMLSpanElement)) {
return;
}

const extractFloat = (str) => {
// Regular expression to match floating-point numbers
const regex = /[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/g;

// Use match() to find all matching numbers in the string
const matches = str.match(regex);

// If there are matches, convert them to floats and return them; otherwise, return the original str.
return matches ? matches.map(Number) : str;
};

const val = extractFloat(elem.value);
const total = parseFloat(val).toFixed(2);
const totalGift = parseFloat(val * 1.25).toFixed(2);

Array.from(spanTotal).forEach((item) => {
item.innerHTML = total;
});

Array.from(spanTotalGift).forEach((item) => {
item.innerHTML = totalGift;
});
const spanTotalGift = gravityform.querySelector('.gform_donation_gifttotal');
if (!(spanTotalGift instanceof HTMLSpanElement)) {
return;
}
spanTotal.innerHTML = donation;
spanTotalGift.innerHTML = giftAidAmount;
}
document.addEventListener('DOMContentLoaded', () => {
window.gform.addAction('gform_input_change', gfGiftAidOnInputChange, 10);
});
70 changes: 69 additions & 1 deletion src/GfGiftAidField.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Itineris\GfGiftaidField;

use GF_Field;
use GFAddOn;
use GFAPI;
use GFForms;

class GfGiftAidField
Expand All @@ -13,11 +15,77 @@ class GfGiftAidField

public static function run(): void
{
if (! method_exists('GFForms', 'include_addon_framework')) {
if (!method_exists('GFForms', 'include_addon_framework')) {
return;
}

GFForms::include_addon_framework();
GFAddOn::register(AddOn::class);

add_action('gform_field_standard_settings', [static::class, 'addSelectedPriceFieldSetting'], 10, 2);
}

/**
* Custom field to enable the user to choose where they would like to pull the total value from.
*/
public static function addSelectedPriceFieldSetting(int $position, int $form_id): void
{
if (25 !== $position || empty($form_id)) {
return;
}
$field_options = static::getFormFields($form_id);
if (empty($field_options)) {
return;
}
?>
<li class="selected_price_field_setting field_setting">
<label for="selected_price_field_dropdown" class="section_label">
<?php esc_html_e('Price Field', 'itineris-gf-giftaid-field'); ?>
</label>

<select
name="donation_total"
id="selected_price_field_dropdown"
onchange="SetFieldProperty('selectedPriceField', this.value);"
>
<?php foreach ($field_options as $field_id => $field_label) : ?>
<?php
if (empty($field_id) || empty($field_label)) {
continue;
}
?>

<option value="<?php echo esc_attr($field_id); ?>"><?php echo esc_html($field_label); ?></option>
<?php endforeach; ?>
</select>
</li>
<?php
}

/**
* Get all the fields in a gravity form in the format:
* ['field class' => 'field_label', ...]
*/
public static function getFormFields(int $form_id): array
{
$exists = GFAPI::form_id_exists($form_id);
if (empty($exists)) {
return [];
}

$form = GFAPI::get_form($form_id);
$fields = $form['fields'] ?? [];
if (empty($fields) || !is_array($fields)) {
return [];
}

return array_reduce($fields, function (array $carry, GF_Field $field) use ($form_id): array {
if (empty($field) || empty($field->id) || empty($field->label)) {
return $carry;
}
$class = "field_{$form_id}_{$field->id}";
$carry[$class] = $field->label;
return $carry;
}, []);
}
}
15 changes: 13 additions & 2 deletions src/GiftAidField.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class GiftAidField extends GF_Field
{
public string $type = 'giftaid';
public string $type = 'gift_aid';

public function get_form_editor_field_title(): string
{
Expand Down Expand Up @@ -39,6 +39,7 @@ public function get_form_editor_button(): array
public function get_form_editor_field_settings(): array
{
return [
'selected_price_field_setting',
'label_setting',
'description_setting',
'rules_setting',
Expand All @@ -65,17 +66,26 @@ public function get_field_input($form, $value = '', $entry = null): string
{
$id = (int) $this->id;
$giftaidImage = plugins_url('public/img/giftaid.svg', __DIR__);
$selectedPriceField = $this->selectedPriceField ?? '';

ob_start();
?>
<div class="gift-box-wrapper bg-gray-50 rounded-br-4 p-7.5">
<div
class="gift-box-wrapper bg-gray-50 rounded-br-4 p-7.5"
<?php if (!empty($selectedPriceField)) : ?>
data-selected-price-field-id="<?php echo esc_attr($selectedPriceField); ?>"
<?php endif; ?>
>

<div class="giftaid-logo mb-2">
<img src="<?php echo esc_url($giftaidImage); ?>" alt="GiftAid logo">
</div>

<div class="description text-primary font-medium text-xl mb-2">
<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php echo wpautop(wp_kses_post($this->get_calculated_gift())); ?>
</div>

<div class="gift-box-form-wrapper my-6 pb-6 border-b border-b-gray-200">
<div class="ginput_container ginput_container_checkbox mb-6">
<div class="gfield_checkbox" id="input_<?php echo esc_attr($id); ?>">
Expand All @@ -94,6 +104,7 @@ class="gfield-choice-input"
</div>
</div>
</div>

<div class="details-description"><?php echo wp_kses_post($this->description); ?></div>
</div>
<?php
Expand Down

0 comments on commit b8f7dfe

Please sign in to comment.