BeginCollectionItem() gives only lastly appended item for PostBack - collections

InquiryOrderViewModel
public class InquiryOrderViewModel
{
public InquiryOrder InquiryOrder { get; set; }
public List<InquiryOrderDetail> InquiryOrderDetails { get; set; }
}
InquiryOrderIndex View and the Script to add items
#model eKnittingData.InquiryOrderViewModel
#using (Html.BeginForm("Save", "InquiryOrder"))
{
<div id="editorRows">
#foreach (var item in Model.InquiryOrderDetails)
{
Html.RenderPartial("_DetailEditorRow", item);
}
</div>
#Html.ActionLink("Add another...", null, null, new { id = "addItem" })
<div class="col-md-6"> <input type="submit" value="Save" class="btn btn-success" /> </div>
}
<script>
$('#addItem').click(function (e) {
e.preventDefault();
var isExist = false;
$('.editorRow').each(function () {
if ($(this).children('.class01').val() == 0 || $(this).children('.class02').find("option:selected").text() == "Select") {
isExist = true;
return false;
}
});
if (isExist == false) {
$('.editorRow').each(function () {
$(".editorRow").children().attr("disabled", "disabled");
});
$.ajax({
url: '#Url.Action("BlankEditorRow", "InquiryOrder")',
cache: false,
success: function (data) {
$("#editorRows").append(data);
}
});
}
});
</script>
DetailEditorRow PartialView
#model eKnittingData.InquiryOrderDetail
#using eKnitting.Helpers
#using (Html.BeginCollectionItem("InquiryOrderDetails"))
{
<div class="editorRow">
#Html.DropDownListFor(a => a.ComponentId, (SelectList)ViewBag.CompList, "Select", new { Class = "class02" })
#Html.DropDownListFor(a => a.DesignCodeId, (SelectList)ViewBag.DCodeList, "Select", new { Class = "class03" })
#Html.TextBoxFor(a => a.NoOfParts, new { Class = "class01" })
delete
</div>
}
ActionResult which returns PartialView
public ActionResult BlankEditorRow()
{
var objContext = new KnittingdbContext();
ViewBag.CompList = new SelectList(objContext.Components, "ComponentId", "ComponentName");
ViewBag.DCodeList = new SelectList(objContext.DesignCodes, "DesignCodeId", "DesignCodeCode");
return PartialView("_DetailEditorRow", new InquiryOrderDetail());
}
ActionResult for 'GET'
var objContext = new KnittingdbContext();
var newIovm = new InquiryOrderViewModel();
var newIo = new InquiryOrder();
//initial item
var newIoD = new List<InquiryOrderDetail>
{
new InquiryOrderDetail()
};
newIovm.InquiryOrder = newIo;
newIovm.InquiryOrderDetails = newIoD;
ViewBag.CompList = new SelectList(objContext.Components, "ComponentId", "ComponentName");
ViewBag.DCodeList = new SelectList(objContext.DesignCodes, "DesignCodeId", "DesignCodeCode");
return View(newIovm);
ActionResult for 'POST'
public ActionResult Save(InquiryOrderViewModel inquiryOrderViewModel)
{
.................
}
When i click the add button im able to add items dynamically. But for PostBack it gives me only the lastly appended item. I checked it by putting a break point on post ActionResult. How can i get the whole collection for PostBack? Where did i go wrong? All help appreciated. Thanks!

Your scripts sets a variable var isExist = false;. When you add a new item, you check if the value is false (which it is if you got that far) and then disable all existing inputs.
Disabled form controls do not post back, hence you only get the values for the last row you have added.
Its unclear why you would want to disable them, but if you want to prevent editing of existing rows, the make them readonly
$(".editorRow").children().prop("readonly", true);

Related

I get a null variable in my asp.net mvc project

