-1

I have PROPERTY VM which contains List<FounderInvestmentViewModel>.I have successfully inserted the partial view of FounderInvestmentViewModel into the Main Create Property view.

FounderInvestmentViewModel in turn contains List<InstallmentDetailsViewModel>. I have created the Partial View for InstallmentDetailsViewModel as _InstallmentDetails.cshtml and all the necessary actions.

I want to insert the _InstallmentDetails.cshtml into the partial view of FounderInvestmentViewModel which is in turn inserted into the Main View.

First let us take a look at the codes that I have used so far :--

Property View Model:-

public class PropertyViewModel
    {

        public int? Id { get; set; }
        public string PropertyTitle { get; set; }
        ....other attributes....
        public List<FounderInvestmentViewModel> FounderInvestments { get; set; } = new List<FounderInvestmentViewModel>();
    }

FounderInvestmentViewModel:-

public class FounderInvestmentViewModel
    {
        public int? Id { get; set; }        
        public int InvestorId { get; set; }
        public double Investment { get; set; }
        public int InstallmentPeriod { get; set; }
        public IEnumerable<SelectListItem> FounderInvestorList { get; set; }
        public List<InstallmentDetailsViewModel> InstallmentDetails { get; set; } = new List<InstallmentDetailsViewModel>();

    }

InstallmentDetailsViewModel:-

public class InstallmentDetailsViewModel
    {
        public int? Id { get; set; }

        [Display(Name = "Pay Date")]
        public List<DateTime> PayDates { get; set; }
        [Required]
        public List<double> InstallmentAmounts { get; set; }
    }

PartialView for InstallmentDetails (_InstallmentDetails.cshtml):-

@model propertyMgmt.ViewModel.InstallmentDetailsViewModel

