How can I do something like ActionVIew::Helpers::FormHelper#check_box, but without an object to hang it on?
I'm building a user profile editor. Some of my fields are ordinary booleans, and check_box is great with them:
app/views/users/edit.html.erb:
<%= f.label :admin %>
<%= check_box :user, :admin %>
produces the expected extra hidden field
<label for="user_admin">Admin</label>:
<input name="user[admin]" type="hidden" value="0" />
<input id="user_admin" name="user[admin]" type="checkbox" value="1" />
and posts the setting as expected.
But my users also have a password, and the behavior I want isn't actually to set or clear a boolean field, but rather to trigger an email-mediated reset protocol. I'd like it to look the same as the simple check_box :user, :admin case. User objects don't have a "reset_password" field, so this is just a syntax error:
<%= f.label :reset_password %>
<%= check_box :user, :reset_password %>
EDIT: I guess I could make an actual db column / object attribute named reset_password, which is always false, but when the controller sees an attempt to set it, it instead launches the reset protocol. But an always-false, read-only attribute seems a tad silly, doesn't it?
If it's not part of the user profile data, why make it a checkbox? It could just be a link instead of a checkbox, either on the user edit screen or on the user profile view. If you really want it as a checkbox in the form, you could also just make the checkbox part of a subform that would get submitted at the same time as the main form, using a javascript call, and hiding the submit button...
Related
I'm trying to learn forms in AngularJS 1.x. But I have error messages that are always on when it first loads. How to develop behaviour such that they are blank on load, and only red after a submit if fields were not entered? Seems to be a few states I have to use the built-in directives for.
All the elements are similar so let's just take apart this bit. Also if different for a radio and dropdown list maybe we can discuss that too.
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required">The first name is required.</span>
</p>
Do I chain a few directives with || or && ?
Behaviour I'm aiming for
How to keep the error messages off when it loads?
when I hit submit, and a field is blank, will it then activate the css red error messages?
I'd like the error messages to clear as I fill in the form without reloading.
Yeah, so any tips greatly appreciated. Doesn't have to be particularly pretty
Thanks
UPDATE 1
gist of current code
Well I took a stab at it. Still really a hot mess at this point. Don't know how to use submit to test for each field and then display the error message if blank. Also seems like a lot of duplication on the testing of field states. Is there a better way to break up that logic? Ugggghhhhh
UPDATE 2
This one's weird, the form now has all text boxes not buttons or checkboxes!? But the HTML hasn't changed. Sigh
ng-if="identification.firstName.$error.required && !$pristine"
Go search more on $pristine and $dirty validator
You can add some other property to your ng-if and set its value to true only when form is submitted.
in your html add this new property
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required && running">The first name is required.</span>
</p>
in your controller set this property to true when form is submitted
$scope.submit = function(){
$scope.running = true;
...
}
I want to validate two forms. The MAIN form is for e.q. for Company model and second form is for CompanyAddress model.
CompanyAddressForm is inside CompanyForm.
I'm having problems while validating CompanyForm. It depends on CompanyAddressForm validation and I don't want that.
// Main form
<form ...>
<input ... required />
// MODAL
<button submit ... ng-disabled=MainForm.$invalid>
</form>
// Second form is in modal
<form. ..>
<input ... />
<button submit=SecondForm.$invalid />
</form>
// And there is problem.
According to the html5 spec (and the xhtml spec), it is NOT allowed to have another form inside a form:
Content model:
Flow content, but with no form element descendants.
Source: https://www.w3.org/TR/html5/forms.html#the-form-element
Therefore I strongly (!) suggest you to restructure your forms and not put them into each other, as the behavior may vary (across browsers and over time).
handle both forms seperately using different class or id
You cannot have one form inside another...this is a bad programming pract
I have this hidden input in my form
<input type="hidden" ng-repeat="dasBottle in bottles track by $index" value="{{ dasBottle.id }}" name="bottles[]" />
When a button gets clicked, the option currently selected in a select input gets added to the page:
$scope.bottles.push(bottle);
with the correct value and everything is fine.
<input type="hidden" ng-repeat="dasBottle in bottles track by $index" value="30" name="bottles[]" class="ng-scope">
The user can add as many of these as they wish and the value is correct every time.
However, if the user submits the form, but then presses the back button, the same process works, however each new hidden field has the value of the first hidden input added before the form was first submitted, in this case 30. The only way to get it back to normal is to refresh the page.
The scope variable does get set to an empty array when the controller is setup:
$scope.bottles = [];
Any help would be appreciated, thanks.
You might explicitly add index to the array of data you want to form from your form:
bottles[{{ $index }}]
My colleagues on the backend side say that this doesn't change the way data arrives to them, but strange behaviour gets fixed.
I'm trying to implement a multilingual text input field with a little dropdown button to the left for selecting the language. For instance, when the dropdown menu shows 'de' the text field should be bound to model.multilingualData['de'].someField and so on.
My first approach was to set ngModel to model.multilingualData[selectedLanguage].someField. But when the user selects a different language without filling in the field correctly, no error is set on the form, because the model now points to a different object.
My next idea was to create an entire element directive without ngModel, but then I wouldn't be able to do other validations like ngMaxLength.
I couldn't find anything helpful on the web either. Any idea on how to implement this properly?
EDIT
Here's a little fiddle that illustrates the problem: http://jsfiddle.net/FZ2kg/
Not only that the form appears valid when you switch languages, the previous field value is also deleted, because the model is set to null when the field becomes invalid.
would be nice if you use this awesome external directive for multilanguage!
https://angular-translate.github.io/
I hope it helps
If you need to have form validation for all language variations and you're loading all languages at once in your model, can't you just create an input per language in the form and hide all but the currently selected language?
Here's a fiddle: http://jsfiddle.net/jvl70/w3rstmwd/5/
<form name="myForm">
<div ng-repeat="(lang, value) in model.multilingualData"
ng-show="lang==stuff.currentLanguage">
<ng-form name="innerForm">
<div ng-class="{ 'has-error': innerForm.anything.$invalid }">
<input type="text" name="anything" ng-model="value.someField" ng-maxlength="6"/>
</div>
</ng-form>
</div>
</form>
(At first I tried to use dynamic names for each input but found that the individual field $invalid wasn't available for dynamically named inputs. See this post to get around it: Dynamic validation and name in a form with AngularJS.
As an alternative to ng-form, you could use dynamic names for each input and try one of the custom directives on the link.)
I guess if there were many possible languages, this approach might get slower but it's ok for a few languages.
I have a server that is hosting a JSP page. Can I populate it's text boxes from my client's database?
Create a servlet which loads the data, puts it in request scope and forwards the request to the JSP. If you want to do it whenever the client opens a link/bookmark, then do it in the doGet() method. Or when you want to do it when the client submits a form, then do it in the doPost() method.
Here's an example which preloads a specific product from the DB based on request parameter:
Product product = productService.find(request.getParameter("id")); // Do your DB access job.
request.setAttribute("product", product); // It'll be available by ${product}.
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response); // Let JSP display it.
Map this servlet on an URL pattern of /product then you'll be able to call it by http://example.com/somecontext/product?id=123
In the JSP you just have to set the value attribute of the HTML input element to display it as value of the input element. Since this is sensitive to XSS attacks when you print it plain like as suggested in the other answer, you'd like to use JSTL fn:escapeXml() to avoid XSS attacks.
<%#taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<input type="text" name="name" value="${fn:escapeXml(product.name)}" />
<input type="text" name="description" value="${fn:escapeXml(product.description)}" />
<input type="text" name="price" value="${fn:escapeXml(product.price)}" />
Note that scriptlets (those <% %> things) are a poor practice and don't offer instant access to request attributes (i.e. <%= product.getName() %> style as suggested in other answer won't work), nor does it offer standard XSS escaping facility.
Can I populate it's text boxes from my
client's database?
Yes you can.
Steps:-
Connect to database in servlet.
Retrieve data in servlet and pass it to jsp.
Get that data from request in jsp.
Display data in jsp using scriptlet or jstl.
to populate data in text box in jsp use following:
suppose you have User object that holds user's information then ...
<input type="text" value="<%= user.getName()%>" />