lundi 2 février 2015

How to properly connect a list from the view to the controller using a Model


I want to have a form that allows the user to fill in a number of fields that should be condensed to an object when the controller receives them. I'm having trouble finding the words to explain this so let me give the example.


Basically there are six fields in this object (AllocationInformation), which is a part of the model:



AllocationInformation
{
FundSource
Function
Location
Program
Subject
Object
}


Now the model has a List<AllocationInformation> in it. The view will allow the user the create an arbitrary number of Allocation objects.


So there are six fields in the form, and a button that let's the user add another of the same six fields as many times as they want.


The view also needs to be able to render these objects if they already exist in the model. I can make all this work, but it's ugly as sin, and I'm hoping to find a better way.


Currently my view is like this:



<button type="button" class="btn btn-primary" onclick="addAllocation()">Add Allocation</button>
<div class="row">
<div id="allocationsDiv" class="container">
<div class="row">
<div class="col-sm-1" id="fundSourceCol">FundSource</div>
<div class="col-sm-1" id="functionCol">Function</div>
<div class="col-sm-1" id="locationCol">Location</div>
<div class="col-sm-1" id="programCol">Program</div>
<div class="col-sm-1" id="subjectCol">Subject</div>
<div class="col-sm-1" id="objectCol">Object</div>
<div class="col-sm-1" id="removeCol">Remove?</div>
</div>



@if (Model.Allocations != null)
{
for (int i = 0; i < Model.Allocations.Count; i++)
{
<div>
@Html.TextBoxFor(m => m.Allocations[i], new { @class = "form-control input-xsmall" })
</div>
}
}
</div>
</div>


Here's the javascript for addAllocation():



function addAllocation()
{
var $row = $("<div class='row'></div>");

$("#allocationsDiv").append($row);

var fundSource = "<div class='col-sm-1'><input type='text' name='Allocation.FundSource' class='funding-source-item form-control' /></div>";

$row.append(fundSource);

var func = "<div class='col-sm-1'><input type='text' name='Allocation.Function' class='funding-source-item form-control col-sm-1' /></div>";

$row.append(func);

var location = "<div class='col-sm-1'><input type='text' name='Allocation.Location' class='funding-source-item form-control col-sm-1' /></div>";

$row.append(location);

var program = "<div class='col-sm-1'><input type='text' name='Allocation.Program' class='funding-source-item form-control col-sm-1' /></div>";

$row.append(program);

var subject = "<div class='col-sm-1'><input type='text' name='Allocation.Subject' class='funding-source-item form-control col-sm-1' /></div>";

$row.append(subject);

var object = "<div class='col-sm-1'><input type='text' name='Allocation.Object' class='funding-source-item form-control col-sm-1' /></div>";

$row.append(object);

var $remove = $("<div class='col-sm-1'><i class='glyphicon glyphicon-remove glyphicon-clickable col-sm-1 funding-source-item'></i></div>");

$remove.on('click', function () {
$row.remove()
});

$row.append($remove);



}


And here's where the rub comes in. The addAllocation() function needs to know the current index of how many Allocations have been made so that it builds the input names right, since they should be in the form Allocation[i].FundSource, which means I would have to have a global javascript variable or something similar to keep track of it, which just seems like a terrible idea.


I'm just thinking there has to be a way to do this better that I'm not aware of.


Here's the actual AllocationInformation class in case it's helpful:



public class AllocationInformation
{
[Key]
public int Id { get; set; }

[ForeignKey("CheckRequestModel")]
public int CheckRequestId { get; set; }

public CheckRequestModel CheckRequestModel { get; set; }

public string FundSource { get; set; }

public string Function { get; set; }

public string Location { get; set; }

public string Program { get; set; }

public string Subject { get; set; }

public string Object { get; set; }

public float Amount { get; set; }

public int VendorNumber { get; set; }
}




Aucun commentaire:

Enregistrer un commentaire