Form Validation
From Nephtali Documentation
Nephtali is built from the ground up to facilitate proper input validation. Inputs are validated through what are called ports, the gatekeepers to any Nephtali web application.
Validating Inputs Server Side
To validate user inputs (get, post, cookie, or file), you perform the following steps:
- Register a port for each input you'll receive. The port defines what type of data you'll accept (e.g., min length, max length, type, encrypted, etc.)
- Validate your ports before using any of their data. Usually this entails presenting a 'feedback' view if there are any invalid ports, and not performing the typical processing (as seen in the example below.)
- Use the values from the ports as needed within your pipes.
Here's the markup for the Nephtali contact form page:
<!--pipe:mail-->
<!--view:default-->
<h2>Thank you for sending us a message</h2>
<p>We appreciate your feedback.</p>
<!--view:default-->
<!--view:error-->
<h2>We weren't able to send your message</h2>
<p>We encountered an error while tring to send your messaage, and we apologize for the inconvenience.</p>
<!--view:error-->
<!--view:feedback-->
<h2>Some of the data was invalid:</h2>
<ul class="standard_list">
<!--data-->
<li>{message}</li>
<!--data-->
</ul>
<!--view:feedback-->
<!--pipe:mail-->
<h2>Send us an email</h2>
<form id="contact" action="index.php" method="post" class="remoteValidation">
<ul>
<li>
<label for="name">Name</label>
<input type="text" id="name" name="name" maxlength="50" />
</li>
<li>
<label for="email">Email</label>
<input type="text" id="email" name="email" maxlength="100" />
</li>
<li>
<label for="message">Message</label>
<textarea id="message" name="message" rows="2" cols="60"></textarea>
</li>
<li>
<input type="submit" value="Send message" />
</li>
</ul>
</form>
</div>
Here's code that validates the inputs and then takes appropriate action (either shows invalid input info or sends the email.)
n\port\register(
$name = 'name',
$value = $_POST['name'],
$opts = array('max_length' => 50, 'filter' => n\constant\FILTER_TEXT)
);
n\port\register(
$name = 'email',
$value = $_POST['email'],
$opts = array('max_length' => 250, 'filter' => n\constant\FILTER_EMAIL)
);
n\port\register(
$name = 'message',
$value = $_POST['message'],
$opts = array('max_length' => 600, 'filter' => n\constant\FILTER_TEXT_MULTILINE)
);
n\pipe\register_action(
$name = 'mail',
$actions = array(
n\port\signature(array('name','email','message')) => function($markup)
{
if (count($rows = n\port\validate(array('name', 'email', 'message'))))
{
return n\view\render($view = 'feedback', $markup, $rows);
}
$ports = n\port\get(array('name','email','message'));
$from = 'contact@nephtaliproject.com';
$to = 'adam@envisionic.com';
$subject = 'Nephtali contact form submission';
$message = "Name: ".$ports['name']."\n"
."Email: ".$ports['email']."\n"
."\n"
.$ports['message']."\n\n";
if (!mail($to, $subject, $message, 'From: '.$from))
{
throw new Exception('We could not send the email.');
}
return n\view\render($view = 'default', $markup);
}
// you could have several other actions added, and the first with a valid port signature would be processed.
),
$opts = array()
);
Providing Feedback Client Side
Once you have server-side code for variable validation, adding feedback for users client-side is very easy. Because all ports automatically provide REST-based calls, you can easily use the javascript framework of your choice to add client-side error feedback.
Port validation can be done REST-fully using the following URL format: http://yourwebsite.com/your_page.php?nmode=validate&nports=COMMA_SEPARATED_LIST_OF_PORT_NAMES
Nephtali JQuery Plugin
To facilitate client-side error feedback, there is a plugin for jQuery that simplifies the validation process. The code below is used to render the client-side feedback for the Nephtali contact form. The plugin allows you to jump in and handle the three states typically involved: the field is invalid, the field is valid, the field should be highlighted (only the most recently visited invalid field is highlighted, allowing for a clean user display in which one error message is displayed at a time.)
$(function(){
$("#contact").validate({
renderInvalid: function(field, errorMsg){
$("#" + field.attr('name') + "Div").remove();
field.removeClass("invalid").addClass("invalid").after("<div class='invalid' id='" + field.attr("name") + "Div" + "'> <div class='displayContainer'><div class='messageWrapper'><div class='errorText'>" + errorMsg + "</div></div><div class='bottom'></div></div></div>");
$("#" + field.attr('name') + "Div div.displayContainer").hide();
// adjust placement of div's after textarea
if(field.tagName == 'TEXTAREA'){
var topMargin = $("#" + field.attr('name')).height();
$("#" + field.attr('name') + "Div").css('marginBottom', topMargin);
}
},
renderValid: function(field){
$("#" + field.attr('name') + "Div").remove();
field.removeClass("invalid").after("<div class='valid' id='" + field.attr('name') + "Div" + "'> </div>");
// adjust placement of div's after textarea
if(field.tagName == 'TEXTAREA'){
var topMargin = $("#" + field.attr('name')).height();
$("#" + field.attr('name') + "Div").css('marginBottom', topMargin);
}
},
highlightError: function(field){
// hide all error messages
$("div.invalid div.displayContainer").hide();
// unhide current message
$("#" + field.attr("name") + "Div div.displayContainer").show();
}
});
$("textarea").autogrow();
});