<div class="installmentDetails">
    @using (Html.BeginCollectionItem("InstallmentDetails"))
    {
        @Html.HiddenFor(m => m.Id, new { @class = "id" })

        <div class="form-group">
            @Html.LabelFor(m => m.InstallmentAmounts, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(m => m.InstallmentAmounts, new { htmlAttributes = new { @class = "form-control", @type = "number" } })
                @Html.ValidationMessageFor(m => m.InstallmentAmounts, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(m => m.PayDates, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(m => m.PayDates, new { htmlAttributes = new { @class = "form-control", @placeholder = "01/02/2017" } })
                @Html.ValidationMessageFor(m => m.PayDates, "", new { @class = "text-danger" })
            </div>
        </div>
    }
</div>

This _InstallmentDetails.cshtml is inserted into this _FounderInvestmentDetails.cshtml which is PartialView for FounderInvestmentDetails View Model:-

@model propertyMgmt.ViewModel.FounderInvestmentViewModel

<div class="founderInvestmentDetails">
    @using (Html.BeginCollectionItem("FounderInvestments"))
    {      
            @Html.HiddenFor(m => m.Id, new { @class = "id" })

            <div class="form-group">
                @Html.LabelFor(m => m.InvestorId, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownListFor(m => m.InvestorId, Model.FounderInvestorList, "Select Investor", htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(m => m.InvestorId, "", new { @class = "text-danger" })                    
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(m => m.Investment, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(m => m.Investment, new { htmlAttributes = new { @class = "form-control", @type = "number" } })
                    @Html.ValidationMessageFor(m => m.Investment, "", new { @class = "text-danger" })

                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(m => m.InstallmentPeriod, htmlAttributes: new { @class = "control-label col-md-2", @type = "number" })
                <div class="col-md-10">
                    @Html.EditorFor(m => m.InstallmentPeriod, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(m => m.InstallmentPeriod, "", new { @class = "text-danger" })

                </div>
            </div>
            <div class="form-group" id="installmentDetailsDiv">
                @foreach (var InstallmentDetails in Model.InstallmentDetails) 
                {
                    @Html.Partial("_InstallmentDetails", InstallmentDetails)
                }
            </div>

            <div class="form-group col-md-10">
                <input type="button" class="btn btn-info btn-xs" value="Add Installment Details" onclick="addInstallmentDetails()" /> 
            </div>    
    }
</div>

This is the MAIN CREATE VIEW :-

@model propertyMgmt.ViewModel.PropertyViewModel.PropertyViewModel   
@{
    ViewBag.Title = "Create";    
}
<script src="~/Areas/Admin/themes/jquery/jquery.min.js"></script>        
<h2>Property</h2>    
@using (Html.BeginForm("Create", "Property", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Add Property</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.PropertyTitle, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.PropertyTitle, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.PropertyTitle, "", new { @class = "text-danger" })
            </div>
        </div>
        .....Other form Groups.....
        <div id="founderInvestmentDetails">          
            @foreach(var FounderInvestments in Model.FounderInvestments)
            {
            @Html.Partial("_FounderInvestmentDetails", FounderInvestments)
            }
        </div>

        <div class="form-group col-md-10" >
            <input type="button" class="btn btn-info btn-xs" value="Add Founder Investors" onclick="addFounderInvestors()" />
        </div>
    </div>
}

This is My JS Code in the Main View:-

function addFounderInvestors() {
        var url = '@Url.Action("FounderInvestmentDetails")';
        var form = $('form');
        var founders = $('#founderInvestmentDetails');
        $.get(url, function (response) {
            founders.append(response);
            // Reparse the validator for client side validation
            form.data('validator', null);
            $.validator.unobtrusive.parse(form);
        });
    };

    function addInstallmentDetails() {
        var url = '@Url.Action("InstallmentDetails")';
        var form = $('form');
        var installments = $('#installmentDetailsDiv');
        $.get(url, function (response) {
            installments.append(response);
            // Reparse the validator for client side validation
            form.data('validator', null);
            $.validator.unobtrusive.parse(form);
        });
    };

Controller Code :-

public PartialViewResult FounderInvestmentDetails()
        {
            var model = new FounderInvestmentViewModel {
                FounderInvestorList = _investorQueryProcessor.GetInvestorByType(1).Select(x => new SelectListItem
                {
                    Value = x.Id.ToString(),
                    Text = x.InvestorName
                })

        };
            //return PartialView(model);
            return PartialView("_FounderInvestmentDetails", model);
        }

        public PartialViewResult InstallmentDetails()
        {
            return PartialView("_InstallmentDetails",new InstallmentDetailsViewModel());
        }
public ActionResult Create()
        {
            if (Session["AdminName"] != null)
            {
                //ViewBag.Investors = SelectListItems;
                List<FounderInvestmentViewModel> model = new List<FounderInvestmentViewModel>();
                List<InstallmentDetailsViewModel> model2 = new List<InstallmentDetailsViewModel>();
                return View(new PropertyViewModel());

            }
            else return Redirect("/Account/Login");
        }

EDIT:- Sorry this is what is throwing the exception -->> Collection.cshtml PROCESS:- In the Main View, "Add Founder Investor Buttons" on click event adds the partial view _FounderInvestmentDetails.cshtml successfully.Now the "Add Installment Details" button is appended.Upon clicking this "Add Installment Details" button _InstallmentDetails.cshtml partial view should be appended,BUT this part is not working. When I click this button, I get the error "Object reference not set to an instance of an object" in the following code:-

@using HtmlHelpers.BeginCollectionItem

<ul>                                 
    @foreach (object item in Model)-->>ERROR CODE
    {
        <li>
            @using (Html.BeginCollectionItem(Html.ViewData.TemplateInfo.HtmlFieldPrefix)) 
            {
                @Html.EditorFor(_ => item, null, "")
            }
        </li>
    }
</ul>
SudeepS
  • 29
  • 9
  • 3
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Camilo Terevinto Dec 24 '17 at 16:10
  • The model, `propertyMgmt.ViewModel.FounderInvestmentViewModel`, is NULL. That's why you get a NRE. – Camilo Terevinto Dec 24 '17 at 16:11
  • @CamiloTerevinto If that view model was null, why would the first partial view be appended to the Main view? – SudeepS Dec 24 '17 at 16:14
  • Because it's not required, at all, that the model is initialized. – Camilo Terevinto Dec 24 '17 at 16:15
  • @CamiloTerevinto I have initialized both the Models, I initialized it in the View Model itself. Why would it show me Null reference exception? Where do You think is the issue? – SudeepS Dec 24 '17 at 16:17
  • You didn't post your Controller's code, so we cannot just guess. However, you most likely used `return PartialView()` instead of `return PartialView(new FounderInvestmentViewModel())` – Camilo Terevinto Dec 24 '17 at 16:18
  • @CamiloTerevinto I added the controller code above. Check Please :/ – SudeepS Dec 24 '17 at 16:24
  • @CamiloTerevinto Sorry, the error was thrown By Collection.cshtml. Take a look for the problem If you would like to.Thank You :) – SudeepS Dec 24 '17 at 16:46

1 Answers1

1

The Paydates and Installments does not need to be <List> as it already is a PartialView and can be added multiple times.

public class InstallmentDetailsViewModel {
    public int? Id { get; set; }    
    [Display(Name = "Pay Date")]
    public List<DateTime> PayDates { get; set; }
    [Required]
    public List<double> InstallmentAmounts { get; set; }
}
Ram Koti
  • 2,147
  • 6
  • 24
  • 34
Sudeep Shrestha
  • 128
  • 1
  • 13