4
votes

Lets say i have a class 'Location', and I'm using MVC3 to create a scaffolding list(index.cshtml). The index html page uses @model IEnumerable. If i want to add a new location to the list, i press create, and i end up with a new html page using @model Project.Models.Location.

Instead of going to a new page, i would like to have the create page as a popup using modal in boostrap(twitter). I've tried using partialview without any luck. Whatever i do i get the dictionary error message.

The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1[Project.Models.Location]', but this dictionary requires a model item of type 'Project.Models.Location'.

The modal(bootstrap) itself is working when i'm not fetching the partialview. The partialview itself is exactly the same as the generated create(CRUD).

EDIT: I rewrote the whole thing.

Index:

@model IEnumerable<LoLStats.Models.Location>

@{
    ViewBag.Title = "Index";
}
@foreach (var item in Model) {
    <ul>
        <li>@Html.DisplayFor(modelItem => item.LocationName)</li>
    </ul>
}

<a class="btn" data-toggle="modal" href="#myModal" >Create</a>

<div class="modal hide" id="myModal">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3>Modal header</h3>
  </div>
  <div class="modal-body">
    <p>@Html.Partial("_createLocation")</p>
  </div>
  <div class="modal-footer">
    <a href="#" class="btn" data-dismiss="modal">Close</a>
    <a href="#" class="btn btn-primary">Save changes</a>
  </div>
</div>

_createLocation:

@model LoLStats.Models.Location

@{ ViewBag.Title = "Create"; }

@using (Html.BeginForm()) { @Html.ValidationSummary(true) Location

    <div class="editor-label">
        @Html.LabelFor(model => model.LocationName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.LocationName)
        @Html.ValidationMessageFor(model => model.LocationName)
    </div>
    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset> }
3
You have spelled Project wrong 'Prosject.Models.Cars'JoonasL
Thats not the problem. I didnt have the exact errormessage at hand, so i wrote it. But thanks anyways :)sindrem
Please also post the code you currently haveJoonasL

3 Answers

4
votes

You could make a view model that has two properties:

  • The IEnumerable for the parent view
  • A singular object for the modal

Then strongly type both views to the view model and you should be all set.

Edit

ViewModel:

public class MyViewModel()
{
  public IEnumerable<LoLStats.Models.Location> Locations {get; set;}
  public LoLStats.Models.Location Location {get; set;}
}

Index:

@model myNamespace.MyViewModel
...
@foreach (var item in Model.Locations) {
    <ul>
        <li>@Html.DisplayFor(modelItem => item.Locations.LocationName)</li>
    </ul>
...

_createLocation:

@model myNamespace.MyViewModel
...
<div class="editor-label">
        @Html.LabelFor(model => model.Location.LocationName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Location.LocationName)
        @Html.ValidationMessageFor(model => model.Location.LocationName)
    </div>
...

Hopefully that's enough detail to get you going

2
votes

try this in the Index view:

   ... <p>@Html.Partial("_createLocation", Model.FirstOrDefault())</p>

on the other hand, maybe this will make more sence:

   ... <p>@Html.Partial("_createLocation", new LoLStats.Models.Location())</p>

hope it works for you.

0
votes

Your pop-up would need to have a model defined as Project.Models.Car (singular item). After successfully saving the single item you need to update your original list view. Which you can do using jQuery by inserting a new item into the DOM or just by refreshing the page by navigating to the action that gave you the list to begin with.