2013-08-07 2 views
0

У меня есть форма, которая представляет коллекцию TimeItems (объект таблицы), которые затем будут добавлены в базу данных. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу разрешить пользователю добавлять столько же или как несколько TimeItems, сколько они хотят собрать перед подачей. В настоящее время входных ПОЛЕИ TimeItem состоят из скрытого входа для внешнего ключа, поле со списком для выбора сотрудника, а основное поле ввода для ввода заметок на мой взгляд, с JavaScript:.VB.Net MVC4 Расширенное создание объектов в форме submit w/jQuery

<div> 
    <img src="" alt="Add row" id="add-timesheet-row" />   
    @Using Html.BeginForm("AddToTimesheet", "Project") 
     @<div> 
      <input type="hidden" name="TimeItems[0].TaskID" value="@Model.TaskID"/> 
      <select name="TimeItems[0].EmployeeID"> 
       @For Each emp As SelectListItem In ViewBag.EmployeeID 
        @<option value="@emp.Value">@emp.Text</option> 
       Next 
      </select> 
      <input type="text" name="TimeItems[0].Notes" value="Test Notes" /> 

      <div id="add-row-target" style="display: none"></div> 

      <div class="button-submit"> 
       <input type="submit" value="Create" /> | 
       @Html.ActionLink("Back", "Index") 
      </div> 
     </div> 
    End Using 
</div> 

<script type="text/javascript"> 
    $(document).ready(function() { 
     $("#add-timesheet-row").click(function() { 
      $.get('@Url.Action("RenderTimeItems", New With {.id = Model.TaskID})', function(data) { 
       $('#add-row-target').before(data); 
      }); 
     }); 
    }); 
</script> 

Что происходит здесь заключается в том, что при нажатии кнопки «Добавить строку» img javascript возвращает действие RenderTimeItems, которое, в свою очередь, возвращает частичное представление. Этот частичный вид содержит входной HTML снова (скрытый, комбо, и текстовое поле):

<input type="hidden" name="TimeItems[#].TaskID" value="@Model.TaskID"/> 
<select name="TimeItems[#].EmployeeID"> 
    @For Each emp As SelectListItem In ViewBag.EmployeeID 
     @<option value="@emp.Value">@emp.Text</option> 
    Next 
</select> 
<input type="text" name="TimeItems[#].Notes" value="Test Notes" /> 

Этот HTML затем добавляется к первоначальной форме. Проблема с моим частичным представлением заключается в том, что «#» в TimeItems[#] должно быть фактическим числом и должно увеличиваться каждый раз, когда пользователь нажимает «Добавить строку» для моего контроллера, чтобы иметь возможность правильно интерпретировать коллекцию TimeItems. В моем первоначальном представлении обратите внимание на использование TimeItems[0] для исходного TimeItem, поэтому следующий в моем частичном представлении должен быть TimeItems[1]. Как я могу отслеживать число, увеличивать его, когда в моем главном представлении щелкнет «Добавить строку», но все же получить доступ к нему в частичном представлении после вызова RenderTimeItems?

Когда пользователь отправляет форму, он идет к действию AddToTimesheet, который потребляет сбор и добавляет каждый отдельный TimeItem в базу данных, как и в this example как так:

<HttpPost()> 
Function AddToTimesheet(ByVal TimeItems() As ppTimeItem) As ActionResult 
    If TimeItems IsNot Nothing Then 
     For Each time In TimeItems 
      db.ppTimeItems.Add(time) 
      db.SaveChanges() 
     Next 
    End If 
    Return RedirectToAction("Index") 
End Function 

Кроме того, если я хотел бы разрешить пользователю удалять TimeItem (ранее добавленные) перед отправкой формы, это приведет к удалению индекса из коллекции, который должен содержать совместимые индексы для правильной работы. то есть если TimeItems[0], TimeItems[1] и TimeItems[2] были добавлены, а затем пользователь удаляет TimeItems[1], то TimeItems[2] больше не будет добавлен правильно, так как остальные индексы равны 0 и 2. Любые мысли?

ответ

1

Сначала вам нужно будет отслеживать, сколько строк TimeItem у вас есть на странице, поэтому вам нужно что-то, что есть на каждой строке. add-row-target будет работать, но я рекомендую давая <div> класс как «timeItem»:

var numItems = $("#add-row-target").length; 

Вы можете продолжать возвращать частичный вид и в $.get обратного вызова просто заменить „#“ в возвращении data с numItems ,

$.get('@Url.Action("RenderTimeItems", New With {.id = Model.TaskID})', function(data) { 
       var dataWithNumber = data.replace(/#/g , numItems); 
       $('#add-row-target').before(dataWithNumber); 
      }); 

При желании, можно передать количество в метод действия, который возвращает частичное

$.get('@Url.Action("RenderTimeItems", New With {.id = Model.TaskID})?number=' + numItems 


<input type="hidden" name="TimeItems[@Model.Number].TaskID" value="@Model.TaskID"/> 
<select name="TimeItems[@Model.Number].EmployeeID"> 
    @For Each emp As SelectListItem In ViewBag.EmployeeID 
     @<option value="@emp.Value">@emp.Text</option> 
    Next 
</select> 
<input type="text" name="TimeItems[@Model.Number].Notes" value="Test Notes" /> 
+0

Как бы заменить «#» в данных возвратных с вар количество_элементов? – ElliotSchmelliot

+0

Я обновил свой ответ, чтобы показать, как заменить '#' в обратном вызове –

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