MVC5 Lost value in Textbox after Submit - razor

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/

Related

The right way to pass a input to the typescript file

I know about this way to send a input from the user to the typescript (angular) :
<form >
<input #input type="text" [(ngModel)]="inputColor" (input)="sendInput(input.value)" />
</form>
But its looking for not very effective , i create a reference to the DOM with #input and after that send the input.value .
After all, I am very confused about the input.value does he refer to #input or to to (input)=...;.
Bottom line, is there a more efficient way to pass the value the user puts into the box, into the typescript file and then use it for another tag in the HTML file?
For example the user put a size of text and i want to use with the use on another tag on HTML ....
I think you are trying to use angular input inside a html input tag, which is not possible.
You need to use a keyboard event handler like "keyup", "keydown"...
<input type="text" [(ngModel)]="inputColor" (keyup)="sendInput($event)" />
If i understand well, you re looking for $event ?
<input #input type="text" [(ngModel)]="inputColor" (input)="sendInput($event)" />
typescript side:
sendInput($event) {
console.log('input value:', $event.data);
}
But $event.data will only contain the last typed char, is it what you re looking for ?.
EDIT:
With (input), you can have the content of input in $event.target.value:
<input #input type="text" [(ngModel)]="inputColor"
(input)="sendInput($event.target.value)" />
First of you you have used ngModel with input, so your inputcolor will have that value, and you can use it. But if you want it passed to a method you can do it like :-
<input type="text" [(ngModel)]="inputColor" (change)="sentInput($event.target.value) />
Change event will be fired as soon as user is done typing and click anywhere else.
then have a sendInput method in ts to copy received value in a property
public sendInput(value) {
this.data = value;
}
OR
If you don't need two way binding, you can use ngModel for one way binding as well like :-
<input type="text" (ngModel)="inputColor" />
After this typescript value change will not impact, only change in template will be reflected in typescript variable.

what is the proper way to dynamically mark a field as required using Angular 2 Forms?

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.

How to add default values to input fields in Thymeleaf

I am programming in Spring and using Thymeleaf as my view, and am trying to create a form where users can update their profile. I have a profile page which lists the user's information (first name, last name, address, etc), and there is a link which says "edit profile". When that link is clicked it takes them to a form where they can edit their profile. The form consists of text fields that they can input, just like your standard registration form.
Everything works fine, but my question is, when that link is clicked, how do I add the user's information to the input fields so that it is already present, and that they only modify what they want to change instead of having to re-enter all the fields.
This should behave just like a standard "edit profile" page.
Here is a segment of my edit_profile.html page:
First Name:
Here is the view controller method that returns edit_profile.html page:
#RequestMapping(value = "/edit", method = RequestMethod.GET)
public String getEditProfilePage(Model model) {
model.addAttribute("currentUser", currentUser);
System.out.println("current user firstname: " + currentUser.getFirstname());
model.addAttribute("user", new User());
return "edit_profile";
}
currentUser.getFirstname() prints out the expected value, but I'm getting blank input values in the form.
Thanks.
Solved the problem by removing th:field altogether and instead using th:value to store the default value, and html name and id for the model's field. So name and id is acting like th:field.
I'm slightly confused, you're adding currentUser and a new'd user object to the model map.
But, if currentUser is the target object, you'd just do:
<input type="text" name="firstname" value="James" th:value="${currentUser.firstname}" />
From the documentation:
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
I did not have a form with input elements but only a button that should call a specific Spring Controller method and submit an ID of an animal in a list (so I had a list of anmials already showing on my page). I struggled some time to figure out how to submit this id in the form. Here is my solution:
So I started having a form with just one input field (that I would change to a hidden field in the end). In this case of course the id would be empty after submitting the form.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:field="*{id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
The following did not throw an error but neither did it submit the animalIAlreadyShownOnPage's ID.
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>
In another post user's recommended the "th:attr" attribute, but it didn't work either.
This finally worked - I simply added the name element ("id" is a String attribute in the Animal POJO).
<form action="#" th:action="#{/greeting}" th:object="${animal}" method="post">
<p>Id: <input type="text" th:value="${animalIAlreadyShownOnPage.id}" name="id" /></p>
<p><input type="submit" value="Submit" /> </p>
</form>

Html.CheckBoxFor renders two inputs Which becomes an issue In Form Post

My code is like this
<div class="form-group" style="padding-top: 30px;">
#Html.CheckBoxFor(model => model.IsVatPaidByInsurer)
</div>
Inside Model Class
public bool IsVatPaidByInsurer { get; set; }
Inside Controller
public ActionResult Create([Bind(Include = "PayerID,Name,CreatedDate,PayerTypeSelected,ReferingInstitute,ApplicationUserId" +
"IsVatPaidByInsurer,PatientContribution")] Payer payer)
I expect this line of code to generate a checkbox on front end, But how it renders is like this (value not true, it's I just checked the checkbox)
<div class="form-group" style="padding-top: 30px;">
<input data-val="true" data-val-required="The IsVatPaidByInsurer field is required." id="IsVatPaidByInsurer" name="IsVatPaidByInsurer" type="checkbox" value="true">
<input name="IsVatPaidByInsurer" type="hidden" value="false">
</div>
As you can see there is two inputs with same name generated (IsVatPaidByInsurer).
And second one's value always false. So when I make my form post I can't get the real value of checkbox.It will interpret always as false there. Can anyone Tel me what This is whole about? and a way to overcome this?
The 2 inputs are correct (and without the hidden input you could get incorrect values). If the checkbox is checked, true, false is posted back and the DefaultModelBinder sets the model value to true (the second value is ignored). If the checkbox is unchecked false is posted back (unchecked checkboxes do not post back) so the model property is set to false

Checkboxes in MVC not functioning correctly

Ok, I posted a question on stackoverflow regarding checkboxes that had a nullable view model parameter and was told this wouldn't work. I've substantially reworked my application to support a non-nullable view model parameter so I'm ready to ask my question again.
I have a checkbox in my application, like this:
#Html.CheckBoxFor(m => m.IsNonUk)
which renders in the browser like this:
<input data-val="true" id="IsNonUk" name="IsNonUk" type="checkbox" value="true" />
<input name="IsNonUk" type="hidden" value="false" />
Inspecting the element in Chrome reveals this markup:
<input data-val="true" id="IsNonUk" name="IsNonUk" type="checkbox" value="">
<input name="IsNonUk" type="hidden" value="">
My action has this signature:
public ActionResult CreateSelfPay(CreateSelfPayViewModel viewModel)
and my CreateSelfPayViewModel view model contains this property:
public class CreateSelfPayViewModel : ViewModel
{
// ..
[DisplayName("Is non-UK")]
public bool IsNonUk { get; set; }
// ..
}
The problem is that no matter what I do to the checkbox the values posted back to the server are both null which results in a false value in the view model. I have checked this with Fiddler.
What is going on? Why can't I get a true value if the box is checked?
I hope someone can help!
== More information ==
The application is using various libraries such as jQuery, jQuery validate, jQuery UI and Bootstrap. Perhaps one of these is fiddling with the input values since they are null when inspected with the developer tools. Does anyone know of any issues in this respect?
M