I understand with built in function to render UI controls like
#Html.TextBoxFor(model => model.CustomerId)
#Html.ValidationMessageFor(model => model.CustomerId)
The rendered Html will look like
<input data-val="true" data-val-number="The field CustomerId must be a number." data-val-required="The CustomerId field is required." id="CustomerId" name="CustomerId" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="CustomerId" data-valmsg-replace="true"></span>
All the attributes inside input elements are used to support unobtrusive validation feature.
But for some reason I cannot render by using Html helper, but I have to hand code Html markup like
<select id="MyId" name="MyId" />
<%=Html.ValidationMessageFor(model => model.MyId)%>
In this case how can I still make unobtrusive validation word without hard code all these attributes in select element?
Thanks
Hardy
Unobtrusive validation relies completely on this attributes to determine which validation it will apply to the element, you will have to hard code them in your html is you dont want to use the helper, just make sure the name attribute of you select tag is equal to the property name it binds to.
Related
I'm building a view with Thymeleaf templates, which contains a form that provides a way to bind the value of my inputs with the attributes passed in the model. The backend was developed using Spring 4.
The following snippet includes an autocomplete datalist with the data of the namelist object, which was added to the model as an attribute. Said namelist is an ArrayList of a class with the fields int id and String name.
<form th:action="#{/}" method="POST" th:object="${example}">
<div class="form-group">
<input list="names" class="form-control" id="nameinput" th:field="${example.num.id}"> </input>
<datalist id="names">
<option th:each="row : ${namelist}" th:value="${row.id}" th:label="${row.name}">
</datalist>
<button>submit</button>
</div>
</form>
The value of the selected option is already bound to example.num.id, which is the expected and desired behaviour. However, when loading the view on a web browser (tested on latest Firefox and Chrome), it is represented like this:
As you can see, the id's are showing. However, I'm trying to emulate the behaviour of a <select>; the value should not be shown, just the text or label.
Is there a better way to achieve this? Am I not using the datalist properly?
I have a View in ASP.NET Core application where I have a form:
<div class="form-group">
<label asp-for="#Model.Property" class="col-md-2 control-label">Description</label>
<div class="col-md-10">
<textarea asp-for="#Model.Property" class="form-control" rows="10" data-val-maxlength-max="1000"></textarea>
<span asp-validation-for="#Model.Property" class="text-danger" />
</div>
</div>
I want to make textarea empty and Not to have the value from Model. I don't see any value property on this textarea.
Is it possible to have textarea mapped to #Model.Property but Not display it?
I'll be using this textarea for POST only and I don't want to display anything for GET. But I want to have other properties fetched so that's why I need the model in GET.
I also tried to change the Model property in controller before sending, but this model is a part of a DBSet and if I modify in controller then the DBSet gets affected.
Javascript is another option but I want to avoid that.
I had a look at How to overwrite one model property in ASP.Net core but this is not convincing.
Thank you.
In my MVC project I'm using an ajax form to dynamically update some search results based on a modified search term.
When rendering the Ajax.BeginForm() Method, it doesn't render a <form> tag on the page (in the DOM)
everything is set up fine, Jquery, Unobtrusive and AJAX are all referenced and I have working Ajax.BeginForm instances elsewhere
#using (Ajax.BeginForm("FilterSearch","Attachment", new AjaxOptions()
{
OnComplete = "updateSearchResults",
HttpMethod = "POST"
},new{}))
{
#Html.HiddenFor(model => model.AccountId)
#Html.HiddenFor(model => model.ContactId)
#Html.HiddenFor(model => model.OpportunityId)
#Html.TextBoxFor(model => model.SearchTerm, new { placeholder = "Search Term", #class = "header-search-box" })
<input type="submit" class="header-search-input" />
}
is just rendering inside the DOM as
<input id="AccountId" name="AccountId" type="hidden" value="">
<input id="ContactId" name="ContactId" type="hidden" value="">
<input id="OpportunityId" name="OpportunityId" type="hidden" value="O6UJ9A001TB1">
<input class="header-search-box" id="SearchTerm" name="SearchTerm" placeholder="Search Term" type="text" value="">
<input type="submit" class="header-search-input">
Things to try (generally speaking):
Examine your source code (and not what the DOM is interpreting).
The DOM is based on how a browser/HTML parser interpreted the page, and now how it may actually be output. (Invalid markup will generally be suppressed, to the best of the parser's ability, and won't show up in debug tools, but will still sit on the page).
Confirm you don't have any markup mis-aligned.
Razor is smart enough to detect invalid markup, and may be cleansing output (and fixing a potential mistake), but not in a manner you were expecting.
Given this is dynamic content, make sure you're not nesting forms.
Ajax.BeginForm (and the other form helpers) supply <form>/</form> tags regardless; It's in the ctor/de-ctor methods to output those tags.
Some kind of post-processing (on the side of the AJAX processor) may be "cleansing" the output to avoid invalid HTML (e.g nested form tags). If it sees there's already a <form>, it may strip that tag from any supplemental markup being brought in.
You cannot make a form inside another form. Check your parent views to make sure you haven't accidentally started a form, and then included this partial page.
(Thanks for the tip #LiamHT)
I'm trying to validate that a radio button has been selected via server side in ColdFusion. The text input errors out if empty, however, the radio button group does not trigger an error if none are selected. I cannot seem to find any documentation on this.
<cfform name="mobile_device_request" id="form" action="">
Text Box:
<cfinput type="Text" name="subscriber" message="Please enter in a subscriber" required="yes" validateat="onserver">
Subscriber:
<cfinput type="Radio" name="service_provider" value="AT&T" required="yes" validateat="onserver"><span class="label">AT&T</span>
<cfinput type="Radio" name="service_provider" value="Sprint" required="yes" validateat="onserver"><span class="label">Sprint</span>
<cfinput type="Radio" name="service_provider" value="Verizon" required="yes" validateat="onserver"><span class="label">Verizon</span>
Explanation:
To answer your question, while I have never used that feature, I would say it is a bug.
According to the documentation onServer validation works by automatically appending hidden form fields with a special naming convention. The CF server then inspects all requests for certain patterns in form field names, such as ones ending in _required or _cfformrequired, and if found performs validation on the related field.
If you view the source of your cfform, notice CF has added several hidden fields:
<input type='hidden' name='subscriber_CFFORMREQUIRED' value='Please enter in a subscriber'>
<input type='hidden' name='service_provider_CFFORMREQUIRED' value='Error in service_provider text.'>
<input type='hidden' name='service_provider_CFFORMREQUIRED' value='Error in service_provider text.'>
<input type='hidden' name='service_provider_CFFORMREQUIRED' value='Error in service_provider text.'>
Those should trigger CF's server side validation for both fields. However, as you discovered it only works with the text field, not the radio buttons. Though curiously, it works just fine if you manually add a hidden field ending in _required:
<input type="hidden" name="service_provider_required"
value='You forgot to select a service_provider'>
Answer:
Again, I think the behavior you are seeing may be a bug. Frankly, one of many with cfform. Personally, I would recommend ditching cfform/cfinput. Use plain html inputs and write your own validation instead. Since it is a radio button, the field will only be defined if one of the buttons was checked. So you can either test for the existence of the field:
<cfif NOT structKeyExists(FORM, "service_provider")>
no service_provider selected. do something
</cfif>
... OR assign a default, and test for that value:
<!--- default to empty string --->
<cfparam name="FORM.service_provider" default="">
<cfif NOT len(FORM.service_provider)>
no service_provider selected. do something
</cfif>
I am using MVC3 and my view has a mixture of razor and raw html in my view e.g.
<div class="editor-field">
#Html.EditorFor(model => model.PAGE)
#Html.ValidationMessageFor(model => model.PAGE)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.PERIODICAL)
</div>
div class="editor-field">
<div class="editor-field">
<input type="text" id="periodicallist" name="tiperiodical" />
</div>
</div>
My JavaScript applies the tokenInput control plugin to the textbox and its all fine, but I wonder how I can validate this (i.e. for empty textbox/tokenInput), it needs to filled with at least 1 token. At the moment it's confusing having these two forms of creating a view, letting Razor constuct elements direct from the model, and then adding more complexity/cusomization by usin jQuery plugins etc.
Can anyone advise how I can validate jQuery plugins on posting back to the controller?
Cheers
If you are using unobtrusive validation then you all have to do is add the necessary HTML5 data attributes to the input elements from javascript and microsoft's unobtrusive javascript library will take care of the rest.
For ex. if you have dynamically injected a textbox into the form through javascript and you need to perform required validation then all you have to add the data-val and data-val-required attributes as below.
<input data-val="true"
data-val-required="No. of joinees is required"
name="NoOfJoinees"
type="text" />
EDIT:
To display the validation error message you have to inject a span near to the field,
<span class="field-validation-valid"
data-valmsg-for="NoOfJoinees"
data-valmsg-replace="true">
</span>