Play framework select input validation - input

I am using Play 2.1
I made a select drop down box using the helper field constructor.
The drop down box have 3 fields, default:"choose a gender", Male, and Female.
How do I ensure that the user choose one of male or female, and not the default value? (A required drop down field)

I am using Play!Framework 2.1.0, below is a simple solution for your problem:
The model should be like this: (Below is simple model for your problem)
package models;
import play.data.validation.Constraints;
public class Gender {
// This field must have a value (not null or not an empty string)
#Constraints.Required
public String gender;
}
The controller should be like this:
/** Render form with select input **/
public static Result selectInput() {
Form<Gender> genderForm = Form.form(Gender.class);
return ok(views.html.validselect.render(genderForm));
}
/** Handle form submit **/
public static Result validateSelectInput() {
Form<Gender> genderForm = Form.form(Gender.class).bindFromRequest();
if (genderForm.hasErrors()) { // check validity
return ok("Gender must be filled!"); // can be bad request or error, etc.
} else {
return ok("Input is valid"); // success validating input
}
}
The template/view should be like this:
#(genderForm: Form[models.Gender])
#import views.html.helper._
#main(title = "Validate Select") {
#form(action = routes.Application.validateSelectInput()) {
#********** The default value for select input should be "" as a value *********#
#select(
field = genderForm("gender"),
options = options("" -> "Select Gender", "M" -> "Male", "F" -> "Female")
)
<input type="submit" value="Post">
}
}
See also this post as reference : Use of option helper in Play Framework 2.0 templates

Related

Behat Pass a value from a test step

I'm trying to make assertion that the random text entered in one field appears on next page (confirmation)
I do it like this
When I fill in "edit-title" with random value of length "8"
/**
* Fills in form field with specified id|name|label|value with random string
* Example: And I fill in "bwayne" with random value of length "length"
*
* #When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with random value of length "(?P<length>(?:[^"]|\\")*)"$/
*/
public function fillFieldWithRandomValue($field, $length)
{
$field = $this->fixStepArgument($field);
$value = $this->generateRandomString($length);
$this->getSession()->getPage()->fillField($field, $value);
}
Than I want to make assertion - something like this:
Then I should see text matching "<RANDOM VALUE ENTERED IN THE PREVIOUS STEP>"
is it possible?
UPDATE:
But how would it look like with setters and getters if i want to use a generateRandomString method multiple times and then get the values of this methods one after another? DO I have to make variables and functions for every test step? like this:
When I fill in "x" with random value of length "8"
And I fill in "y" with random value of length "12"
And I go to other page
Then I should see text matching "VALUE ENTERED TO X"
And I should see text matching "VALUE ENTERED TO Y"
You can create a property and set it in the previous step. And use it in the next one, but assert it if it has value.
Also it would be nice and readable to define that property with proper visibility type
/**
* #var string
*/
private randomString;
/**
* Fills in form field with specified id|name|label|value with random string
* Example: And I fill in "bwayne" with random value of length "length"
*
* #When /^(?:|I )fill in "(?P<field>(?:[^"]|\\")*)" with random value of length "(?P<length>(?:[^"]|\\")*)"$/
*/
public function fillFieldWithRandomValue($field, $length)
{
$field = $this->fixStepArgument($field);
$this->randomString = $this->generateRandomString($length);
$this->getSession()->getPage()->fillField($field, $this->randomString);
}
/**
*
* #Then /^(?:|I )should see that page contains random generated text$/
*/
public function assertPageContainsRandomGeneratedText()
{
//Assertion from phpunit
$this->assertNotNull($this->randomString);
$this->assertPageContainsText($this->randomString);
}
NOTE: Depending on your behat setup - assertion from phpunit might not work.
Since you will will call the generateRandomString method in multiple places then you should also have a method for getting this value like getRandomString like setters and getters.
My recommendation would be to have a class with related methods that handle all the data and not saving in variable in every place you will use data, generate+save and read from the same place anywhere you need.
Tip: You could be more flexible about the step definition and have a default length for the random string in case one one not provided.
High level example:
class Data
{
public static $data = array();
public static function generateRandomString($length = null, $name = null)
{
if ($name = null) {
$name = 'random';
};
if ($length = null) {
$length = 8;
};
// generate string like $string =
return self::$data[$name] = $string;
}
public static function getString($name = null)
{
if ($name = null) {
$name = 'random';
};
// exception handling
if (array_key_exists($name, self::$data) === false) {
return null;
}
return self::$data[$name];
}
}
In context:
/**
* #Then /^I fill in "x" with random value as (.*?)( and length (\d+))?$/
*/
public function iFillInWithRandomValue($selector, $name, $length = null){
$string = Data::generateRandomString($length, $name);
// fill method
}
/**
* #Then /^I should see text matching "first name"$/
*/
public function iShouldSeeTextMatching($variableName){
$string = Data::getString($variableName);
// assert/check method
}
This is high level example, you might need to do some adjustments.
If you have the validation in the same class then you can also have all these in the same class, meaning generateRandomString and getString in the same class with the steps.

