re-display all form input before post - c#

Before some people start yelling, I realize there is similar questions up, but their all dealing with single entries...
I have a long form and want to use a generic method of dealing with the re-displaying of data.
Please note : this is an asp.Net MVC 4 application using razor2 views
Example of one of the fields,
<div class="control-group">
<label class="control-label">#Html.LabelFor(m => m.Name)
<span class="required">*</span>
</label>
<div class="controls">
#Html.TextBoxFor(m => m.Name, new { #name = "nameInput" })
</div>
</div>
My think was to add an ID to each Textbox...
Example of how is might be displayed on the confirmation view..
<div class="control-group">
<label class="control-label">Name:</label>
<div class="controls">
<span class="text display-value" data-display="nameInput"></span>
</div>
</div>
Then render that value using data-display with the ID...
jQuery that I thought would deal with it...
var displayConfirm = function() {
$('.display-value', form).each(function(){
var input = $('[name="'+$(this).attr("data-display")+'"]', form);
if (input.is(":text") || input.is("textarea")) {
$(this).html(input.val());
} else if (input.is("select")) {
$(this).html(input.find('option:selected').text());
}
});
}
Unfortunately this does not appear to be working correctly....
Can anyone point out / re-solve the issue ?

Got it, I needed to use the name in the model rather then assigning names.
Got correct names from "page view source", and simply plugged that value into data-display tag.

Related

Posting a list with a missing number within the list [duplicate]

This question already has answers here:
MVC3 Non-Sequential Indices and DefaultModelBinder
(6 answers)
Closed 3 years ago.
I have a form whereby I post a list of information.
So the list can be like so.
Person[0].FullName
Person[0].Address
Person[1].FullName
Person[1].Address
Person[2].FullName
Person[2].Address
Person[3].FullName
Person[3].Address
When I POST this information and run my update comment, it all works fine. The List<> model comes back with 4 records.
However, when I remove one of the middle records using jQuery, it removes the whole line from the HTML. So I end up with, for example, the scenario below.
Person[0].FullName
Person[0].Address
Person[2].FullName
Person[2].Address
Person[3].FullName
Person[3].Address
But now when I POST the information, the List<> count is now 1, because it's ignoring everything after the removal. I'm guessing it's because the List is now not sequential?
Has anyone come across the same issue before and know a way to save all items?
Thanks
EDIT - HTML
for (int i = 0; i < Model.PersonsViewModel.Count(); i++)
{
<div id="clone_#i" class="form-group clone">
<div class="col-sm-6 has-feedback">
<div class="row">
<div class="col-sm-12">
#Html.TextBoxFor(model => model.PersonsViewModel[i].FullName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.PersonsViewModel[i].FullName)
</div>
</div>
</div>
<div class="col-sm-6 has-feedback">
<div class="row">
<div class="col-sm-12">
#Html.TextBoxFor(model => model.PersonsViewModel[i].Address, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.PersonsViewModel[i].Address)
</div>
</div>
</div>
</div>
}
Because you are breaking List chain and it lost index of list .Maybe you can try controller-side edit.I met this issue in the past and fix it in controller.

Problem preventing evaluation of AngularJS expression when bound with ng-model

I have a problem with a web page that is rendered using the ASP.NET MVC (5.2.3) razor engine but which also uses AngularJS (1.7.4). The problem is that what should be rendered as plain text is being evaluated by AngularJS.
So, for example, in our model we have a property Name that when the value is, for example, {{1 + 1}} is being displayed as 2 i.e. the AngularJS expression is being evaluated:
The (redacted) cshtml page is along the following lines:
#model Models.SomeViewModel
<div ng-controller="RuleController" ng-form="ruleForm" novalidate>
<!-- stuff here -->
<div class="panel">
<div class="panel-heading">
<!-- stuff here -->
</div>
<div class="panel-body ng-cloak">
<!-- stuff here -->
<div class="row form-group">
#Html.LabelFor(model => model.Name, new HtmlAttributeBuilder().WithCssClass("col-sm-1 control-label"))
<div class="col-xs-12 col-sm-10 col-md-11 pull-right">
#Html.TextBoxFor(model => model.Name, new HtmlAttributeBuilder().WithCssClass("form-control form-group-margin").WithNgModel("viewModel.name").WithNgChange("updateName(viewModel.name)").WithRequired())
<span id="name-error" class="text-danger error-text" ng-model="errors.viewModel.Name">{{errors.viewModel.Name}}</span>
</div>
</div>
The C# class that is referenced in the Razor view - HtmlBuilder - inherits from `Dictionary'
[Serializable]
public class HtmlAttributeBuilder : Dictionary<string, object>
{
public HtmlAttributeBuilder WithCssClass(string cssClassName)
{
this.Add("class", cssClassName);
return this;
}
public HtmlAttributeBuilder WithNgModel(string property)
{
this.Add("ng-model", property);
return this;
}
public HtmlAttributeBuilder WithNgChange(string val)
{
this.Add("ng-change", val);
return this;
}
}
Interestingly, when I look at the value of $scope.viewModel.name in the RuleController I can see that it is {{1 + 1}} and not 2.
I have tried using ng-non-bindable and while it prevents evaluation of the Angular expression it also prevents persisted updates to the value as it removes two-way binding.
Have you tried this directive?
https://docs.angularjs.org/api/ng/directive/ngNonBindable
Note, this should probably go in the comments, but I don't have enough reputation.

Passing value of an input control to controller