This is Ajax code
<script>
$(document).ready(function () {
$("#btnKaydet").click(function () {
debugger
var data = $("#myForm").serialize();
$.ajax({
type:"POST",
url: "/Home/Olusturma",
data: data,
success: function (response) {
alert("Kayıt İşlemi Başarılı")
}
})
})
})
</script>
This is saving button code
<form id="myForm">
<input type="button" value="Buradan Kaydet" class=" btn btn-default" id="btnKaydet" />
</form>
This is HomeController code
public ActionResult Olusturma()
{
KullaniciDBEntities db = new KullaniciDBEntities();
List<Kisi> kL = db.Kisi.ToList();
ViewBag.kisiList = new SelectList(kL, "AdSoyad", "Email", "Yas", "Konum", "Telefon", "Parola");
return View();
}
[HttpPost]
public ActionResult Olusturma(KullaniciDBEntities model)
{
try
{
KullaniciDBEntities db = new KullaniciDBEntities();
List<Kisi> kL = db.Kisi.ToList();
ViewBag.kisiList = new SelectList(kL, "AdSoyad", "Email", "Yas", "Konum", "Telefon", "Parola");
Kisi k = new Kisi();
k.ID = model.ID;
k.AdSoyad = model.AdSoyad;
k.Email = model.Email;
k.Yas = model.Yas;
k.Konum = model.Konum;
k.Telefon = model.Telefon;
k.Parola = model.Parola;
db.Kisi.Add(k);
db.SaveChanges();
int SonId = k.ID;
}
catch (Exception ex)
{
throw ex;
}
return RedirectToAction("Listeleme");
}
Hello everyone. When ı run my project, ı get a error. My variables seems normal but they dont show anything.It shows (null) variable in their places .How can ı fix this error? I have controller, KullaniciDBentities model and View parts.

Asp net core mvc model details not validating and passing values to controller

In the Edit method of a controller, I cannot successfully validate and pass the details of a model. But when I add new row, it validates and pass it's values to the controller.
Here is the sample output:
The two records is not passing and validating but when I add a new row, the record from new row validates and passes
Here is my code for getting the existing details
var form = $('form');
$.ajax({
url: '/Journals/EditJournalDetails',
data: {
id: #Model.Id
},
success: function (data) {
$('#journalRow').append('<tr>' + data + '</tr>');
$('tbody#journalRow>tr.checkDetails').appendTo('#checkRow');
form.data('validator', null);
$.validator.unobtrusive.parse(form);
}
});
the code for EditJournalDetails
#model IEnumerable<SimplyAccounting.Models.TransactionViewModels.JournalDetailsViewModel>
#using (Html.BeginCollectionItem("JournalDetailsViewModel"))
{
#foreach (var item in Model)
{
//row values here
}
}
Controller code:
public async Task<IActionResult> EditJournalDetails(int? id)
{
var journaldetails = await _context.JournalDetails.Where(m => m.JournalId == id).ToListAsync();
var jdvmodel = _mapper.Map<List<JournalDetailsViewModel>>(journaldetails);
foreach(var item in jdvmodel)
{
//retrieve data here
}
return PartialView("_EditJournalDetails", jdvmodel);
}
Add row code JS:
function GetRow() {
var form = $('form');
$.ajax({
url: '/Journals/CreateJournalDetails',
success: function (data) {
$('#journalRow').append('<tr>' + data + '</tr>');
$('tbody#journalRow>tr.checkDetails').appendTo('#checkRow');
form.data('validator', null);
$.validator.unobtrusive.parse(form);
}
});
}
CreateJournalDetails partialview code:
#model SimplyAccounting.Models.TransactionViewModels.JournalDetailsViewModel
#using (Html.BeginCollectionItem("JournalDetailsViewModel"))
{
//row codes here
}
Controller code:
public IActionResult CreateJournalDetails(JournalDetailsViewModel vmodel)
{
vmodel = new JournalDetailsViewModel();
//some code here
return PartialView("_CreateJournalDetails", vmodel);
}
Solve the issues using this code
View
<tbody id="journalRow">
#foreach(var item in Model.JournalDetailsViewModel)
{
#Html.Partial("_JournalDetails", item)
}
</tbody>
PartialView
#model SimplyAccounting.Models.TransactionViewModels.JournalDetailsViewModel
#using (Html.BeginCollectionItem("JournalDetailsViewModel"))
{
<tr class="checkDetails" id="#Model.Guid">
<td>
}
}

