WiTon Nope WiTon Nope - 7 months ago 118
Javascript Question

Onsen UI: Contact Us Form Submission

I'm creating a mobile app using onsen-ui framework and phonegap. I want to add an In-App "contact us" form, where a user can submit a form and on successful submission the form will be sent to email@domain.com.

In index.html I added

<script type="text/ons-template" id="contact.html">
<ons-navigator title="Navigator" var="sNavigator">
<ons-page id="page-contact">
<ons-toolbar>

<div class="left">
<ons-toolbar-button onclick="setHome();">
<ons-icon icon="fa-chevron-left"></ons-icon>
</ons-toolbar-button>
</div>

<div class="center white">
<span id="search-text" class="trn" data-trn-key="contact">Contact Us</span>
</div>
</ons-toolbar>

<div class="home-header">
<img src="css/images/banner.png" alt="" title="">
<p class="center trn" data-trn-key="contact">We respond to messages in the order received</p>
</div>

<form id="frm-contact" class="frm-contact" method="post">

<div class="wrapper">
<div class="field-wrapper">
<input type="text" name="first_name" class="first_name text-input text-input--underbar has_validation"
placeholder="First Name" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
</div>

<div class="field-wrapper">
<input type="text" name="last_name" class="last_name text-input text-input--underbar has_validation"
placeholder="Last Name" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
</div>

<div class="field-wrapper">
<input type="number" name="contact_phone" class="contact_phone text-input text-input--underbar has_validation"
placeholder="Mobile Phone" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
</div>

<div class="field-wrapper">
<input type="email" name="email_address" class="email_address text-input text-input--underbar has_validation"
placeholder="Email address" value="" data-validation="email" data-validation-error-msg="this field is mandatory!" >
</div>

<div class="field-wrapper">
<input type="text" name="subject" class="subject text-input text-input--underbar has_validation"
placeholder="Subject" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
</div>

<div class="field-wrapper">
<textarea style="width:100%;height:80px" name="message" class="message text-input text-input--underbar has_validation"
placeholder="Your Message" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" ></textarea>
</div>

<p class="small-font-dim trn" data-trn-key="create_account_terms">
Please note all fields are mandatory, you should fill in all before submission.</p>
</div>

<button class="button green-btn button--large trn" onclick="contact();" data-trn-key="contact" >
Submit Now!
<div class="search-btn"><ons-icon icon="fa-chevron-right"></ons-icon></div>
</button>
</form>

</ons-page>
</ons-navigator>
</script>


Then I'm validating the form in the .js file and calling the API function

case "page-contact":
translatePage();
translateValidationForm();
$(".full_name").attr("placeholder", getTrans("Full Name",'full_name') );
$(".last_name").attr("placeholder", getTrans('Last Name','last_name') );
$(".contact_phone").attr("placeholder", getTrans('Mobile Phone','contact_phone') );
$(".email_address").attr("placeholder", getTrans('Email address','email_address') );
$(".subject").attr("placeholder", getTrans('Subject','subject') );
$(".message").attr("placeholder", getTrans('Your Message','message') );

break;


Here I'm doing the validation and calling the API from the webserver:

function contact()
{
$.validate({
form : '#frm-contact',
borderColorOnError:"#FF0000",
onError : function() {
},
onSuccess : function() {
var params = $( "#frm-contact").serialize();
params+="&device_id="+ getStorage("device_id");
callAjax("contact",params);
return false;
}
});
}


At the webserver end the PHP code includes

public function actionContact($to='',$from='',$subject='',$body='')
{
$from1=Yii::app()->functions->getOptionAdmin('global_admin_sender_email');
if (!empty($from1)){
$from=$from1;
}

$email_provider=Yii::app()->functions->getOptionAdmin('email_provider');

if ( $email_provider=="smtp"){
$smtp_host=Yii::app()->functions->getOptionAdmin('smtp_host');
$smtp_port=Yii::app()->functions->getOptionAdmin('smtp_port');
$smtp_username=Yii::app()->functions->getOptionAdmin('smtp_username');
$smtp_password=Yii::app()->functions->getOptionAdmin('smtp_password');

$mail=Yii::app()->Smtpmail;

Yii::app()->Smtpmail->Host=$smtp_host;
Yii::app()->Smtpmail->Username=$smtp_username;
Yii::app()->Smtpmail->Password=$smtp_password;
Yii::app()->Smtpmail->Port=$smtp_port;

$mail->SetFrom($from, '');
$mail->Subject = $subject;
$mail->MsgHTML($body);
$mail->AddAddress($to, "");
if(!$mail->Send()) {
//echo "Mailer Error: " . $mail->ErrorInfo;
return false;
}else {
//echo "Message sent!";
return true;
}
} elseif ( $email_provider=="mandrill"){
$api_key=Yii::app()->functions->getOptionAdmin('mandrill_api_key');
try {
require_once 'mandrillapp/Mandrill.php';
$mandrill = new Mandrill($api_key);
$message = array(
'html' => $body,
'text' => '',
'subject' => $subject,
'from_email' => $from,
//'from_name' => 'Example Name',
'to' => array(
array(
'email' => $to,
//'name' => 'Recipient Name',
'type' => 'to'
)
)
);
$async = false;
$ip_pool = '';
$send_at = '';
$result = $mandrill->messages->send($message, $async, $ip_pool, $send_at);
//dump($result);
if (is_array($result) && count($result)>=1){
if ($result[0]['status']=="sent"){
return true;
}
}
} catch(Mandrill_Error $e) {
//echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();

}
return false;
}

$body = $_POST['first_name']. ' ' .$_POST['last_name']. ' ' .$_POST['contact_phone']. ' ' .$_POST['message'];

$to = 'info@domain.com';
$from = $_POST['email_address'];

$headers = "From: $from\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";
$subject = $_POST['subject'];
$message =<<<EOF
$body
EOF;

if (!empty($to)) {
if (@mail($to, $subject, $message, $headers)){
return true;
}
}
return false;
}