I have the following:
#Html.BeginForm("AddComment", "Shared", new { guid = Model.VideoGuid, content="", userid = authenticatedUserId.ToString()}){
<div class="input-group">
<input name="txtCommentContent" type="text" class="form-control"><span class="input-group-btn">
<button class="btn btn-default">
<img src="~/Content/images/Message-Add.png" /></button>
</span>
</div>
}
I need to pass the text input inside the input control to the control as part of the routeValues. The above content="" is going to do that.
How can this be done?
You should be using the HTML Helpers:
#Html.EditorFor(m => m.CommentContent);
This will model bind the value in CommentContent (Which should be a property in your model) and pass it back up to the server when the form is POSTED.
As an alternative solution, you can also serialize the form and pass it up via AJAX.
As #Ic has pointed out you could also use:
#Html.TextBoxFor(m => m.CommentContent, new { #class = "form-control" });
Which will change the input type to text and also add your CSS class form-control.

Adding jQuery to forms with the same model in MVC3

I am trying to have two submission forms with similar functionality on the same view, where each form is strongly typed to the same model. I then am trying to add a datepicker to the same input on both forms, but I am unsure of how to do this. Here is my code:
#using (#Ajax.BeginForm(...
new { id = "editScheduleForm" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.StartTime)
</div>
<div class="editor-field">
<input
#Html.EditorFor(model => model.StartTime)
#Html.ValidationMessageFor(model => model.StartTime)
</div>
}
...
#using (#Ajax.BeginForm(...
new { id = "addScheduleForm" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.StartTime)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StartTime)
#Html.ValidationMessageFor(model => model.StartTime)
</div>
}
Both of these forms are in their own strongly-typed partial views. I naturally tried simply adding the datepicker in jQuery to both partial views, like so:
$(function () {
$("#StartTime").datepicker();
});
But it unsurprisingly only worked for one of the inputs. I have been trying to use the HTML id that I added to both Ajax form declarations (e.g. editScheduleForm and addScheduleForm), but am unsure of how to do this. Any suggestions?
Solution:
As scottm suggested, I looked through documentation for using a custom editor template. I read this, detailing functionality I didn't know existed:
http://msdn.microsoft.com/en-us/library/ee407399.aspx
Here, you can specify a template, and then add a parameter for the htmlFieldName, which is specifically designed to circumvent the problem I was happening.
You can add a class to the inputs in your editor template. Then you can then use the class as the jQuery selector.
Add a file called DateTime.cshtml under ~/Views/Shared/EditorTemplates, and add the following:
#model DateTime
#Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { #class = "date" })
Then add this jQuery to the page.
$(function () {
$(".date").datepicker();
});
The ID must be unique in a document.
Never rely on multiple ids on a page working correctly. Matter of fact, despite what most examples in blogs do, you should hardly ever use ids as jquery selectors.
Like #scottm said. You should use classes to tag items which you want to be widget-ized.
Here's a simplistic bit of code so you can create jq ui widgets declaratively:
$(function() {
$('[data-usewidget]').each(function() {
var $this = $(this), widget = $this.data('usewidget');
$.fn[widget] && $this[widget]();
});
});
Then in your html
<input name=startTime data-usewidget=datepicker />

MVC3 Passing Model to Controller - Receiving Null values

I just started working with MVC3 a few weeks ago and being young in the programming ladder I'm still learning quite a bit. I've recently been working with Models, using TextBoxFor and other helpers to populate properties for my "Character" Model.
Essentially what I'm trying to do is define a model and then pass it to my controller, however any property that I have defined as a static value in my Model is being passed as a null value on runtime.
Below are some snippets of the parts needed to understand whats going on..
Character.cs - Model
// Instances of manipulated objects.
otReal db = new otReal();
public player newPlayer = new player();
public byte[] conditions
{
get
{
return newPlayer.conditions;
}
set
{
byte[] array1 = null;
array1 = new byte[16 * 12 * 3];
newPlayer.conditions = array1;
}
}
CharacterController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Submit(Character c)
{
// Add a new character to the database via LINQ to Entities.
otReal.AddToplayers(c.newPlayer);
otReal.players.AddObject(c.newPlayer);
otReal.SaveChanges();
return View();
}
The only helpers I have in my View are the ones that the user actually needs to interact with. If I go into my controller and set the values there they will get set to the correct value and it will insert. Any help would be greatly appreciated!
Index.cshtml - View
#using (Ajax.BeginForm("Submit", new AjaxOptions { OnComplete = "done" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>New Character Information</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name, "Character Name")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.TownList)
</div>
<div class="editor-field">
#* #Html.DropDownList("TownList", ViewData["TownList"] as SelectList)*#
#Html.DropDownListFor(model => model.TownList, ViewData["TownList"] as SelectList)
#Html.ValidationMessageFor(model => model.TownList)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Sex)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Sex, ViewData["sex"] as SelectList)
#Html.ValidationMessageFor(model => model.Sex)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Vocation)
</div>
<div class="editor-field">
#Html.DropDownList("VocList", ViewData["VocList"] as SelectList)
#Html.ValidationMessageFor(model => model.Vocation)
</div>
<p>
<input id="button" type="submit" value="Create" />
</p>
<div style="font-family: Tahoma; font-size: large" id="completeDiv" style="display: none;">
</div>
<span></span>
</fieldset>
}
Basically what I'm trying to do here is create my model that has a bunch of base values that every 'Character' will have in the database table. This way when a player creates his/her character he/she will be able to enter a Character Name, Sex, Class(Vocation), Starting Town and all the other values will be populated behind the scenes and passed to the controller for creation.
Assuming you're trying to set values on 'newPlayer', then you can replace this
public player newPlayer = new player();
with this
public player newPlayer { get; set; }
The default model binder will create everything from the form on post-back--there's no need to instantiate it in the model.
Created a constructor for my model and inside the constructor I set the default values via the newly instantiated player model. Temp fix until I read into ataddeini's solution. Thanks everyone!

Categories