2016-07-16 1 views
1

Я создаю приложение MVC для планирования, и у меня есть 3 класса CodeFirst EF6 в конфигурации «многие ко многим», причем средняя таблица содержит дополнительную информацию, такую ​​как время, дату и т. д. встречи между хозяином и их посетителями. Я создал ViewModel, чтобы позволить мне создавать хосты, посетителей и собрания на одной странице вместо того, чтобы идти на каждую страницу отдельно, чтобы создать необходимые ресурсы для собрания. Контроллер и вид для этой компоновки порождают несколько вопросов.Включить поле без базы данных в верхней части окна SelectList for Razor в MVC 5

Я передаю, используя ViewBag, а SelectList к представлению

ViewBag.HostID = new SelectList(db.Hosts.OrderBy(x => x.Name), "id", "Name"); 

и

ViewBag.VisitorID = new SelectList(db.Visitors.OrderBy(x => x.LastName). 
ThenBy(y => y.FirstName), "id", "VisitorName"); 

которая успешно оказывается на мой взгляд, Razor с помощью

<div class="form-group"> 
     @Html.LabelFor(model => model.HostID, "HostID", htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownList("HostID", null, htmlAttributes: new { @class = "form-control" }) 
      @Html.ValidationMessageFor(model => model.HostID, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.VisitorID, "VisitorID", htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.DropDownList("VisitorID", null, htmlAttributes: new { @class = "form-control" }) 
      @Html.ValidationMessageFor(model => model.VisitorID, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

Однако, Я хотел бы иметь возможность выбрать строку в DropDownList, которая не имеет связанного с ней HostID или VisitorID. h, чтобы затем я мог ввести нового Хоста или Посетителя и чтобы мой контроллер создал необходимые записи, когда форма отправлена ​​обратно.

Таким образом, мой вопрос заключается в том, как добавить поле базы данных в верхнюю часть SelectList, которое будет означать контроллер (однажды отправленный назад), чтобы новая запись была создана вместо ссылки на существующий узел использоваться?

+0

После создания 'SelectList', используйте' .ToList() 'на полученном' IEnumerable '' и использовать Insert() ', чтобы за -pend новый 'SelectListItem'. Но неясно, как вы собираетесь это использовать. Вы не знаете какую-либо информацию о« Хосте »или« Посетителе »из опубликованных данных, так что бы вы вставляли в базу данных? –

+0

В файле Razor есть дополнительные элементы формы, которые потребовали бы заполнения, если бы посетитель, не входящий в список, был необходим. –

+0

Тогда вы можете просто сделать это в соответствии с первым комментарием (или 'ViewBag.HostID = новый List

ответ

1

Вы можете создать свой SelectList с помощью

ViewBag.HostID = new List<SelectListItem>() 
{ 
    new SelectListItem() 
    { 
     Value = "-1", // note, do not make this "0" unless you make HostID nullable 
     Text = "New Host" 
    } 
}.Concat(db.Hosts.OrderBy(x => x.Name).Select(x => new SelectListItem() 
{ 
    Value = x.id.ToString(), 
    Text = x.Name 
})); 

Обратите внимание, что вы не должны быть именование ViewBag свойства такого же имени, как свойство вашего связывания (см this answer), и вы должны использовать вид модель с IEnumerable<SelectListItem> HostList так что с точки зрения вы сильно привязать к модели представления, используя

@Html.DropDownListFor(m => m.HostID, Model.HostList, "-Please select-", new { @class = "form-control" }) 

Однако лучший подход, чтобы решить проблему добавления нового параметра в <select> будет включать кнопку «Добавить новый хост», которая отображает модальную форму для создания Host и использовать ajax для ее отправки, и в случае успеха добавьте новый параметр в DOM. Код структуры будет

@using (Html.BeginForm()) 
{ 
    .... 
    @Html.DropDownListFor(m => m.HostID, Model.HostList, "-Please select-", new { @class = "form-control" }) 
    <button type="button" id="addhost">Add new Host</button> 
    .... 
} 
<div id="hostmodal"></div> 

$('#addhost').click(function() { 
    $('#hostmodal').load('@Url.Action("Create", "Host")); 
    // reparse the validator 
}); 

где Create() метод HostController возвращает частичный вид формы для создания нового Host (см this answer для повторной обработки валидатора)

Затем обработать .submit() события ' Create Host ', отмените его и отправьте значения с помощью ajax в метод, который возвращает новый ID из Host в JsonResult(). Используя возвращаемые значения ID и Name из формы, вы можете добавить новый элемент <option> и выбрать его.

$('#hostmodal').on('submit', '#hostform', function() { 
    var data = $(this).serialize(); 
    var url = '@Url.Action("Create", "Host")'; 
    var text = ... // a value from the form that you want as the option text 
    $.post(url, data, function(response) { 
     if (response) { 
      $('#HostID').append($('<option></option>').val(response).text(text)).val(response); 
     } else { 
      // Oops 
     } 
    }).fail(function() { 
     // Oops 
    }); 
    // ... close the modal 
    return false; // cancel the default submit 
}); 

Примечание, Если вы хотите иметь новый Host добавил в порядке сортировки см this answer.

и метод POST будет что-то вроде

[HttpPost] 
public JsonResult Create(HostViewModel model) 
{ 
    // Initialize a new Host data model and set its properties based on the view model 
    var host = new Host() 
    { 
     Name = model.Name, 
     .... 
    } 
    // Save it 
    db.Hosts.Add(host); 
    db.SaveChanges(); 
    // Return its ID 
    return Json(host.ID); // or return Json(null); if error 
} 
+0

Большое спасибо. Я думаю, что я слежу за всем этим. Дайте мне время, чтобы реализовать его и выработать все детали, которые мне нужно понять, и я приду назад –

+0

Я думаю, что я рядом, но не сигары. Я могу отображать поля при нажатии «Добавить нового посетителя», но когда я clic k «Сохранить посетителя» jQuery не выполняется. Похоже, скрипт не зарегистрирован. Я начну новые вопросы и отправлю ссылку здесь в ближайшее время. –

+0

Связанный с этим вопрос - http://stackoverflow.com/questions/38418163/using-jquery-and-partial-views-to-add-a-new-dropdownlist-item-in-mvc –

Смежные вопросы