Registering plugin on quick find in Dynamics CRM 2013

I have to register a plugin on Quick Find search on "Artilce" entity. When user enter any thing in quick find text box on Article entity at that time my plugin execute and return filter the data based on our business logic.
1.What event is fired when we find using quick find.
2.What message passes when this event is fired.
I have tried registering the plugin on RetrieveMultiple message but this is not triggered when we click on search in quick find.
Please help.
We have a Plugin registered on the RetrieveMultiple. We had a business requirement to search for the records, using WildCard by default.
Plugin Registration Details:
Message: RetrieveMultiple
Primary Entity:None
Secondary Entity:None
Pre-Operation
Code:
public const String QueryLiteral = "Query";
public const String LIKE = "%";
public void Execute(IServiceProvider serviceProvider)
{
String ParentEntity = String.Empty;
String OriginalSearch = String.Empty;
// Obtain the execution context from the service provider.
var ContextInstance = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// Get a reference to the Organization service.
IOrganizationService ServiceInstance =
((IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory))).
CreateOrganizationService(ContextInstance.InitiatingUserId);
// Critical Point here - NOTICE that the InputParameters Contains the word Query
if (ContextInstance.Depth < 2 && ContextInstance.InputParameters.Contains(QueryLiteral) &&
ContextInstance.InputParameters[QueryLiteral] is QueryExpression)
{
QueryExpression QueryPointer = (ContextInstance.InputParameters[QueryLiteral] as QueryExpression);
//Verify the conversion worked as expected - if not, everything else is useless
if (null != QueryPointer)
{
// Check if the request is coming from any Search View
// We know this b/c Criteria isn't null and the Filters Count > 1
if (null != QueryPointer.Criteria && QueryPointer.Criteria.Filters.Count > 1)
{
ParentEntity = ContextInstance.PrimaryEntityName;
OriginalSearch = QueryPointer.Criteria.Filters[1].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
}
ConditionExpression NewCondition = null;
FilterExpression NewFilter = null;
if (null != QueryPointer.Criteria)
{
//Change the default 'BeginsWith'Operator to 'Contains/Like' operator in the basic search query
foreach (FilterExpression FilterSet in QueryPointer.Criteria.Filters)
{
foreach (ConditionExpression ConditionSet in FilterSet.Conditions)
{
if (ConditionSet.Operator == ConditionOperator.Like)
{
if (OriginalSearch != "")
ConditionSet.Values[0] = OriginalSearch;
else
{
OriginalSearch = QueryPointer.Criteria.Filters[0].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
ConditionSet.Values[0] = OriginalSearch;
}
}
}
}
}
}
ContextInstance.InputParameters[QueryLiteral] = QueryPointer;
}
}
Check details on this Post: http://www.williamgryan.mobi/?p=596
We have raised a ticket with Microsoft to address this situaation.
The solution they provided was to modify the Database to make the message
SearchByTitleKbArticleRequest available in the plugin registration tool.
I currently dont remember the table that we updated a flag against these messages.
After updating the table we were able to register the plugin against the message
SearchByTitleKbArticleRequest
Then the plugin triggered and we modified the entity collection returned from there.

custom Yii validation class

I've created this custom class to validate some numbers on my website.
class EPriceValidator extends CValidator
{
public $number_type;
/*
* Regular Expressions for numbers
*/
private $default_pattern = '/[^0-9,.]/';
private $price_pattern = '/[^0-9,.]/';
/*
* Default error messages
*/
private $default_msg = '{attribute} is an invalid number.';
private $price_msg = '{attribute} is an invalid price.';
/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* #param CModel $object the object being validated
* #param string $attribute the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
// check the strength parameter used in the validation rule of our model
if ($this->number_type == 'price')
{
$pattern = $this->price_pattern;
$error_message = $this->price_msg;
}
else {
$pattern = $this->default_pattern;
$error_message = $this->default_msg;
}
// extract the attribute value from it's model object
$value=$object->$attribute;
if(!preg_match($pattern, $value))
{
$this->addError($object,$attribute, $error_message);
}
}
/**
* Implementing Client Validation
*
* Returns the JavaScript needed for performing client-side validation.
* #param CModel $object the data object being validated
* #param string $attribute the name of the attribute to be validated.
* #return string the client-side validation script.
* #see CActiveForm::enableClientValidation
*/
public function clientValidateAttribute($object,$attribute)
{
// check the strength parameter used in the validation rule of our model
if ($this->number_type == 'price')
{
$pattern = $this->price_pattern;
$error_message = $this->price_msg;
}
else
{
$pattern = $this->default_pattern;
$error_message = $this->default_msg;
}
$condition="value.match(".$pattern.")";
return "
if(".$condition.") {
messages.push(".CJSON::encode($error_message).");
}
";
}
}
it works fine. but how do i make it display the correct field name of the error? right now when there is an error detected on client side, the clientValidateAttribute() displays
{attribute} is an invalid number.
instead of
Total orders is an invalid number.
where Total orders is the input field that is in valid.
Any idea how to fix this?
I rechecked this in the Yii documentation, and it seems you have to add an array with parameters to replace the placeholders in your string. But if you only use the default placeholder for the attribute, it should work by default.
Do you have only the problem on client validation? Because I now checked also the Yii code, and it seems that your code is right, and should work (at least the server validation). But in the client validation you just pass the error mesasage to JSON without any processing, so the {attribute} is not replaces anywhere.
Try to add this to youc client validation before the return
$params['{attribute}']=$object->getAttributeLabel($attribute);
$error_message = strtr($error_message,$params));

