So I'm attempting to create a custom FieldType for Freeform for a custom one-off application. Basically I have multiple hidden fields to populate data associated with a regular user input field.
I've been struggling with this for a while and don't know of a better way, so if someone knows I'd be happy to hear it!!
Basically here's my setup:
Within the freeform:form
I'm listing channel entries to populate the inputs
<input id="product_{count}" type="hidden" name="product[]" value="{sku}/" />
<input id="product_{count}" type="hidden" name="product[]" value="{title}/" />
<input id="product_{count}" type="hidden" name="product[]" value="{price}/" />
<input id="product_{count}" type="number" name="product[]" value="" />
<input id="product_{count}" type="hidden" name="product[]" value="," />
As stated, I don't know that this is the best approach, but it's the best I could figure out for now.
When a member views the page all they see is the input for the quantity, which is the line <input id="product_{count}" type="number" name="product[]" value="" />
When the form is submitted the product
array comes in looking like:
[0] => 1011/
[1] => Product A/
[2] => 9.95/
[3] => 50
[4] => ,
[5] => 1011/
[6] => Product B/
[7] => 24.95/
[8] =>
[9] => ,
[10] => 1011/
[11] => Product C/
[12] => 11.95/
[13] => 12
[14] => ,
As you can see, element 8 is empty, this means that products was not ordered. So I need a way to skip that one.
So I've copied the text
field type as a base to start off of from the Freeform pre-installed FieldTypes.
In the pre_process()
method here is what I have created:
public function pre_process($data)
{
if(is_array($data)){
$data_string = implode($data);
// print_r($data_string);
// First get all the products into single lines we can work with
$process_product = explode(",", $data_string);
// String to hold our return value
$return_str = "";
// Loop through and process the extracted strings
foreach($process_product as $value) {
// Testing
//echo($value . "<br/>");
try{
// Split the string by the "/" delimiter
$explode = explode("/", $value);
// Count should always be 4, even if no QTY entered, it will contain " "
if(count($explode) == 4){
list($sku, $descr, $price, $qty) = explode("/", $value);
// Checking if there really is a QTY
if (trim($qty) !== "") {
// echo(" SKU: " . $sku . " Description: " . $descr . " Price: $" . $price . " Qty: " . $qty . "<br/>");
$ordered_product = (" SKU: " . $sku . "<br>" . " Description: " . $descr . "<br>" . " Price: $" . $price . "<br>" . " Qty: " . $qty . "<br>");
//echo($ordered_product);
$return_str .= $ordered_product . "<br>";
}
}
}
catch (Exception $e){
log_message('error', $e->getMessage());
return;
} // end try/catch
}// end for
// Final check to see if return_str is what we expect
//echo($return_str);
return $return_str;
}
return $data;
}
Basically I'm imploding the returned array so I can then delimit the string as needed. The string will now be in the format:
"1011/Product A/9.95/50,1011/Product B/24.95/,1011/Product C/11.95/12,"
This is working for both the front-end within the {exp:freeform:entries}
tag pair, and also within the control panel. I get what I would expect. Basically it looks like this in the CP and on the front-end of the website:
SKU: 1011
Description: Product A
Price: $ 9.95
Qty: 50
But notifications are still receiving the original array in its entirety? This is my problem. I don't understand where the notifications are pulling the data from, and which function to use to process that data so I only get the data I need.