The Community forums are being phased out in favor of a new Slack group.
Add your email address below to get an invitation to join the community slack group

Slack Signup
Newsletter Optin
Help Desk

Calculations Within Repeater Rows

Labels

This Discussion is public

Notifications

I hope someone can help,

I've copped fine learning php while I learn formidable forms simultaneously. I've been able to implement most of the php examples however when working with repeater section i'm struggling. I understand this works as a loop but I can't get the structure right/understand it.

I'm trying to calculate time within each repeater row. Can someone help with what i'm doing wrong here? From my novice eyes this looks like it should work.

add_filter('frm_validate_field_entry', 'modify_repeating_section_field', 10, 3);
function modify_repeating_section_field($errors, $posted_field, $posted_value){
if ( $posted_field->id == 24691 ) { //id of the repeater section
foreach ( $_POST['item_meta'][ $posted_field->id ] as $key => $val ) {
$start = strtotime($_POST['item_meta'][ 1 ]); //Start time field field on row 1
$end = strtotime($_POST['item_meta'][ 2 ]); //End time field on row 1
$totaltime = ($end - $start);
$hours = intval($totaltime / 3600);
$seconds_remain = ($totaltime - ($hours * 3600));
$minutes = intval($seconds_remain / 60);
$leading_zero_for_minutes = $minutes < 10 ? '0' : '';
$totaltime = $hours . ':' . $leading_zero_for_minutes . $minutes;
$value = $_POST['item_meta'][ 3 ] = $totaltime; //Total time field on row 1
}
}
return $errors;
}

Any ideas?

Repeater fields in the global $_POST variable are multidimensional arrays that are 4-levels deep. You are not accessing their values correctly.

The dimensions are item_meta, field_id, row_id, and field_id within the row.

To provide a better understanding, I've attached a screen shot of the content of a repeater field multidimensional array as displayed in the Kint debugger for a sample form in my dev environment. Let me walk you through it.

In this example, I am using a repeater field with a single text field. I've added three rows of content.

87 is the field id for the repeater field on the primary form. This would be accessed as $_POST['item_meta']['87'].

form => '6' is the id of the repeater field child form. Every repeater field is a child form of the primary form. This would be accessed as $_POST['item_meta']['87']['form'].

the row_ids array tells us how many repeater rows are being saved. You can use the length of this array to set up a loop if you so choose. Your loop is using $_POST['item_meta'][ $posted_field->id ]. While this will provide you with the correct field_id on the parent form ($_POST['item_meta']['87']) it will not go deep enough to retrieve the repeater row content.

The next 3 arrays are the contents of each repeater field row. They would be accessed as $_POST['item_meta']['87']['0']['89']
$_POST['item_meta']['87']['1']['89']
$_POST['item_meta']['87']['2']['89']

The values of each in order are:
$_POST['item_meta']['87']['0']['89'] = "Test string 1"
$_POST['item_meta']['87']['1']['89'] = "Test string 2"
$_POST['item_meta']['87']['2']['89'] = "repeating field 3"

Hope this helps...


Attachment:

Thanks Victor

That's a great explanation, i'll attempt to re write it or maybe start with a simpler calculation.

Thanks Again I really appreciate this. I'll update this thread with my outcome it might be helpful for others.

 

Victor quick question:

In $_POST['item_meta']['87']['0']['89'] = "Test string 1"

If ['0'] is the row number can I set this to [' '] in order to access all rows?

example:

change all fields in all repeater rows to "Hello":

In $_POST['item_meta']['87'][' ']['89'] = "Hello"

No, you cannot have an empty array index. It's an out of bounds error.

You have to loop through the row_ids array and use the row id as a variable. Since it's a simple array and not key => value, here's an example of the code you could use.

foreach ( $_POST['item_meta']['row_ids'] as $val ) {
$_POST['item_meta']['87'][$val]['89']
}

Victor,

You're always so helpful. I managed to get this working! Understanding this structure will help me manipulate the repeater fields.

Below is the code I've used to calculate time in each repeater row with 3 fields:

Single Time drop down (Start Time)  - 1510
Single Time drop down (End Time) - 1511
Text Field (Total Time) - 1509

FYI the repeater section id - 1507

<?php

add_filter('frm_validate_field_entry', 'modify_repeating_section_field', 10, 3);
function modify_repeating_section_field($errors, $posted_field, $posted_value){
if ( $posted_field->id == 1507 ) {                                                           //1507 is the repeater id
foreach ( $_POST['item_meta']['1507']['row_ids'] as $val ) {          //Extract row ids to loop through

$start = strtotime($_POST['item_meta']['1507'][$val]['1510']);     //Start time field field
$end = strtotime($_POST['item_meta']['1507'][$val]['1511']);       //End time field
$totaltime = ($end - $start);
$hours = intval($totaltime / 3600);
$seconds_remain = ($totaltime - ($hours * 3600));
$minutes = intval($seconds_remain / 60);
$leading_zero_for_minutes = $minutes < 10 ? '0' : '';
$totaltime = $hours . ':' . $leading_zero_for_minutes . $minutes;
$value = $_POST['item_meta']['1507'][$val]['1509'] = $totaltime;      //Total time field
}
}
return $errors;
}

?>

Discussion closed.