I am new to Html5 so go easy on me with this question...
I am trying to use HTML5 built in form validation. I am using Bootstrap as my framework. Each time I go to submit a form, when it validates it is putting the bubble way below the form fields that needs to be fix. It would seem to the end user as though it is the field below the one that has the error (Product Name is the one with the error). I have included a screen shot of what I am geting. Here is my markup: Thanks for your help!!!
<div class="control-group">
<label class="control-label required" for="product_name">Name</label>
<div class="controls">
<input type="text" id="product_name" name="product[name]" required="required" placeholder="Product Name" class="span12" value="" />
</div>
In your FormBuilder, turn off the option require and use Form Validation.
Example in ProductType.php
$builder->add('name', 'text', array(
'label' => 'Name',
'required' => false // this will remove the HTML5 error which in my opinion is meh
));
In your validation.yml
Your\AwesomeBundle\Entity\Product:
properties:
name:
- NotBlank: ~ # when you call bindRequest on the form object it will validate the form data against that constraint
Make sure you check the Form Validation documentation because as of Symfony2.2 some constraints has changed.
Related
Using Angular 2 (2.0.0), what is the recommended way to dynamically mark a field as required, using Angular Forms?
In all of their examples, the required attribute is just added like:
<input type="text" class="form-control" id="name" required>
What if the model I'm binding to has an IsRequired property, that will be true/false?
If I use something like:
<input [(ngModel)]="field.Value" type="text" value="{{field.Value}}" [attr.required]="field.IsRequired"/>
That renders on the page like (note the ="true"):
<input type="text" required="true" />
For some reason, Angular doesn't appear to recognize this attribute when it has an actual value (the ="true") so when this field is blank, my form itself still is valid:
<form class="ng-untouched ng-pristine ng-valid">
So it would appear that I must use required and not required="true", but how can I add that attribute in dynamically?
What also doesn't work:
<input type="text" {{ getRequiredAttr(field) }} />
Thought I might be able to have a function that returns my string "required" based on the field, that just gives templating errors.
Is there a way to accomplish this and render only required for my attribute? Or a way to make Angular recognize this attribute when it has a value of true/false?
FWIW - I've verified that I can use *ngIf to write two near-identical <input type='text' /> controls based on my IsRequired property and hardcode one with the required attribute but that seems pretty hacky. Hoping there's a better way!
Why do you have to make it so complicated when you can simply do this,
[required]="isFieldRequired() ? 'required' : null"
The basic forms stuff is great for simple forms, but when you need more control like what you have here, that is when you need to start using the more advanced form stuff. What that would look like in your case would be something like this.
#Component({
selector: 'something',
template: `
<form #myForm="ngForm">
<input [(ngModel)]="field.Value" [formContol]="myFieldControl" type="text" [value]="field.Value">
</form>
`
})
export class MyComponent{
public field: any = {Value: 'hello', isRequired: false};
public myFieldControl: FormControl = new FormControl('', [this.dynamicRequiredValidator.bind(this)]);
public dynamicRequiredValidator(control: FormControl):{[key: string]: boolean}{
if(field.IsRequired && !control.value){
return {required: true};
}
return {};
}
}
Note: You will probably need to import the ReactiveFormsModule into your #NgModule. This comes from #angular/forms as well.
There is also another way you can do this with a directive shown here.
I have worked on AngularJs and now working on Angular2. Whenever I searched for form validation in angular I always found the submit button like below:
In AnglarJs
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
In Angular2
<button type="submit" class="btn btn-default"
[disabled]="!heroForm.form.valid">Submit</button>
But I wanted the submit button should be enable and whenver user click on that we prompt the error below the text fields. There is no exact solution mentioned for this purpose.
I found some of that some of the users directly clicks on submit button and they wanted to fill only required fileds.
This is my observation only may be some of you also experienced the same while development.
For AngularJs 1 I am using custom-submit directive from here
https://gist.github.com/maikeldaloo/5133963
So please suggest me any solution to provide custom-submit in angular2 also.
---- Sample Login Form (Angular2) ---
<form class="ui large form" (ngSubmit)="onUserLogin(loginForm.form.valid)" #loginForm="ngForm" method="post" novalidate>
<sm-loader [complete]="!formSubmited" class="inverted" text="Loading..."></sm-loader>
<div class="field">
<input type="email" name="email" placeholder="Email" [(ngModel)]="login.email" #email="ngModel" required />
<div [hidden]="email.valid || email.pristine" class="error text-left">
Email is required
</div>
</div>
<div class="field">
<input type="password" name="password" placeholder="Password" [(ngModel)]="login.password" #password="ngModel" required />
<div [hidden]="password.valid || password.pristine" class="error text-left">
Password is required
</div>
</div>
<button class="fluid yellow large ui button" type="submit">Login</button>
</form>
Please check what custom-submit directive are doing. Please give me answers the based on that. I know I can check the form valid status on controller level, but why this way I can say only form is not valid, I can not say which field is empty (we can also check this which field is valid, but don't know how to enable the error divs from controllers)
Please refer this...
https://gist.github.com/maikeldaloo/5133963
Thanks,
Just set a state and show/hide the errors depending on the state:
onSubmit() {
if(hasErrors()) {
this.hasErrors = true;
return false; // preventDefault
}
this.postData(); // process submit event
}
<div *ngIf="hasError">
... error info here
</div>
This way we actually validate whether you have entered the correct values or not. If any of the value fails then submit button gets disabled otherwise enabled.
For ex: E-mail : If email id doesn't have # and ., then it will be considered as dirty, which wouldn't lead to enable the submit button.
Edited:
To display the message you can do one thing:
<input type="submit" ng-click="done(heroForm.form.valid)" />
And in controller you can do this way.
$scope.done = function(valid){
if(valid) {
// Form content is valid, process it
} else {
// show error and do nothing.
}
}
I would like to clarify one thing about MVC5 Razor Views.
I was told that I don't have to use HTML Helpers (#Html.EditorFor, #Html.TextBoxFor) in my razor views and it will still work.
Controller Code
[HttpPost]
public ActionResult Create(Models.TestObj obj)
{
ViewBag.TestStr = string.Format("You typed: {0} {1}", obj.FirstName, obj.LastName);
return View(obj);
}
Razor View
#using (Html.BeginForm())
{
<div>
#Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { #class = "form-control", style = "width: 120px;" } })
<input class="form-control text-box single-line" id="LastName" name="LastName" style="width: 120px;" type="text">
<input type="submit" name="submit" value="Filter" / >
</div>
#ViewBag.TestStr
}
But when I actually test it like the above, the value typed in 'LastName' textbox is not preserved. I can catch both textbox values in my Controller. But after postback, lost the value in 'LastName' textbox. The textbox which is created by using HTMLHelper didn't lose the value though.
Am I doing something wrong or is it supposed to be like that? Do I have to use HtmlHelpers in RazorViews in MVC5 if I want to keep the submitted values?
What's a "postback"? It sounds like you're trying to think of this in terms of WebForms, where the server-side controls have a lot of plumbing doing things behind the scenes.
Simply put, there is no code in your view which actually puts a value in that input. When using the HTML helpers, while the generated client-side markup is the same (and, thus, the post to the next controller action is the same), one thing that's different is that the HTML helpers will bind the control to the model that's supplied to the view.
HTML, by itself, won't do that. You can, however, do that manually:
<input value="#Model.LastName" class="form-control text-box single-line" id="LastName" name="LastName" style="width: 120px;" type="text">
^--- right here
Your not binding the second input to the value of LastName, just setting its name attribute. If you inspect the html you generating, you will note the first one has a value attribute whereas the second does not.
You need to use the EditorFor() (or TextBoxFor()) as you did for the FirstName which generates the correct value attribute (and other data-val-* attributes necessary for using client side validation).
Side note: You could also use
<input name="LastName" ..... value="#Model.LastName"` />
however this will not take into account ModelState values
You need to add the textbox in your model, and the link it in the view index.cshtml like this: m = m.Variable_name_from_your_model
Check out this site:
https://mvcstepbystep.wordpress.com/how-to-update-a-c-mvc-textbox-from-jquery/
I'm facing the well known Chrome's "not-focusable-input" error but my situation is different from the explained in the other post I could find there.
I have this error message duplicated first on a well pointed input, this input has no required attribute:
The code:
<fieldset>
<label>Total (montaje incl.)</label>
<input type="number" id="priceFinal" name="priceFinal"> €
</fieldset>
The error:
An invalid form control with name='priceFinal' is not focusable.
While the user is filling the form this field gets its value by a js script with jquery. The user type a size in another input, the script do its maths with the size value and then put the outcome in the 'priceFinal' input with the jquery function: .val()
In the browser we can see that the input is correctly filled and no errors are displayed at that time. And with the 'novalidate' solution everything goes fine, so it couldn't be responsible for the nofocusable error, I think.
Then I got the same error with an input with no name which I didn't write and doesn't exist in my DOM:
An invalid form control with name='' is not focusable.
This is weird because the only input without name in my form is the type:submit one
<input type="submit" class="btn btn-default" value="Ver presupuesto" />
I have a few required fields but I've always checked that their are all filled when I send the form. I paste it just in case it could help:
<fieldset>
<input type="text" id="clientName" name="clientName" placeholder="Nombre y apellidos" class="cInput" required >
<input type="text" id="client_ID" name="client_ID" required placeholder="CIF / NIF / DNI" class="cInput">
</fieldset>
<fieldset>
<input type="text" id="client_add" name="client_add" placeholder="Dirección de facturación" class="addInput" required >
</fieldset>
<fieldset>
<input type="text" id="client_ph" name="client_ph" placeholder="Teléfono" class="cInput" required>
<input type="email" id="client_mail" name="client_mail" placeholder="Email" class="cInput" required>
</fieldset>
The novalidate solution clears the error but it doesn't fix it, I mean there must be a way to solve it with no hacks.
Any one have any idea of what's might going on?
Thanks
I had the same problem, and everyone was blaming to the poor hidden inputs been required, but seems like a bug having your required field inside a fieldset.
Chrome tries to focus (for some unknown reason) your fieldset instead of your required input.
This bug is present only in chrome I tested in version 43.0.2357.124 m.
Doesn't happen in firefox.
Example (very simple).
<form>
<fieldset name="mybug">
<select required="required" name="hola">
<option value=''>option 1</option>
</select>
<input type="submit" name="submit" value="send" />
</fieldset>
</form>
An invalid form control with name='mybug' is not focusable.
The bug is hard to spot because usually fieldsets don't have a name so name='' is a WTF! but slice piece by piece the form until I found the culprid.
If you get your required input from the fieldset the error is gone.
<form>
<select required="required" name="hola">
<option value=''>option 1</option>
</select>
<fieldset name="mybug">
<input type="submit" name="submit" value="send" />
</fieldset>
</form>
I would report it but I don't know where is the chrome community for bugs.
Thanks to this post, I saw that my problem also rested with Chrome trying to focus on my fieldsets, instead of the input field.
To get a better response from the console:
Assign every DOM element a new name
Set every input & select style.display to 'block'
Changed the type of input[type="hidden"] elements to 'text'
function cleanInputs(){
var inputs = document.getElementsByTagName( 'input' ),
selects = document.getElementsByTagName( 'select' ),
all = document.getElementsByTagName( '*' );
for( var i=0, x=all.length; i<x; i++ ){
all[i].setAttribute( 'name', i + '_test' );
}
for( var i=0, x=selects.length; i<x; i++ ){
selects[i].style.display = 'block';
}
for( var i=0, x=inputs.length; i<x; i++ ){
if( inputs[i].getAttribute( 'type' ) === 'hidden' ){
inputs[i].setAttribute( 'type', 'text' );
}
inputs[i].style.display = 'block';
}
return true;
}
In the console, I ran cleanInputs() and then submitted the form.
The result, from the console, was:
An invalid form control with name='28_test' is not focusable.
An invalid form control with name='103_test' is not focusable.
Then, switching over to the Web Developer "Elements" view, I was able to find "28_test" and "103_test" (both fieldsets) -- confirming that my problem was a required input field, nested inside a fieldset.
While I was writting the question I realized one thing: the value the script was putting into the 'priceFinal' field sometimes was a decimal number.
In this case the solution was to write the step attribute for this input:
... step="any" ...
Step on w3s
So this 'nofocusable' bug is not only a required and hidden fields issue, it's also generated by format conflicts.
Nach gave me the best pointer... (y) I also had a input type="number" with step="0.1" and the console shows me this error while validating: An invalid form control with name='' is not focusable.
remove the step="0.1" on the element and now the form can be validated
I had the same issue so I removed required="required" from the troublesome fields.
If you get the error when jQuery function is executed, try to put "return false" on your function, or function(e) { e.preventDefault(); ... }
i had this issue once. to fix it, add
novalidate
as an attribute to the form. e.g
<form action="" novalidate>
....
</form>
In my case, the input element did not have a required attribute but it was hidden. and the problem was while it was hidden, it had a value in it. I guess if an input field is hidden it shouldn't have a value too, aside required attribute.
When I remove the value through my javascript code, everything works fine.
Element is hidden, No required Attribute, No value. Worked
Here is the solution....
<form>
<input type="text" ng-show="displayCondition" ng-required="displayCondition"/>
</form>
Many people do not realize that passing false into ng-required disables the directive.
how can I send date from my form ?
In previous form I have something like this :
#Html.TextBoxFor(m => m.UserName)
But now I have:
<input type="text" class="form-control" placeholder="Login">
So how I can pass my data ?
I think this is what you are looking for..
<input type="text" class="form-control" value="SOME THING" placeholder="Login">
add an 'id' attribute in your tag, and on postback of your form, you can query the form elements by id. Thats what the MVC code you posted does internally.