0

Models

public class IntegerList
{
    public int IntegerListID { get; set; }
    public string Direction { get; set; }
    public long Performance { get; set; }
    public virtual ICollection<Integer> Integers { get; set; }
}

public class Integer
{
    public int IntegerID { get; set; }
    [Required(ErrorMessage = "An integer is Required")]
    [Range(0, 9999999, ErrorMessage = "Enter an integer")]
    public int IntegerValue { get; set; }
    public int IntegerListID { get; set; }
    public virtual IntegerList IntegerList { get; set; }
}

The above models are for an application that sorts a range of integers into ascending or descending order and calculates the time taken to perform the sort.

The integers are entered into textboxes by the user who can add or remove them using jquery.

I've got the application working by passing formcollection to the controller, splitting the string of integers into an array of integer values to be added to IntegerList.Integers.

However, I'm looking for a more elegant strongly-typed solution.

ViewModel

public class IntegerViewModel
{
    [UIHint("Integers")]
    public IEnumerable<Integer> Integers { get; set; }
    public string Direction { get; set; }
}

Where I'm struggling is adding Integers.IntegerValues to the view so they can be passed to the controller via the viewmodel. I also need to increment/decrement each IntegerValue textbox value as it is added/removed by jquery. I'm not sure I'm approaching this from the right angle.

I hope that's clear. Thanks for your assistance.

Razor

    <form method="post">
        <div id="integers">
            @Html.Label("Enter Integers")
            <div class="integer">
                @Html.EditorFor(model => model.Integers)
                <a href="#" id="addInt">Add Integer</a>
            </div>
        </div>
        @Html.Label("Sort Direction")
        <div>
            @Html.DropDownListFor(model => model.Direction, new[] {
                new SelectListItem() {Text = "Ascending", Value = "Ascending"},
                new SelectListItem() {Text = "Descending", Value = "Descending"}
            })

            <input class="button" type="submit" value="Submit" />
        </div>
    </form>

Editor Template (for Integers)

@model Integer

@Html.EditorFor(m => m.IntegerValue)
user1405195
  • 1,667
  • 4
  • 22
  • 35
  • 3
    Check out Phil Haack's old article on collection binding. Your question isn't quite clear without more code, but this should point you in the right direction: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx – David Fox Oct 04 '13 at 11:18
  • Andrei - Razor added. David - thanks, I'll read that now... – user1405195 Oct 04 '13 at 11:32

1 Answers1

0

Let me summarize everything.

You will not find any strongly-typed solution there as far as you are adding and removing values (integers) using JavaScript (jQuery).

So, when you are adding integer editor using jquery you should render approppriate HTML according to ASP.NET MVC contracts.

David's comment is very valuable. Check out this link. http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

Here you can see how you should render your HTML to receive different types of data on the server (ASP.NET MVC action).

Also you can check your EditorFor output and render HTML like it was rendered using MVC.

And finally, here is the question about dynamic form fields in ASP.NET MVC. ASP.NET MVC Dynamic Forms

Hope this helps.

Community
  • 1
  • 1
Andrei
  • 42,814
  • 35
  • 154
  • 218
  • Thanks Andrei. That did help. The Haacked article solves my problem very simply as I'm using primitive types. Similarly, your knockout solution also works. But both use standard HTML rather than razor. Is that compromise necessary? My EditorFor is naming my inputs "IntegerValues.IntegerValue" and therefore not recognised by ViewModel. Whereas hardcoding the names in HTML as "IntegerValue" binds them to the viewmodel just fine. If I'm not using razor, will I have to validate a different way? Or should I customise the Editor Template to accept the correct name? I sense I'll have to compromise. – user1405195 Oct 04 '13 at 16:23
  • @user1405195, Probably I haven't got everything you are talking about. But looks like you should accept some compromise. Regarding strongly-typed solution and name generation: try to use @Html.NameFor(m => m.Field) or @Html.IdFor(m => m.Field). These helpers might help you a little. And good luck of course. – Andrei Oct 05 '13 at 00:26