when returning a view from Child Ajax Form it redirects to child forms url instead of refreshing the child ajax form only

Child ajax form redirects to the URL http://www.AppName/Email/Email/AttachmentList instead of refreshing the AttachmentList view only.
Here is the child form (View Name: Attachment List)
#foreach (var attachment in Model.Attachments)
{
<li>
#using (Ajax.BeginForm("RemoveAttachment", "Email", new { area = "Email" }, new FSIAjaxOptions { UpdateTargetId = "uploadedFilesSection" }, new { #id = "fromEditRole" + attachment.IdString }))
{
#Html.HiddenFor(model => attachment.IdString)
<span><a `enter code here`href="#Url.Content("~/File/GetFile")?folder=EmailAttachments&file=#(attachment.AttachName)" target="_blank">#attachment.OriginalName</a></span>
<button type="submit" class="imageButton removeButton" title="Remove"></button>
}
</li>
}
Here is the Controller Action
[Authorize]
[HttpPost]
public ActionResult RemoveAttachment(FormCollection fm)
{
EmailViewModel model = SessionData.GetCurrentObject<EmailViewModel>();
if ((fm.AllKeys.Contains("attachment.IdString")) && !string.IsNullOrEmpty(fm["attachment.IdString"]))
{
var attachment = model.Attachments.Where(x => x.IdString == fm["attachment.IdString"]).FirstOrDefault();
if (attachment != null)
{
FileHelper.RemoveFile("EmailAttachments","",attachment.AttachName);
Directory.Delete(WebConfig.SharedFileContainer + #"\EmailAttachments\" + attachment.IdString, true);
model.Attachments.Remove(attachment);
}
SessionData.SaveCurrentObject<EmailViewModel>(model);
}
return View("AttachmentList", "Email", new { area = "Email" });
}
public ActionResult AttachmentList()
{
EmailViewModel email = SessionData.GetCurrentObject<EmailViewModel>();
if (Request.IsAjaxRequest())
{
return PartialView(email);
}
else
{
return View("AttachmentList", "~/Views/Shared/Wrapper.cshtml", email);
}
}
Make sure you have the ajax js file referenced.

How do I pass an id of a clicked button to controller using AjaxBeginForm?

I'm using #Ajax.BeginForm() with KendoUI ListView in my asp.net mvc3 application. The KendoUI ListView displays a list of Items with a button for each item.
My requirement is that onclick of submit button, I need to send the id of a clicked button to the controller and return the full information of the Item.
My approach was to use onclick function for all buttons to trigger AjaxBeginForm submit input but the AjaxBeginForm submit input doesn't seems to pass the right value into the controller,
How can I achieve this?
<pre>
//My Ajax form
var ajaxOpts = new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "gallery",
InsertionMode = InsertionMode.Replace,
OnBegin = "OnBeginT1",
};
#using (Ajax.BeginForm("BlogInformation", ajaxOpts))
{
<input id="input" type="submit" style="display: none"/>
}
<script id="listview-template" type="x-kendo-template">
<button class="k-button1" onclick="returnsubmitted()" id="#:id#" name="but">Read More</button>
//Displaying a list
</div>
#(Html.Kendo().ListView<Blog>()
.Name("listView")
.TagName("div")
.ClientTemplateId("listview-template")
.DataSource(dataSource =>
{
dataSource.Read(read => read.Action("Blog_Read", "Blog"));
})
)
<script>
function returnsubmitted() {
//$("input").val($("#:id#").val());//This does not pass the right value to input
// $("#input").val($('.k-button1').attr('class').id);
$("#input").click();
}
</script>
//Here is my controller
[HttpPost]
public ActionResult BlogInformation(string blogid)
{
XElement element = XElement.Load(Server.MapPath("~/App_Data/Blogs.xml"));
IEnumerable<Blog> data = null;
if (!string.IsNullOrEmpty(blogid))
{
var xElement = FindByID(blogid, element.Element("Blog")).Element("Blog");
if (xElement != null)
{
data = FindByID(blogid, element.Element("Blog"))
.Element("items")
.Elements("Blog")
.Select(e => ToBlog(e));
}
else
{
data = element.Elements("Blog").Select(e => ToBlog(e));
}
}
return View(data);
}

