Skip to content

Commit

Permalink
ADD: repeater inner fields support
Browse files Browse the repository at this point in the history
  • Loading branch information
ihslimn committed Oct 21, 2024
1 parent 3876c00 commit ccf6b3a
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 42 deletions.
81 changes: 59 additions & 22 deletions assets/js/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
'jet.fb.input.makeReactive',
'jfb-update-field/on-observe',
function( input ) {

return;


if ( ! input.path || input.path.length < 2 ) {
return;
Expand All @@ -31,11 +30,12 @@
const observable = input.getRoot(),
formId = observable.form.getFormId(),
node = input.nodes[0],
updatedNode = node.closest( '[data-update-field-name]' );
updatedNode = node.closest( '[data-update-field-name]' ),
path = input.path;

setFieldWatcher( formId, input );

updateFormField( updatedNode, input.root );
triggerUpdate( input );

}
);
Expand Down Expand Up @@ -104,12 +104,12 @@

const input = observable.getInput( key );

setFieldWatcher( formId, input );

if ( ! input || ! input.value || input.inputType === "repeater" ) {
continue;
}

setFieldWatcher( formId, input );

triggerUpdate( input );

}
Expand Down Expand Up @@ -150,14 +150,23 @@

function getFormValues( observable ) {

if ( observable?.parent?.root ) {
observable = observable.parent.root;
}

const formFields = observable.getInputs(),
formId = observable.form ? observable.form.getFormId() : observable.parent.root.form.getFormId();

let formValues = {};

formFields.forEach( function( input ) {

if ( undefined === input?.value?.current || input.inputType === "repeater" ) {
if ( undefined === input?.value?.current ) {
return;
}

if ( input.inputType === "repeater" ) {
formValues[ input.name ] = getRepeaterValue( input );
return;
}

Expand All @@ -173,6 +182,24 @@

}

function getRepeaterValue( input ) {

if ( input?.inputType !== "repeater" ) {
return [];
}

let result = [];

input.value.current.forEach( function( observable, i ) {
observable.getInputs().forEach( function( input ) {
result[ i ] ??= {};
result[ i ][ input.name ] = input.value.current;
} );
} );

return result;
}

function styleCalculated( updatedCalculated, type = 'add' ) {

if ( ! updatedCalculated ) {
Expand Down Expand Up @@ -274,8 +301,8 @@

function updateFormField( updatedNode, observable, button = null ) {

const updated = updatedNode.dataset.updateFieldName,
updatedInput = observable.getInput( updated );
let updated = updatedNode.dataset.updateFieldName,
updatedInput = observable.getInput( updated );

if ( ! updatedInput ) {
return;
Expand All @@ -286,14 +313,16 @@
updatedCalculated = observable.rootNode.querySelectorAll( `[data-formula*=${updated}]` ),
cacheTime = updatedNode.dataset.updateCacheTimeout || 60;

if ( aborters[ updated + formId ] ) {
aborters[ updated + formId ].abort();
delete aborters[ updated + formId ];
let aUpdated = ! observable?.parent?.name ? updated : updatedInput.rawName;

if ( aborters[ aUpdated + formId ] ) {
aborters[ aUpdated + formId ].abort();
delete aborters[ aUpdated + formId ];
}

let aborter = new AbortController();

aborters[ updated + formId ] = aborter;
aborters[ aUpdated + formId ] = aborter;

updatedNode.classList.add( 'jfb-updated-field' );

Expand All @@ -303,9 +332,11 @@

maybeClearInput( updatedInput );

updatedInput.reporting.validityState.current = false;
if ( updatedInput?.reporting?.validityState ) {
updatedInput.reporting.validityState.current = false;
}

const hash = getHash( updated, formId, formFields );
const hash = getHash( aUpdated, formId, formFields );

if ( cache.has( hash ) ) {
const cached = cache.get( hash );
Expand All @@ -328,18 +359,20 @@
}
}

let rUpdated = ! observable?.parent?.name ? updated : updatedInput.rawName;

wp.apiFetch( {
method: 'post',
path: '/jet-form-builder-update-field-addon/v1/get-field',
data: {
"form_id" : formId,
"field_name" : updated,
"form_fields" : formFields,
"form_id": formId,
"field_name": rUpdated,
"form_fields": formFields,
},
signal: aborter.signal,
} ).then( ( response ) => {

if ( aborter !== aborters[ updated + formId ] ) {
if ( aborter !== aborters[ aUpdated + formId ] ) {
return;
}

Expand All @@ -358,10 +391,10 @@

} ).catch( function ( e ) {

if ( aborter === aborters[ updated + formId ] ) {
if ( aborter === aborters[ aUpdated + formId ] ) {
console.error( e );

delete aborters[ updated + formId ];
delete aborters[ aUpdated + formId ];

updatedNode.classList.remove( 'jfb-updated-field' );

Expand All @@ -376,7 +409,7 @@

function setFieldWatcher( formId, watchedField ) {

const observable = watchedField?.root || JetFormBuilder[ formId ];
let observable = watchedField?.root || JetFormBuilder[ formId ];

if ( ! observable ) {
return;
Expand All @@ -392,6 +425,10 @@
watched = watchedField.name;
} else if ( watched.includes('[') ) {
watched = watched.replaceAll( /\[\d+\]\[/g, '[' );

if ( observable?.parent?.name ) {
watched = watched.replaceAll( observable.parent.name + '[', '[' );
}
}

if ( ! watchedField?.value ) {
Expand Down
4 changes: 2 additions & 2 deletions jet-form-builder-update-field.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: JetFormBuilder - Update Fields
* Plugin URI:
* Description:
* Version: 1.1.3
* Version: 1.2.0
* Author:
* Author URI:
* Text Domain:
Expand Down Expand Up @@ -31,7 +31,7 @@ class Plugin {

public $storage = null;

private $version = '1.1.3';
private $version = '1.2.0';

public function __construct() {
add_action( 'plugins_loaded', array( $this, 'jec_init' ) );
Expand Down
60 changes: 49 additions & 11 deletions rest-api/endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,61 @@ public function get_support_type( $attrs ) {

public function callback( $request ) {

$params = json_decode( $request->get_body() );
$params = json_decode( $request->get_body(), true );

$form_id = $params->form_id;
$field_name = $params->field_name;
$form_fields = ( array ) $params->form_fields;
$form_id = $params['form_id'];
$field_name = $params['field_name'];
$form_fields = $params['form_fields'];

$storage = Plugin::instance()->storage;

foreach ( $form_fields as $name => $value ) {
$_REQUEST['jfb_update_related_' . $name] = $value;
Plugin::instance()->storage->save_field_value( $name, $value );
$storage->save_field_value( $name, $value );
}

//setup form context
$blocks = Block_Helper::get_blocks_by_post( $form_id );
jet_fb_handler()->set_form_id( $form_id );
jet_fb_context()->set_request( $form_fields );
jet_fb_context()->apply( $blocks );

$is_repeater = preg_match( '/(?<field_name>.+)\[(?<index>\d+)\]\[(?<sub_name>.+)\]/', $field_name, $matches );

if ( $is_repeater ) {
$field_name = $matches['field_name'];
$sub_name = $matches['sub_name'];
$index = $matches['index'];
}

$block = \Jet_Form_Builder\Blocks\Block_Helper::find_block_by_name( $field_name, $blocks );

if ( $is_repeater && $block['blockName'] !== 'jet-forms/repeater-field' ) {
return array(
'type' => 'error',
'value' => 'This field does not have Field Updater enabled or its settings are invalid.',
);
}

if ( $is_repeater && ! empty( $block['innerBlocks'] ) ) {
foreach ( $block['innerBlocks'] as $inner_block ) {
if ( ! empty( $inner_block['attrs'] ) && $inner_block['attrs']['name'] === $sub_name ) {
$block = $inner_block;
}
}

$storage->set_context( $field_name );
$storage->set_index( $index );
}

if ( ! empty( $block['attrs']['jfb_update_fields_value_enabled'] ) && $this->get_support_type( $block ) === 'value' ) {

$value = $this->get_value( $block['attrs'], $field_name, $form_id, $form_fields );
$value = $this->get_value(
$block['attrs'],
$is_repeater ? $params->field_name : $field_name,
$form_id,
$form_fields
);

if ( empty( $value ) && isset( $block['attrs']['default'] ) ) {
$value = $block['attrs']['default'];
Expand All @@ -95,13 +132,14 @@ public function callback( $request ) {
);
}

// set up block structure
jet_fb_context()->set_parsers(
$blocks
);
if ( $is_repeater ) {
$field_path = array( $field_name, $index, $sub_name );
} else {
$field_path = array( $field_name );
}

try {
$parser = jet_fb_context()->resolve_parser( $params->field_name );
$parser = jet_fb_context()->resolve_parser( $field_path );
} catch ( Silence_Exception $exception ) {
// field not found
return array( 'error' => true );
Expand Down
41 changes: 34 additions & 7 deletions storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,41 @@

class Storage {

private $form_fields = array();
private $form_fields = array();

public function save_field_value( $field_name, $value ) {
$this->form_fields[ $field_name ] = $value;
}
private $context = '';
private $index = -1;

public function get_field_value( $field_name ) {
return $this->form_fields[ $field_name ] ?? '';
}
public function set_context( $context ) {
$this->context = $context;
}

public function set_index( $index ) {
$this->index = $index;
}

public function save_field_value( $field_name, $value ) {
$this->form_fields[ $field_name ] = $value;
}

public function get_values() {
return $this->form_fields;
}

public function get_field_value( $field_name ) {
if ( preg_match( '/(?<field_name>.+)\[(?<index>\d+)\]\[(?<sub_name>.+)\]/', $field_name, $matches ) ) {
$field_name = $matches['field_name'];
$sub_name = $matches['sub_name'];
$index = $matches['index'];

return $this->form_fields[ $field_name ][ $index ][ $sub_name ] ?? '';
}

if ( $this->context && $this->index >= 0 && preg_match( '/\[(?<sub_name>.+)\]/', $field_name, $matches ) ) {
return $this->form_fields[ $this->context ][ $this->index ][ $matches['sub_name'] ] ?? '';
}

return $this->form_fields[ $field_name ] ?? '';
}

}

0 comments on commit ccf6b3a

Please sign in to comment.