Html Helpers in Razor partial view for collections - html

I have - again - a case where I need to put a lot of fields in a partial view in order to be able to add dynamically this partial view in a form.
Up to now, I always made my html markup by hand, so the file looks like:
#{
var collectionId = $"Collection[{Model.CollectionId}].{{0}}";
}
<label for="#(string.Format(collectionId, "FirstName"))">#ApplicationResources.FieldFirstName<span style="color:red"> *</span></label>
<input class="form-control"
data-val="true"
data-val-required="#(string.Format(ApplicationResources.Error_Required, ApplicationResources.FieldFirstName))"
id="#(string.Format(collectionId, "FirstName"))"
name="#(string.Format(collectionId, "FirstName"))"
type="text"
value="#(string.IsNullOrWhiteSpace(Model.FirstName) ? string.Empty : Model.FirstName)" />
<span class="field-validation-valid text-danger"
data-valmsg-for="#(string.Format(collectionId, "FirstName"))"
data-valmsg-replace="true"></span>
And it works well:
If error in post, I can show back the data - they are not lost
I can also display (with edition) previous saved data
But, I have to do all the html markup manually, for every imaginable input type...
So, my question is to know if it is possible to achieve the same html output through #Html helpers (Html.TextBoxFor (or TextBox), DropdownFor, CheckboxFor, ValidationMessageFor etc.), as everything I tested at this point doesn't work for viewmodel's attributes validation?

Related

ui-bootstrap datetime-picker define show-meridian to false

I'm using ui-bootstrap-datetime-picker with angularJS. And i'd like to know if it's possible to set show-meridian options of time-picker directly inside timepickerOptions ?
...
<input type="text" class="form-control"
datetime-picker="MM/dd/yyyy HH:mm"
timepickerOptions="{'show-meridian': 'false'}"
ng-model="ctrl.date.value"
is-open="ctrl.date.showFlag"/>
<span class="input-group-btn"></span>
...
This is a plnkr which illustrate the problem.
Root cause of the problem is wrong naming style. To make your code work, you have to change camel-case to dash-delimited: timepicker-options instead of timepickerOptions (see my forked plunker):
<input type="text" class="form-control"
datetime-picker="MM/dd/yyyy HH:mm"
timepicker-options="{'show-meridian': false}"
ng-model="ctrl.date.value"
is-open="ctrl.date.showFlag"/>
The key point here is normalization process being done by AngularJS. Since HTML is case-insensitive, AngularJS cannot convert HTML attribute named timepickerOptions into scope variable timepickerOptions - because timepickerOptions in HTML is seen by AngularJS exactly like timepickeroptions; so, there is no chance for it to determine how to normalize this name. Thus, you should always use -, _ or : to delimiter different words in directive name when using HTML.

Request.Form works only on name tags?

I am developing a very simple data entry application (in bootstrap) using ASP.net and VB.Net as code behind in Visual Studio 2012 web.
Suppose that i have the following html to get the firstname:
<form id="form1" runat="server">
<div style="padding:20px">
<div class="form-group">
<label for="firstname">Firstname</label>
<input type="text" class="form-control" id="firstname" name="firstname" placeholder="" style="max-width:450px" maxlength="60" />
<small class="text-muted">Enter your first name.</small>
</div>
<button runat="server" type="submit" class="btn btn-primary" onserverclick="btnSubmit_ServerClick" >Submit</button>
</div>
</form>
and the corresponding code behind to handle its value:
Protected Sub btnSubmit_ServerClick(sender As Object, e As EventArgs)
Dim fname As String = Request.Form("firstname").ToString
End Sub
Suppose that I don't want to use runat="server" in my html firstname field.
I see that Request.Form("firstname").ToString only works when I have set the tag name="firstname". If I have set only the id tag (and NOT the name tag) it does not take it into account; in my case if I have only <input type="text" class="form-control" id="firstname" placeholder="" style="max-width:450px" maxlength="60" /> the Request.Form("firstname") in my server side, returns NULL.
I also try Request.Form with no luck. I see that the collection NameValueCollection is filled by components that have set only the name tag.
And my question is, is it possible to change my server code in order to work with html components that they have set their ID only?
When you opt out of using server-side controls, you're left with the Request collection method of reading the values.
The code behind will only be able to read the data sent to the back-end. If you inspect your request (the page requested when you submit the form) in the Network tab of your favorite browser, you will find a section showing the data sent. And since you're not setting a name on that input field, the data is NOT sent to the server. That is why you cannot read it. The ID has no impact on what is sent to the server. The ID is ment only for client-side useage. The reason it "works" when you add Runat="server" is because the framework add information to the secret hidden input field named "__VIEWSTATE" (or something).
So in the end, the way HTML works, when you submit a form, all input elements are sent in the form name=value and since you omit the name, no data is sent.
Like the comments below your post suggests, you really should consider using the server-side controls (runat="server") or add the name tag to your form elements.
I know a lot of people don't like asp.net webforms (actually i'm not a fan either), but there are other alternatives - a logic shift would be to move to asp.net mvc instead. Whatever you do, if you opt out of the framework specifics you have to comply with the html5 standart.
Good luck :)

