I would like to present to you my code vision of Ajax form validation in Zend Framework 3. I am a beginner in Zend Framework and jQuery too, so I don't know that my solution is good and acceptable.
My module has simple work to do. A guest fills the contact form, presses submit button and form is processing. If a guest has enable JavaScript a request is processing by $.ajax()
.
contact.phtml (only jQuery script, the rest is not necessary)
<script type="text/javascript">
$(function(){
$("#foo").submit(function(event){
event.preventDefault();
$.ajax({
url: '/kontakt',
type: 'POST',
dataType: 'json',
data: ($("#foo").serialize()),
success: function (data) {
console.log(data);
if (data.status == false) {
$(".form-error").empty();
$.each(data.msg, function (key, value) {
$.each(value, function (k, val) {
$(".form-error." + key).append(("<li>" + val + "</li>"))
});
});
}
if (data.status == true)
{
$(".form-error").empty();
$( "#contact-form" ).fadeOut( "1000", function() {
$(".description.form").html("<div class='form-flash-msg'>" + data.msg + "</div>");
$( ".description.form" ).animate({
opacity: 0
}, 10000 );
});
}
},
error: function (data) {
console.log(data);
}
});
})
})
</script>
Request has been sent so let's look what we have in ContactController
->contactAction()`.
//ControllerContact->contactAction();
public function contactAction()
{
$contactService = $this->contactService; //set by ContactController::construct()
$form = $this->form; //set by ContactController::construct()
$request = $this->getRequest();
$response = $this->getResponse();
$prg = $this->prg("kontakt", true); // "kontakt" is a route name
$vm = new ViewModel(['form' => $this->form]); //default ViewModel Object
if ($prg instanceof Response) //PostRedirectGet plugin prevent
{ //double form sending when someone refresh
return $prg;
}
if ($prg === false) {
return $vm;
}
$form->setInputFilter(new ContactFormFilter()); //InputFilter for ContactForm
$form->setData($prg); //sets sent data
if (!$form->isValid())
{
if ($request->isXmlHttpRequest()) //
{
$contactService->setResponse('status', false);
$contactService->setResponse('msg', $form->getMessages());
$response->setContent(Json::encode($contactService->getResponse()));
return $response;
}
else //If reguest is't xmlHttpRequest
return $vm;
}
//Ok a form looks valid, let's try to send a mail
$contactService->setResponse('msg', 'Dziękujemy - Twoje zapytanie zostało wysłane.'); //Default msg to return in view if mail will sent ofc.
try {
$contactService->sendMail($form->getInputFilter());
}catch (\Exception $e)
{
$contactService->setResponse('msg', $e->getMessage()); //If we have exception, get exception message
}
if ($request->isXmlHttpRequest()) //XmlHttpResponse request
{
$contactService->setResponse('status', true);
$response->setContent(Json::encode($contactService->getResponse()));
return $response;
}
else //Not XmlHttpResponse
{
$vm->setVariable('msg', $contactService->getResponse('msg'));
$vm->setTemplate("contact/contact/form_sent.phtml");
return $vm;
}
}
The last one is the ContactService
class (it's short so I put the whole thing).
ContactService
-> class
namespace Contact\Service;
use Zend\Mail;
class ContactService
{
private $reciverAddress = '[email protected]';
private $reciverName = 'ReciverName:)';
private $response = [];
/**
* @return mixed
*/
public function getResponse($value = null)
{
if ($value == null)
return $this->response;
else
return $this->response[$value];
}
public function sendMail($email)
{
$mail = new Mail\Message();
$mail->setBody($email->getValue('message'));
$mail->setFrom($email->getValue('email'), $email->getValue('personal'));
$mail->addTo($this->reciverAddress, $this->reciverName);
$mail->setSubject($email->getValue('subject'));
$transport = new Mail\Transport\Sendmail();
$transport->send($mail);
}
public function setResponse($key, $value)
{
if (empty($key))
return false;
$this->response[$key] = $value;
}
}
Everything seems to be fine because it works but I think that maybe it can be done better. Is that even a safe use?
".form-error." + key)
relies on containers to be present in the DOM for all possible keys. It would be safer to create those containers on-the-fly, thereby ensuring they exist. – Roamer-1888 Nov 12 at 10:03