Send form to different e-mail based on zip code

MuzikBraud05 19 Mar, 2009
Hello,

I am building a form and I want to be able to send the form to the appropriate e-mail address based on the zip code the user enters. For example, when a user enters their address and submits the form, if they have entered 23669, 23608, or 23502 in the zip code field, the form will be sent only to the north office, but if they entered 23462, 23454, or 23302, it will go only to the south office (I actually have a long list of zip codes!). I've used Chronoforms before, so I think the form itself will be pretty basic - the user enters their name, contact info, & select from a list of problems and submits the form.

Is there anything I can do to make this happen, or anything I should know before setting up the form? Thanks!
GreyHead 19 Mar, 2009
Hi MuzikBraud05,

This is failry straightforward and there are several examples in the forums (and I think one in the FAQs) - make sure that you find one using Joomla 1.5 code with 'JFactory' style code and not 'mos' style code.

If your list of zip codes is really long it might be easier to handle them in a database table and look the e-mail value up there rather than have an enormous array to manage.

Bob
MuzikBraud05 19 Mar, 2009
Thank you for yor quick response.

I couldn't find anything inthe FAQs or forum specifically relating to my problem, which is why I posted a new topic. I saw #31 in the FAQ almost answered my question, but it was based on a drop-down menu, and I am not trying to create a drop-down list of zipcodes for users, I need them to be able to type it in. I am also not simply trying to send the form to different e-mails, but I need it to be sent to a particular e-mail based upon the zip code. When I searched the forum I found similar questions and answers but they were concerning drop-down menus as well. Myabe it's a "duh" thing, but I can't figure out how to apply this to my situation.

Since you know where the examples are, can you please post links to a few threads that will help, or tell me what combination of words to type in the search box to find what I am looking for because I really have tried. I'm sorry that it's not so straightforward to me 😶

Thanks again for any help you can point me towards.
GreyHead 19 Mar, 2009
Hi MuzikBraud05,

The example in the FAQ is very similar - you are just going to use an input box to return the result instead of a drop-down box.

I suggest that you build a simple example with 4 or 5 zip codes to see how it works.

Bob
nml375 19 Mar, 2009
Your intentions is not that different from a dropdown box, at least from a coder's perspective. You have some form input, which you use to determine the recipient email address.
The trick is, figure out which email address to use as recipient, and save/add that to $emails[0]->to.

The part of figuring out which email address to use may wary, and partly depends on your needs.
If possible, I'd try to figure some pattern for sending. Zip codes usually are geographically oriented.

Looking at the 6 zip-codes you posted, I'd guess anything like 233xx-234xx would go to south office while 235xx-236xx would go to north.
Here I chose to use a tree-like switch structure because it allows me to make decisions early on most significant digit, but still allows me to proceed until the least significant digit if needed (say anything 1xxxx would go to west office, we easily add a case for that).

There are, of course numerous other methods you could do this, including storing one email per zip-code in an array, storing them in a database table (as suggested by Bob), etc. Since you're the one holding the information on which email to use on which zip, you'll have to decide this part.

<?php
$zip = JRequest::getVar('zipcode');
switch (substr($zip, 0, 1)) {
 case 1:
  $email[0]->to .= ',west@yourdomain.com';
  break;
 case 2:
  switch (substr($zip, 1, 1)) {
   case 3:
    switch (substr($zip, 2, 1)) {
     case 3:
     case 4:
      $email[0]->to .= ',south@yourdomain.com';
      break;
     case 5:
     case 6:
      $email[0]->to .= ',north@yourdomain.com';
      break;
    }
  }
}
?>


Edit: Fixed missing break; in the code, and the missing ?>.
Also, starting on something simple such as 4-5 zip's for starters sounds like a very good idea.
MuzikBraud05 21 Mar, 2009

The example in the FAQ is very similar - you are just going to use an input box to return the result instead of a drop-down box.



This is what I can't figure out - there is no "value" field in the html for the input box, so I don't know what to do with the on submit code provided in FAQ31. Here is the zip code part of my form:

<div class="form_item">
  <div class="form_element cf_textbox">
    <label class="cf_label">5-digit Zip Code</label>
    <input class="cf_inputbox required validate-number" maxlength="150" size="30" id="text_6" name="text_6" type="text" />

  </div>
  <div class="clear"> </div>
</div>


In FAQ 31 it provides the following example:

Select the recipient you wish to contact:
<select name="recipients">
  <option value="em1">Name 1</option>
  <option value="em2">Name 2</option>
  <option value="em3">Name 3</option>
  . . . 
</select>


and says to enter this code in the 'On Submit code - before sending email' field:

<?php
$emails_2 = array('em1'=>'sample1@email.com', 'em2'=>'sample2@email.com', 'em3'=>'name_3@example.com', . . .);
 $emails[0]->to .= ','.$emails_2[$_POST['recipients']];