The form is sending the email, however if there is no/null data I can't get the information submitted.

Please advise, thank you.

Answer

Based on what you posted, there was an error regarding the device ID. Specifically, the function getStorage was undefined. The code posted below works fine and was able to send all the fields via post to my test PHP page and send an email. Granted, I didn't use a complex PHP processor as you have, but it works!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="mobile-web-app-capable" content="yes" />
    <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
    <link href='https://fonts.googleapis.com/css?family=Roboto:400,300italic,300,400italic,500,700,700italic,500italic' rel='stylesheet' type='text/css'>
    <title>Onsen UI 2.0 Quickstart</title>

    <script src="components/loader.js"></script>
    <script src="lib/onsenui/js/onsenui.js"></script>

    <link rel="stylesheet" href="lib/onsenui/css/onsenui.css" type="text/css" media="all" />
    <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components.css" type="text/css" media="all" />
    <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
    <script>
        function contact()
        {
            var params = $( "#frm-contact").serialize();    
            console.log(params);
        }
    </script>

</head>

<body>
 <ons-page id="page-contact">
   <ons-toolbar>     

    <div class="left">
     <ons-toolbar-button onclick="setHome();">
        <ons-icon icon="fa-chevron-left"></ons-icon>
     </ons-toolbar-button>        
    </div> 

    <div class="center white">
    <span id="search-text" class="trn" data-trn-key="contact">Contact Us</span>
    </div>                  
   </ons-toolbar>

    <div class="home-header">
      <img src="css/images/banner.png" alt="" title="">
      <p class="center trn" data-trn-key="contact">We respond to messages in the order received</p>
    </div>   

   <form id="frm-contact" class="frm-contact" method="post">

   <div class="wrapper">
      <div class="field-wrapper">
      <input type="text" name="first_name"  class="first_name text-input text-input--underbar has_validation" 
      placeholder="First Name" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
      </div>

      <div class="field-wrapper">
      <input type="text" name="last_name"  class="last_name text-input text-input--underbar has_validation" 
      placeholder="Last Name" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
      </div>

      <div class="field-wrapper">
      <input type="number" name="contact_phone"  class="contact_phone text-input text-input--underbar has_validation" 
      placeholder="Mobile Phone" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
      </div>

      <div class="field-wrapper">
      <input type="email" name="email_address"  class="email_address text-input text-input--underbar has_validation" 
      placeholder="Email address" value="" data-validation="email" data-validation-error-msg="this field is mandatory!" >
      </div>

      <div class="field-wrapper">
      <input type="text" name="subject"  class="subject text-input text-input--underbar has_validation" 
      placeholder="Subject" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" >
      </div>

      <div class="field-wrapper">
      <textarea style="width:100%;height:80px" name="message"  class="message text-input text-input--underbar has_validation" 
      placeholder="Your Message" value="" data-validation="required" data-validation-error-msg="this field is mandatory!" ></textarea>
      </div>

      <p class="small-font-dim trn" data-trn-key="create_account_terms">
      Please note all fields are mandatory, you should fill in all before submission.</p>      
   </div>

   <button class="button green-btn button--large trn" onclick="contact();" data-trn-key="contact" >
    Submit Now!
    <div class="search-btn"><ons-icon icon="fa-chevron-right"></ons-icon></div>
   </button>
   </form>

</ons-page>

</body>
</html>

PHP:

<?php 
    $to = 'test@test.com'; 
    $from = $_REQUEST['email_address']; 
    $message = $_REQUEST['message']; 
    $subject = $_REQUEST['subject']; 
    $header = "From: <".$email_address.">" ."\r\n";
    $send = @mail($to, $subject, $message, $header); 
    if(!$send){ 
        die(); 
    }
?>

Also, do note that I didn't send your other fields [first_name, last_name, contact_phone] but they can be added anywhere. Lastly, this is by no means a secure method of sending mail, but something thrown together to prove that Onsen does not interfere with the sending of mail via an HTML form with jQuery.

Edit: Although this is branching from the actual question, based on your comments, I would highly recommend reading some of these:

http://codereview.stackexchange.com/questions/19365/is-this-a-secure-and-best-practice-php-mail-function

Secure php email script

What is the best way to send a secure email in PHP