Angular/bootstrap show specific form validation message

I'd like to have a required email input on a form, and I'd like to augment the input's label to show validity with specific messages. I tried the markup below (simplified, and a few variants). The actual can be found at this fiddle illustrating the problem.
<label for="email">Email
<small class="help-inline" ng-show="form.email.$invalid-required"> (required)</small>
<small class="help-inline" ng-show="form.email.$invalid-email"> (email)</small>
</label>
<div class="input-group">
<input type="email" placeholder="Email" name="email"
ng-model="model.email" required>
I'd like the 'required' message to appear when the input is empty, and when it's non-empty, I'd like the 'email' message to appear conditionally if angular email validation passes.
As you'll see in the fiddle, both messages appear and disappear together, even though, as I use the chrome inspector, the $invalid classes on the input seem to change appropriately. This casts suspicion on the ng-show expression for the errors, but no matter what I try there I get the same behavior.
I've seen a couple answers (like this one) that use a lot of code, but that answer seems a little roundabout. I'm new to web, and already appalled by how bulky the html/code can get (each time I learn about a new streamlining idea, mine seems to double in size)
Thanks in advance.
Change the expression for required to
<label for="email">Email <small class="help-inline" ng-show="!form.email.$viewValue">
and it would work.
The problem with Angular is that it does not allow invalid data in the model. So unless you provide a valid email value the linked model property remains empty and both the required and email validation fail.

how to preserve textbox data in jsp even after clicking the refresh button

this is my jsp page
<html>
<body>
<span>User name:</span> <input type="text" name="Teachername" value="<%=request.getParameter("name") %>" class="input_panel" id="Username" readonly/><br><br><br>
<span>Old password:</span> <input type="password" name="TeacherOpwd" class="input_panel" id="TeacherOpwd" /><br><br><br>
<span>New password:</span> <input type="password" name="TeacherNpwd" class="input_panel" id="TeacherNpwd" /><br><br><br>
<input type="submit" id="TeacherSubmit" name="submit" class="submit_button" value=" " />
</body></html>
i need, whatever i write on the textbox remain unchanged after refreshing the page.
please help..
You can't. That's not how HTML/JSP works. If you want to do something like this you should look at implementing some form of MVVM pattern, or using a framework which supports it. (ZK, AngularJS or KnockoutJS).
For more information, read the Wikipedia article on MVVM
For your requirement, data must be preserved for later availability after refresh.
So, as and when you write, there must be some way which is doing the work of storing in background, so that when refresh happens, it can take the data from stored place.
I have not found requirement like this before but can think like you can go with Ajax for this and once you get the data at server, try storing it in cookie and when refresh happens, first try to read from cookie if available or else show blank.
Also, check is there any way you can store it at javascript level, as I am not aware of that.
use HttpSession session = request.getSession(); session.setAttribute("someItem")
after you click the button. It should still be there.

In an ASP.NET MVC 3 view, how can I generate an editor for a list field?

I am creating a form in an ASP.NET MVC 3 view, in which one field is to specify a list of ints (corresponding to List<int> in the edited model). How can I generate this editor field in my view? I assume there are MVC 3 helpers I can make use of.
If you want a dropdownlist you can use the HTML.DropDownList helper method. Is this what you want or do you need to display the List as an Ordered/Unordered HTML list?
EDIT
You can create your own HTML Helper function. Assuming you use Razor you can follow the following steps
1.)Create a new .cshtml file inside App_Code directory and name it as you want (for example HTMLHelpers.cshtml)
2.)Write the following in the file
#helper OrderedList(List<int> list) {
<ul>
#foreach (var item in list)
{
<li>#item</li>
}
</ul>
}
3.)Now in your view you can call your new function. For example write
#HTMLHelpers.OrderedList(Model)
2nd EDIT
You can also use Javascript to achieve that functionality. Knockout.js from Steven Sanderson is a great library that helps you to databind values to html elements.
This sample from knockout.js documentation is similar to your needs.
You can also view this blog post from Steven Sanderson that explains how to use Knockout.js with a variable length list and how to submit the list data back to server.
Phil Haack's blog post discusses every aspect of using model binding to a list: controller code, view code, complex and primitive types, dictionary binding. From the first paragraph of that blog post, MVC builtin model binder binds List with just passing number of same named query string (or form when posting) parameters to controller. Example
<form method="get">
<input type="checkbox" name="ints" value="1" />
<input type="checkbox" name="ints" value="4" />
<input type="checkbox" name="ints" value="2" />
<input type="checkbox" name="ints" value="8" />
<input type="submit" />
</form>
This would bind correctly to
public ActionResult UpdateInts(List<int> ints) {
return View(ints);
}
See that blog post for the complete information