?>


... and I see that if the value of em1 is chosen in the drop-down list, the e-mail would be sent to [email]sample1@email.com[/email]. If I just replace "em1" in the php code with a zip code it doesn't work.... what do I need to do?
nml375 21 Mar, 2009
The only difference between a text input field and a dropdown menu, is that the values are a fixed list in the dropdown menu (each menu item has its own value), where the text input allows the user to enter whatever text they feel like. You may have a value field in a text input as well, but that would only pre-fill the input with a default value.

The onSubmit php code really doesn't care for any value parameters, and is frankly unaware of them, it only receives information that field named "thisfield" has "thisvalue" and "thatfield" has "thatvalue".

In your posted code, you have a text input named "text_6" that contains the zip code. In the onsubmit php code, you retrieve that value using something like this:
<?php $zip = JRequest::getVar('text_6'); ?>


Next step, is to use the value in $zip to try and determine which mail address to send the form input.
You could use the array indexing suggested in the #31 Faq. What you must keep in mind here though, is that it must be an exact match down to any spaces. You might wish to "scrub" the entered zip code from any spaces or strange characters to ensure function ability.
To adapt the code from #31 Faq to your form, the onSubmit code would look something like this:
<?
$zip = JRequest::getVar('text_6');
$emaillist = array('23302' => 'south@yourdomain.com', '23454' => 'south@yourdomain.com', ' 23462' => 'south@yourdomain.com',
 '23502' => 'north@yourdomain.com', '23608' => 'north@yourdomain.com', '23669' => 'north@yourdomain.com');
$emails[0]->to .= ','.$emaillist[$zip];
?>
MuzikBraud05 24 Mar, 2009
Thanks! Worked perfectly. I ended up having to type in each zip code but it really wasn't so bad, and I'm starting to understand how it all works(php, that is), thanks again! 😀
garydev 20 Dec, 2009
Hello,
First off, Thank you! for such an excellent component. You have an exceptional product that goes far beyond being merely a "form component".

I am a CF newbie and developing on a temp domain. Once it is migrated to the permanent domain, I will happily validate my installation.

I have a form working that will send a message to an email address based upon the user's input (as described above.)
<?php $zip = JRequest::getVar('text_12'); ?>
<?
$zip = JRequest::getVar('text_12');
$emaillist = array('85001' => 'me@mydomain.net', '85002' => 'him@hisdomain.net', ' 85003' => 'you@yourdomain.com',
'85004' => 'that@itsdomain.net', '85005' => 'info@adomain.com', '85006' => 'admin@arizonaarmyguard.net');
$emails[0]->to .= ','.$emaillist[$zip];
?>


Works well and every time. The problem is that I have over 500 zips with 90 email addresses. So I created a table that associates the various email addresses with the specific zip codes. That table is called zips_email .

I have been bumping around trying many things to query that table for the $emailad based upon the user's input into the zip code text box (text_12).

I fumble around with php and MySQL well enough. I'm doing okay dealing with the table the form is directly associated with. When I add CF into the mix and the other table, well enough is not a good description of what I'm doing.

Any advice is much appreciated.
GreyHead 21 Dec, 2009
Hi garydev,

The code you need is something like
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post'); ?>
$query = "
  SELECT `email`
    FROM `#__zips_email`
    WHERE `zip` = '$zip' ;
";
$db->setQuery($query);
$email = $db->loadResult();
Note that the table and column names may not be correct. And you will need to add code to deal with the case that the zip isn't found.

Bob
garydev 21 Dec, 2009
Thanks, I'll try it.
garydev 21 Dec, 2009
Hi Bob,
Thank you for your quick reply.
I tried your code (which confirmed I was on the right track). Edited a bit to close the php tag.
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post'); 
$query = "
  SELECT `recruiters_email`
    FROM `#__jos_chronoforms_zip_email`
    WHERE `zip_code` = '$zip' ;
";
$db->setQuery($query);
$email = $db->loadResult();
?>


It is not working. I'm getting nothing back except for a message to the address in the "Set Up Email" tab.

What is the procedure for the "Set Up Emails" tab when using this method? Should I use dynamic options? Leave it blank?

I'll attach a back up of the form in a PM. I hope that is appropriate.

Thank you in advance.
garydev 21 Dec, 2009
Edited to correct recruiters_email $ and php tag error
]<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post'); ?>
<?
$query = "
  SELECT `recruiters_email`
    FROM `#__jos_chronoforms_zip_email`
    WHERE `zip_code` = '$zip' ;
";
$db->setQuery($query);
$recruiters_email = $db->loadResult();
?>
GreyHead 21 Dec, 2009
Hi garydev,

This line is wrong for sure:
FROM `#__jos_chronoforms_zip_email`
It should be
FROM `#__chronoforms_zip_email`
and you'll still need the backend of the previous code to use the value that you get back from the database.