Kohana: trying to dynamically change content (not the whole page)

I am struggling to get my head around this since too many hours and I need some help.:)
I have a website build on Kohana and want to dynamically change the content of some text when the user click one button or and another. Not sure if I am doing it the right way but this what I did so far (ho by the way I am new to this framework).
Controller:
class Controller_Homepage extends Controller_General {
public $template = "template/widepage";
public $textbuyer = array (
'text1' => "homepage.buyer.bigtext1", //transfering language variable.
'text2' => "homepage.buyer.bigtext2",
//with more ...
);
public $textseller = array (
'text1' => "homepage.seller.bigtext1",
'text2' => "homepage.seller.bigtext2",
'text3' => "homepage.seller.bigtext3",
//with more ...
);
public $thetext = array ("textbuyer"); //the defaul array is textbuyer
public function action_index() {
$this->content = View::factory("homepage")
->bind('pagetext', $thetext );
if ($this->request->method() === Request::POST) {
$post= $this->request->post();
if (isset($post['buyer'])){
$thetext = $textbuyer;//gives rrorException [ Notice ]: Undefined variable: textbuyer
// arr::overwrite($thetext, $textbuyer);
}else if(isset($post['seller'])){
$thetext = $textseller;
}
}
}
Section of my view to show how I use the variable in the view:
<div class="container_content">
<div>
<p id='sline'><?php echo $pagetext['text1']; ?></p>
</div>
<div>
Can't get the content of my array to the view and when I click on one of the two buttons this code gives me the following error: ErrorException [ Notice ]: Undefined variable: textbuyer. What I am doing wrong ? Why I get the error I mentionned ?
Thank you!
When you define the variables like this
public $textbuyer = ...
public $textseller = ...
public $thetext = ...
They are attributes of your class. And since they are, you need to call them via
$this->textbuyer
$this->textseller
$this->thetext
Just as you call methods inside the same class with $this->methodName() instead of methodName().
class Foo {
public $bar = "hello ";
public function foo() {
$bar = "world";
print $this->bar.$bar; // hello world
}
}
This would work just fine and you get the error because you never define $textbuyer (because you want to call $this->textbuyer).

Grails Searchable Plugin(Lucene) - 1 To Many Query

I am using grail's searchable plugin(0.6.4). I need to search the Members on the basis of privacy settings. Following is the db design.
Member has MemberProfile, and MemberProfile has PrivacySettings
class Member extends {
String firstName
String lastName
static searchable = {
analyzer "simple"
only = ['firstName', 'lastName']
firstName boost: 5.0
profile component: true
profile reference: true
}
static hasOne = [profile: MemberProfile]
}
class MemberProfile {
static searchable = {
analyzer "simple"
only = ['currentCity', 'currentCountry']
privacySettings component: true
}
static hasMany = [privacySettings:PrivacySettings]
String currentCity
String currentCountry
List<PrivacySettings> privacySettings
}
//For instance Privacy Settings contains
//fieldSectionName: firstName , connectionLevel: true , memberLevel: false
// This means firstName will be shown to only members' friends(connection)
class PrivacySettings {
static searchable = {
analyzer "simple"
only = ['fieldSectionName', 'connectionLevel', 'memberLevel']
}
String fieldSectionName
boolean connectionLevel
boolean memberLevel
}
One member profile has many privacy settings for each field.
What will be the query to search only those members which have display_name in fieldsSectionName and connectionLevel true in the privacy settings table.
I am trying something like this
def query="mydisplayname"
def searchResults = Member.search(query + "*" + " +(fieldSectionName:${'display_name'} AND connectionLevel:${true})", params)
I don't know grail but in Lucene the maximum number of clauses in a boolean query is 1024 by default.
You can increase this limit.
There would be performance penalty, though. or you can index the values on the document and search for them (lucene will do an OR operation on different fields with the same name).
You can change the limit using a static property on BooleanQuery class:
BooleanQuery.MaxClauseCount = 99999;
Omri
I had the same issue in my grails application, to resolve it add org.apache.lucene.search.BooleanQuery.maxClauseCount = 99999 to your config.groovy and restart your application