Hey there -
Thanks for helping me with this!
The wiki article I was referring to is this one:
http://wiki.modxcms.com/index.php/Populate_eform_with_dynamic_data
I’m not doing it exactly like this, since I’m populating from SESSION vars and I don’t need access to the templates array. So my current function code is:
function preFormParse(&$fields){
/* Runs on eFormOnBeforeFormParse event
* Called just before the form is parsed; Parsing is done only if there is $_POST data valid to the form
* Prepopulating code based on this example: http://wiki.modxcms.com/index.php/Populate_eform_with_dynamic_data */
global $modx;
$evt=&$modx->event; // reference to the snippet call event (not eFormOnBeforeFormParse event)
$validFormId=($evt->params['formid']==$_POST['formid']); // replicate $isPostBack variable conditions
$isPostBack=($validFormId && count($_POST)>0); // (bool) true if the form is being updated via POST
if (!$isPostBack) { // Check for NOT postback, since we only want to prepopulate an empty form
if(!empty($_SESSION['order']['Name'])) $fields['Name']=$_SESSION['order']['Name'];
if(!empty($_SESSION['order']['lastName'])) $fields['lastName']=$_SESSION['order']['lastName'];
if(!empty($_SESSION['order']['company'])) $fields['company']=$_SESSION['order']['company'];
if(!empty($_SESSION['order']['street1'])) $fields['street1']=$_SESSION['order']['street1'];
if(!empty($_SESSION['order']['street2'])) $fields['street2']=$_SESSION['order']['street2'];
if(!empty($_SESSION['order']['city'])) $fields['city']=$_SESSION['order']['city'];
if(!empty($_SESSION['order']['state'])) $fields['state']=$_SESSION['order']['state'];
if(!empty($_SESSION['order']['zip'])) $fields['zip']=$_SESSION['order']['zip'];
if(!empty($_SESSION['order']['phone'])) $fields['phone']=$_SESSION['order']['phone'];
if(!empty($_SESSION['order']['email'])) $fields['email']=$_SESSION['order']['email'];
if(!empty($_SESSION['order']['s1_Name'])) $fields['s1_Name']=$_SESSION['order']['s1_Name'];
if(!empty($_SESSION['order']['s1_lastName'])) $fields['s1_lastName']=$_SESSION['order']['s1_lastName'];
if(!empty($_SESSION['order']['s1_company'])) $fields['s1_company']=$_SESSION['order']['s1_company'];
if(!empty($_SESSION['order']['s1_street1'])) $fields['s1_street1']=$_SESSION['order']['s1_street1'];
if(!empty($_SESSION['order']['s1_street2'])) $fields['s1_street2']=$_SESSION['order']['s1_street2'];
if(!empty($_SESSION['order']['s1_city'])) $fields['s1_city']=$_SESSION['order']['s1_city'];
if(!empty($_SESSION['order']['s1_state'])) $fields['s1_state']=$_SESSION['order']['s1_state'];
if(!empty($_SESSION['order']['s1_zip'])) $fields['s1_zip']=$_SESSION['order']['s1_zip'];
if(!empty($_SESSION['order']['s1_phone'])) $fields['s1_phone']=$_SESSION['order']['s1_phone'];
if(!empty($_SESSION['order']['couponCode'])) $fields['couponCode']=$_SESSION['order']['couponCode'];
if(!empty($_SESSION['order']['comments'])) $fields['comments']=$_SESSION['order']['comments'];
if(!empty($_SESSION['order']['list'])) $fields['list']=$_SESSION['order']['list'];
if(!$_SESSION['order']['list']) $fields['list']='Add to eNewsletter list'; // if this var has not been set, default to yes
if(!empty($_SESSION['order']['ship2Billing'])) $fields['ship2Billing']=$_SESSION['order']['ship2Billing'];
}
else { // the form has been posted, so pre-process any data here
$fields['ccNumber']=preg_replace("/\D/",'',$fields['ccNumber']); // remove any non-decimal characters
$fields['couponCode']=strtoupper(str_replace(' ','',$fields['couponCode'])); // remove all spaces and capitalize
}
return true;
}
This works for all the text input fields and textareas, but checkboxes and select menus (and I assume radio buttons, although my form has none of these) don’t get pre-populated.
I guess that what I’m doing here is not actually faking a POSTback but just checking for its conditions. The last time I tried to cross this bridge, I modified the core code and then also had to unset the required and validation arrays and messages in my function when it was not a real POSTback. Now I’m starting to realize that doing it this way will also require some kludges, but hopefully not to the core code....
It doesn’t look to me as if the $formats array should be populated using this method, since it’s not a real POSTback. Which makes me wonder where the placeholders are being set that are working (?). Perhaps the easiest method to make this work without modifying the core code would be to set [+fieldname:value+] placeholders for checkboxes, radio buttons, and select menus manually in the event function.
Do you have another suggestion? I notice a lot of new tricks in the eForm code since I last went through it. I also haven’t tried using the $debug options to see exactly what happens yet.
Just FYI: I converted all of the SHOPx checkout system to use eForm now. It works beautifully, and using the event functions I can save to the database, process the credit card and deal with the returned result, set placeholders for complex emails, etc. It’s currently set up to send data entered by the user to the server via AJAX, so the basket display updates shipping, tax, totals, etc. dynamically as you fill in the form. I still have a lot of work to do before it’s ready for public release, since I’ve been so swamped this summer that I’ve barely been able to keep my head above water. But eForm has been a really helpful tool in the process and made a lot of things much easier than they could’ve been otherwise.
For example, combined with the code in the function above that strips out any non-decimal characters, a simple RANGE validation is enough to make sure that a credit card number is potentially valid:
eform="Credit Card Number:string:1:Your Credit Card Number does not appear to be valid:#RANGE 300000000000000~399999999999999,4000000000000000~6999999999999999"
There are regex’s out there to do this also, but this will catch a missing digit before it goes to the payment gateway.
Thanks again for your help and for creating a great tool.