Bob
garydev 21 Dec, 2009
I thought I would have nailed this down hours ago. Having a difficult time meshing the two snippets you graciously provided. This is what I think is going on (obviously, I'm incorrect)
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post'); ?>
<?
$query = "
  SELECT `recruiters_email`
    FROM `#__chronoforms_zip_email`
    WHERE `zip_code` = '$zip' ;
";
$db->setQuery($query);
$result_email = $db->loadResult();?>


Please correct my misunderstanding.
This code retrieves the email address associated with the zip code entered in text_12 (which is a text input box) and sets the result of the query and loads it as a new variable ($result_email) for the next piece of code.

<?php
$email_recruiter = JRequest::getVar('result_email'); ?>
<? $email_recruiter = JRequest::getVar('result_email');
$emaillist = array('$zip' => '$result_email');
$emails[0]->to .= ','.$emaillist[$email_recruiter];
?>


Creates a new variable ($email_recruiter) from the loaded variable ($result_email). Then I tried to just get an email by plugging the $zip and $result_email in where the hard coded zips and email addresses were from the code snippet that worked sending emails based on the created array.

This is my latest effort. I've tried many other combinations but all I keep getting is an email to the address in the "Setup Emails) tab.

Thank you in advance for any guidance.
nml375 21 Dec, 2009
Hi garydev,
You could probably simplify the code even further:
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post');

$query = "SELECT `recruiters_email`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$result_email = $db->loadResult();

if ($result_email !== null) {
  $emails[0]->to .= ',' . $result_email;
}
?>

The $email[] array is only used in older (3.0) versions of ChronoForms. With the current version (3.1RC5), you'll instead interact with a CFEmails-object, so keep this in mind if you intend to upgrade.

/Fredrik

Edit: Restored the $db declaration I accidentally removed
garydev 21 Dec, 2009
Hi and Thank you very much for the information. My CF installation is new, so I presume the interaction with the object as you describe is pertinent to my installation V3.1_RC5.2

I received the following error:
Fatal error: Call to a member function setQuery() on a non-object in /hermes/web09b/b2831/as.arizonaarmyguard/public_html/components/com_chronocontact/libraries/customcode.php(64) : eval()'d code on line 7
nml375 21 Dec, 2009
Hi garydev,
Sorry, accidentally removed this rather vital line:
$db =& JFactory::getDBO();

I've updated my previous post to include this..

In order to use the newer API, you'll need these three lines instead of the "$emails[0]->to ..."
$MyForm =& CFChronoForm::getInstance('form_name_here');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', $result_email);

(still assuming the destination email address is stored in $result_email, you'll have to change form_name_here to whatever you named your form)

/Fredrik
garydev 21 Dec, 2009
Hmmppfff. Still just getting the result directed at the to address in the "Setup Email" tab. This happened for this code:
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post');

$query = "SELECT `recruiters_email`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$result_email = $db->loadResult();

if ($result_email !== null) {
$MyForm =& CFChronoForm::getInstance('Contact');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', $result_email);  
}
?>


I also tried this

<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('text_12', '' , 'post');

$query = "SELECT `recruiters_email`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$result_email = $db->loadResult();

if ($result_email !== null) {
  $emails[0]->to .= ',' . $result_email;
}
?>


Which eliminated the error code, but produced only an email directed to the address in the "Setup Email" tab.

:?
nml375 21 Dec, 2009
Could you try enabling the site-wide SQL-debugging, and look for the recruiters_email query upon a form submission?
Also, if you could add something like this at the end of the code, and paste the results:
print_r($result_email);
print_r($query);


/Fredrik
garydev 21 Dec, 2009
Okay,
Is this the section of the debug you need? There was no reference to "recruiters_email" query.
s:17:\"com_chronocontact\";a:1:{s:4:\"data\";O:8:\"stdClass\":2:{s:30:\"limitjos_chronoforms_zip_email\";s:2:\"20\";s:35:\"limitstartjos_chronoforms_zip_email\";i:0;}}}


Here is the code which printed on the "After Email" page:
SELECT `recruiters_email` FROM `#__chronoforms_zip_email` WHERE `zip_code` = ''


Please let me know if you need more or something else.

Thanks for your help.
nml375 21 Dec, 2009
That was exactly what was needed. The code fails as $zip apparently is empty:
SELECT `recruiters_email` FROM `#__chronoforms_zip_email` WHERE `zip_code` = ''

Do you got the right form input name in the JRequest::getString() method? (is the form field containing the zip-code named 'text_12')

/Fredrik
garydev 21 Dec, 2009
Oh Brother! No, that input is zipcode_0

I will correct my silly error and come back with the result. I'm sorry for the hassle caused by my error. I got so blurred out working this that the input text box id from the the person that started this thread got incorporated into the code.

Thanks you very much for your patience in helping me troubleshoot.
garydev 21 Dec, 2009
Eureka!

That fixed it. It is now sending emails from a separate table / database based upon the user's input into the zip code text box.

Thank you!

I suppose that an else statement would be inserted after the if argument to send to a default address for zip codes that do not exist in the database?

I'll post the whole procedure / code / forms for the benefit of others after I get a little sleep.

Thanks very much again Fredrik and Bob.
GreyHead 21 Dec, 2009
Hi garydev,

Good to hear you got it working OK.

You should tidy up by an use the 'else' statement to set a default email if all else fails.

Bob
garydev 02 Feb, 2010
Hi,
I was looking through here and realized that I did not post the "Before Sending Email" php code. Here it is.
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('yourzipcodefieldname', '' , 'post');

$query = "SELECT `recruiters_email`
  FROM `#__chronoforms_your_data_base_name`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$result_email = $db->loadResult();

if ($result_email !== null) {
$MyForm =& CFChronoForm::getInstance('Contact');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', '$result_email');  
}
?>
garydev 02 Feb, 2010
Now trying to add a CC for the form based upon the email recipient's superior. I'm trying the following code but not getting the CC in tests:
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('zipcode_0', '' , 'post');

$query = "SELECT `recruiters_email`,`superior`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$ab = NULL;
$result = $db->loadObject($ab);
$result_email = $result->recruiters_email;
$cc_email = $result->superior;
if ($result_email !== null) {
$MyForm =& CFChronoForm::getInstance('Contact');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', '$result_email');  
$MyFormEmails->setEmailData(1, 'cc', '$cc_email'); 
}
?>
GreyHead 02 Feb, 2010
Hi garydev,

If you are using PHP Mail Function as your site mailer then it doesn't support CC or BCC :-(

The code looks OK -- though I'm not sure about the $ab = null bit

Bob
garydev 02 Feb, 2010
Hi Bob,
The $ab = NULL is being used in the After Sending Email to format the "Success" message.

I'm using the default Joomla! form mailer. Bummer to hear that it does not support CC or BCC.

Any advice on how to achieve the desired result? I suppose I could create a duplicate of the code that works and send two emails. . . Any advice on this approach?
GreyHead 02 Feb, 2010
Hi garydev,

The 'best' site mailer option is probably sendmail if your host supports it. That supports CC & BCC OK. (The Gmail smtp server works well if you are on an internet based site not an intranet.)

Otherwise, two emails works OK. Multiple entries in the ToEmail field works OK.

Bob
garydev 02 Feb, 2010
Hi Bob,
Switched over to Sendmail in Joomla! Global Configuration using this code and still no CC.
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('zipcode_0', '' , 'post');

$query = "SELECT `recruiters_email`,`superior`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$ab = NULL;
$result = $db->loadObject($ab);
$result_email = $result->recruiters_email;
$cc_email = $result->superior;
if ($result_email !== null) {
$MyForm =& CFChronoForm::getInstance('Contact');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', '$result_email');  
$MyFormEmails->setEmailData(1, 'cc', '$cc_email'); 
}
?>
GreyHead 02 Feb, 2010
Hi garydev,

What shows up in the dummy email if you turn Debug on?

Bob
garydev 02 Feb, 2010
This:

E-mail message
From: Website [admin@domain.net]
To: $result_email
CC: $cc_email
BCC:
Subject: Email From Domain.com

GreyHead 02 Feb, 2010
Hi garydev,

Ah, so the problem is extra quotes here
$MyFormEmails->setEmailData(1, 'to', '$result_email'); 
$MyFormEmails->setEmailData(1, 'cc', '$cc_email'); 
that shold be
$MyFormEmails->setEmailData(1, 'to', $result_email); 
$MyFormEmails->setEmailData(1, 'cc', $cc_email); 

Bob
garydev 02 Feb, 2010
That fixed it. This code sends an email to a specific address based upon the user's entry of a zip code and CC's the recipient's superior as well. Thanks very much for your help, GreyHead.
<?php
$db =& JFactory::getDBO();
$zip = JRequest::getString('zipcode_0', '' , 'post');

$query = "SELECT `recruiters_email`,`superior`
  FROM `#__chronoforms_zip_email`
  WHERE `zip_code` = '$zip'";
$db->setQuery($query);
$ab = NULL;
$result = $db->loadObject($ab);
$result_email = $result->recruiters_email;
$cc_email = $result->superior;
if ($result_email !== null) {
$MyForm =& CFChronoForm::getInstance('Contact');
$MyFormEmails =& CFEMails::getInstance($MyForm->formrow->id);
$MyFormEmails->setEmailData(1, 'to', $result_email);  
$MyFormEmails->setEmailData(1, 'cc', $cc_email); 
}
?>
This topic is locked and no more replies can be posted.