ASP.NET MVC4 + Get drop down value after HttpPost submit

So I want to get a value of the dropdown (== id of the account) to insert a new transaction
Here below you can find my View:
<div id="content">
<h2>Overschrijving</h2>
<p id="topmsg">velden met een * zijn verplicht</p><p> </p>
<dl class="clearfix form">
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
#Html.ValidationSummary(true, "Gelieve alles correct in te vullen.")
<dt>#Html.Label("Rekening: *")</dt>
<dd>#Html.DropDownList("ddlAccounts")</dd>
<dt>#Html.Label("Begunstigde: *")</dt>
<dd>#Html.TextBox("ToAccountNumber")</dd>
<dt>#Html.Label("Bedrag: *")</dt>
<dd>#Html.TextBox("Amount", null, new { #class = "inpshort" })</dd>
<dt>#Html.Label("Mededeling: ")</dt>
<dd>#Html.TextBox("Message", null, new { #class = "inplong" })</dd>
<dd class="buttons">
<input type="submit" value="Bevestigen" />
<input type="submit" value="Annuleren" />
</dd>
}
</dl>
</div>
this is the Controller code:
public ActionResult Transfer(int? id) {
Holder h = Holder.GetHolderByHolderId(Convert.ToInt32(User.Identity.Name));
List<Account> holderAccounts = Account.GetAccountsByHolderId(h.Id);
List<SelectListItem> ddlHolderAccounts = new List<SelectListItem>();
ddlHolderAccounts.Add(new SelectListItem { Text = "selecteer...", Value = "-1", Selected = true });
foreach (Account acc in holderAccounts) {
if (acc.Id == id) {
ddlHolderAccounts.Add(new SelectListItem { Text = acc.Name, Value = acc.Id.ToString(), Selected = true });
} else {
ddlHolderAccounts.Add(new SelectListItem { Text = acc.Name, Value = acc.Id.ToString() });
}
}
ViewData["ddlAccounts"] = ddlHolderAccounts;
return View();
}
[HttpPost]
public ActionResult Transfer(Transaction tra) {
if (ModelState.IsValid) {
Transaction.InsertTransaction(tra.Amount, tra.Message, tra.FromAccountId, tra.ToAccountNumber);
}
return View(tra);
}
Now I searched a lot with Google, it's probably better to use the DropDownListFor to fill your drop down list? But could anyone show me an example?
By looking at your code, I can see that you're not passing a list of SelectListItems to the DropDownList helper. You can do this one of two ways.
1- Bind it to a property on your model:
#Html.DropDownListFor(x=>Model.Property, new List<SelectListItem> { new SelectListItem { Text = "Item1", Value = "Value1" })
Or
2- You can do it without binding to a model property like:
#Html.DropDownList("propertyName", new List<SelectListItem> { new SelectListItem { Text = "Item1", Value = "Value1" } })
If you're using the second approach then your controller action must accept "propertyName" as a parameter when submitting.
And don't forget to provide a list of SelectListItems to select from (which you're not doing in your code).
Hope this helps.
should be
#Html.DropDownListFor(x=>Model.Property, new List { new SelectListItem { Text = "Item1", Value = "Value1" }})

Resources