I need to insert a data from a table which has a foreach loop inside. I used to work with webforms so I'm newbie to mvc. I always encountered this scenario in webforms using gridview control and just implement the findcontrol command and it works fine. But in mvc, I could hardly get the solutions how to do it. I already search online but can't find any articles that fits my needs for this type of issue. So far, what I've got is if I insert a data from a first row of the table it will insert the record but if I insert them from the second, third, and so fourth, it will no longer insert the records into my database table. How do I make this perfectly be working?
Heres my model,view and controller to help you resolve the issue. Thanks...
Model
public class CommentModel
{
public int Id { get; set; }
[Required(ErrorMessage="Don't miss to put your name.")]
public string name { get; set; }
[Required(ErrorMessage = "Don't leave your comments empty.")]
public string comment { get; set;}
}
public class ReplyModel
{
public int idrep { get; set; }
public string namerep { get; set; }
public string reply { get; set; }
}
public class CreateViewModel
{
public CommentModel CreateComment { get; set; } // this line is optional
public ReplyModel CreateReply { get; set; }
public List<CommentModel> Comments { get; set; }
public List<ReplyModel> Replies { get; set; }
}
Repository:
public class ReplyRepository
{
private ProfileDataContext3 Reprepository;
public ReplyRepository()
{
Reprepository = new ProfileDataContext3();
}
public IEnumerable<ReplyModel> GetAllComments()
{
List<ReplyModel> profiles = new List<ReplyModel>();
var prof = from profile in Reprepository.RepTabs
orderby profile.Id descending
select profile;
var user = prof.ToList();
foreach (var item in user)
{
profiles.Add(new ReplyModel()
{
idrep = item.Id,
namerep = item.Name,
reply = item.Replies
});
}
return profiles;
}
//declaring methods for inserting records
public void InsertReply(ReplyModel profile)
{
var details = new RepTab()
{
Id=profile.idrep,
Name = profile.namerep,
Replies = profile.reply
};
Reprepository.RepTabs.Add(details);
Reprepository.SaveChanges();
}
}
Controller
public ActionResult PostComment()
{
var vModel = new CreateViewModel();
vModel.Comments = comrepository.GetAllComments().ToList();
vModel.Replies = replyrepository.GetAllComments().ToList();
return View(vModel);
}
[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult PostComment(CommentModel com,string butname, ReplyModel rep)
{
switch(butname)
{
case "Post Comments":
if (ModelState.IsValid)
{
comrepository.InsertComment(com); //this is to insert the records
}
//this is to display the records inserted
var vModel = new CreateViewModel();
vModel.Comments = comrepository.GetAllComments().ToList();
vModel.Replies = replyrepository.GetAllComments().ToList();
return View(vModel);
case "Post Reply":
if (ModelState.IsValid)
{
replyrepository.InsertReply(rep); //this is to insert the records
}
//this is to display the records inserted
var vModel2 = new CreateViewModel();
vModel2.Comments = comrepository.GetAllComments().ToList();
vModel2.Replies = replyrepository.GetAllComments().ToList();
return View(vModel2);
default:
return null;
}
}
View
#model MyFirstMVCApp.Models.CreateViewModel
#{
ViewBag.Title = "PostComment";
}
<h2>Post Comment</h2>
<br />
#using (Html.BeginForm("PostComment", "Profile", FormMethod.Post, new { }))
{
#Html.ValidationSummary("Unable to Post Comment. Please correct the errors and try again...")
<fieldset>
<legend>CommentModel</legend>
<div class="editor-label">
<label for="name">Name</label>
</div>
<div class="editor-field">
<input type="text" id="name" name="name" />
<span class="field-validation-valid" data-valmsg-for="name" data-valmsg-replace="true"></span>
</div>
<div class="editor-label">
<label for="comment">Post your Comment here:</label>
</div>
<div class="editor-field">
<textarea id="comment" name="comment" style="width:500px;height:100px;resize:none" ></textarea>
<span class="field-validation-valid" data-valmsg-for="comment" data-valmsg-replace="true"></span>
</div>
<p>
<input type="submit" value="Post Comments" name="butname" />
#Html.ActionLink("See Comments", "DisplayComment")
</p>
<br />
</fieldset>
}
<br />
<h2>Comments</h2>
<br />
#using (Html.BeginForm("PostComment", "Profile", FormMethod.Post, new { }))
{
<table>
#foreach (var item in Model.Comments)
{
<tr>
<td>
<div class="editor-field" style="display:none;margin-bottom:10px;margin-top:10px">
#Html.TextBoxFor(m => m.CreateComment.Id)
</div>
<div style="font-weight:bold;"> #Html.DisplayFor(modelItem => item.name) </div>
<p style ="margin-top:0px;margin-bottom:0px; border-radius: 4px 4px 4px 4px; max-width :500px; min-height :5px; display :block; background-color: #CCCCFF"> #Html.DisplayFor(modelItem => item.comment) </p>
<p style="margin-top:2px;margin-bottom:0px"> <input type="button" id="like" name="like" value="Like" style="color:blue;border:0px;background-color:inherit;cursor:pointer" /> <input type="button" id="Reply" name="Reply" value="Replie(s)" style="color:blue;border:0px;background-color:inherit;cursor:pointer" /></p>
<div id="divrep" style="position:relative;left:50px; overflow:auto;margin-top:0px">
<table>
#foreach (var item2 in Model.Replies)
{
<tr>
<td>
<p style ="margin-top:0px;margin-bottom:0px; border-radius: 4px 4px 4px 4px; max-width :445px; min-height :5px; display :block; background-color: #CCCCFF;">#Html.DisplayFor(modelItem => item2.reply) </p>
<br />
</td>
</tr>
}
</table>
</div>
<input type="text" id="idrep" name="idrep" value="#Html.DisplayFor(modelItem=>item.Id)" />
<span class="field-validation-valid" data-valmsg-for="idrep" data-valmsg-replace="true"></span>
<br />
<input type="text" id="namerep" name="namerep" />
<span class="field-validation-valid" data-valmsg-for="namerep" data-valmsg-replace="true"></span>
<br />
<textarea id="reply" name="reply" style="width:500px;height:100px;resize:none" ></textarea>
<span class="field-validation-valid" data-valmsg-for="reply" data-valmsg-replace="true"></span>
<br />
<input type="submit" value="Post Reply" name="butname" />
</td>
</tr>
}
</table>
}
<br />
<br />
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section scripts
{
<script type ="text/jscript" src="JQuery/jquery-1.4.3.min.js">
</script>
<script type="text/javascript">
$('body').keypress(function(e) {
if (e.which == 13) {
$("input[value='Post Comments']").trigger('click');
}
});
</script>
}
The problem is the naming of your controls, you have multiple controls with the same name and the DefaultModelBinder will only bind the first one (i.e the first row) and ignore the rest. I suggest a different approach using jquery to post new comments and avoid having to refresh the page each time.
View
...
#using (Html.BeginForm()) {
<div>
#Html.LabelFor(m => m.CreateComment.Name)
#Html.TextBoxFor(m => m.CreateComment.Name)
#Html.ValidationMessageFor(m => m.CreateComment.Name)
// repeat for CreateComment.Comment property
<input type="submit" id="post-comment" value="Submit Comment" />
</div>
}
...
Script
$('form').submit(function(e) {
e.preventDefault(); // prevent submission
}
$('#post-comment').click(function() {
// get values for postback
var inputs = $(this).closest('div').find('input');
var name = inputs.first().val();
var comment = inputs.last().val();
var url = '#Url.Action("PostComment", "Profile")';
$.post(url, { Name: name, Comment: comment }, function(data) {
if(data) {
inputs.val(''); // clear existing inputs
// create a new element for the comment and add to the DOM, for example
var para = $('div></div>).text(comment).appendTo(something);
} else {
// display an error message
}
}
}
and add a similar script for posting replies, except use a class name not id for the button so there are no duplicate id's
Controller
[HttpPost]
public ActionResult PostComment(CommentModel model)
{
// save the comment and if successful
return Json(true);
else
return null;
}
For posting back replies, in your foreach loop, add a hidden input for the respective comment ID and include that in the data to post back to a separate action
[HttpPost]
public ActionResult PostReply(ReplyModel model)
{
...
Related
I have problem in edit view. When I debug my code, after Id is passed from ShowCategory view to EditPostGroup method in controller, it works correctly, but after page loads, Id zero is sent to the Edit method in controller and throws an error
Object reference not set to an instance of an object
This is my code: this method is in the PostRepository and get postGroup with Id from database :
public PostGroupViewModel GetPostGroupById(int postGroupId)
{
var postGroup = _context.PostGroups.Find(postGroupId);
PostGroupViewModel postGroupViewModel = new PostGroupViewModel()
{
GroupId = postGroup.GroupId,
GroupTitle = postGroup.GroupTitle,
GroupImageName = postGroup.GroupImageName,
IsDelete = postGroup.IsDelete,
ParentId = postGroup.ParentId
};
return postGroupViewModel;
}
These are Get and Post edit method in CategoryController:
[HttpGet]
public IActionResult EditPostGroup(int id)
{
var groups = _postService.GetGroupForManagePost();
ViewData["Groups"] = new SelectList(groups, "Value", "Text");
var postGroupViewModel = _postService.GetPostGroupById(id);
return View(postGroupViewModel);
}
[HttpPost]
public IActionResult EditPostGroup(PostGroup postGroup, IFormFile imgPostGroupUp)
{
if (!ModelState.IsValid)
return View("EditPostGroup");
_postService.UpdatePostGroup(postGroup, imgPostGroupUp);
return RedirectToAction("ShowCategory", "Category");
}
This is 'ShowCategory' View, It sends PostGroupId to Edit action method:
#{
ViewData["Title"] = "Category List";
}
<div class="row">
<div class="col-lg-12">
<h4 style="color:darkblue;" >Category List</h4>
</div>
<!-- /.col-lg-12 -->
</div>
<br />
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<br />
<div class="col-md-12" style="margin: 10px 0;">
<a asp-controller="Category" asp-action="CreateCategory" asp-area="Admin" class="btn btn-outline btn-success">Create Category</a>
</div>
<br />
<br />
<br />
<table class="table table-striped table-bordered table-hover dataTable no-footer text-center" id="dataTables-example" aria-describedby="dataTables-example_info">
<thead class="table-success black-ribon">
<tr>
<th>Title</th>
<th>Parent Category</th>
<th>Image</th>
<th>Operations</th>
</tr>
</thead>
<tbody>
#foreach (var item in #ViewBag.CategoryList)
{
<tr>
<td>
#item.GroupTitle
</td>
<td>
#item.ParentId
</td>
<td>
<img class="thumbnail" style="width:40px;height:40px;" src="/img/postGroup/#item.GroupTitle/#item.GroupImageName" alt="">
</td>
<td>
<a href="/Admin/Category/EditPostGroup/#item.GroupId" class="btn btn-primary btn-md">
Edit
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
This is the EditPostGroupView:
#model DataLayer.Models.ViewModels.PostGroup.PostGroupViewModel
#{
ViewData["Title"] = "Post Edit";
//Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<div class="row">
<form method="post" asp-action="EditPostGroup" enctype="multipart/form-data">
#* <input type="hidden" asp-for="GroupId" />*#
#*<input type="hidden" asp-for="Post.PostImageName"/>*#
<div class="col-md-8">
<h2>Category List</h2>
<hr/>
<div class="form-group">
<label>Title</label>
<input type="text" asp-for="GroupTitle" class="form-control">
<span asp-validation-for="GroupTitle"></span>
</div>
<div class="form-group">
<label>ParentId</label>
<select class="form-control" asp-for="ParentId" asp-items="#(ViewData["Groups"] as SelectList)">
<option value="">-- please select --</option>
</select>
<span asp-validation-for="ParentId"></span>
</div>
</div>
<div class="col-md-4">
<p></p>
<img id="imgPost" class="thumbnail" src="img/postGroup/#Model.GroupTitle/#Model.GroupImageName"/>
<div class="form-group">
<label>Select Image</label>
<input type="file" name="imgPostGroupUp" id="imgPostGroupUp">
</div>
</div>
<input type="submit" value="Edit" class="btn btn-success"/>
</form>
</div>
#section scripts
{
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#imgPost').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgPostUp").change(function () {
readURL(this);
});
</script>
}
This is the Routing in Program.cs:
app.MapControllerRoute(
name: "MyArea",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
This is PostGroup Model:
public class PostGroup
{
[Key]
public int GroupId { get; set; }
//public int? SubGroupId { get; set; }
public string GroupTitle { get; set; }
[MaxLength(50)]
public string? GroupImageName { get; set; }
public bool IsDelete { get; set; }
[Display(Name = "Category")]
public int? ParentId { get; set; }
[ForeignKey("ParentId")]
public List<PostGroup>? PostGroups { get; set; }
[InverseProperty("PostGroup")]
//[NotMapped]
public List<Post>? Posts { get; set; }
}
This is postGroupViewModel:
public class PostGroupViewModel
{
public int GroupId { get; set; }
public string GroupTitle { get; set; }
[MaxLength(50)]
public string? GroupImageName { get; set; }
public bool IsDelete { get; set; }
public int? ParentId { get; set; }
}
What is the problem?
Could it be a problem with the Program.cs and middleware?
I changed EditPostGroup(PostGroup postGroup, IFormFile imgPostGroupUp) method to
EditPostGroup(PostGroupViewModel postGroupViewModel, IFormFile imgPostGroupUp),but there is still a problem.
You can use a query string instead of passing the id in .net core:
[HttpGet]
public async Task<IActionResult> Edit()
{
string id = HttpContext.Request.Query["id"].ToString();
var model = await _service.FindAsync(int.Parse(id));
return View(model);
}
in razor view:
<a href="/service/edit?id=#item.ServiceId">
Also, using # in the src of a file in razor view causes this problem. remove it or give it a value.
<img id="img-master" class="thumbnail" src="#" />
to
<img id="img-master" class="thumbnail" src="/images/#Model.ImageEdit" />
I have modal form, but i am struggling to pull the table record from the database once a user first check radio button(EmailAddress) and puts a correct email from the Textbox, as soon click Next button it must prompt following columns Name, EmailAddress, LoginID, SSID and Institution. Below is my logic and need some help to put it back with data.
<pre> public class eNtsaRegPeopleLists
{
public string Name { get; set; }
[Key]
public int LoginID { get; set; }
public string Name {get;set;}
public string SISID { get; set; }
public string EmailAddress {get;set;}
public string Role { get; set; } // ignore this one from the View
public DateTime LastActivity { get; set; } // ignore this one from the View
public decimal TotalActivity { get; set; } // ignore this one from the View
public string Institution { get; set; }
}
<div class="form-group row">
<div class="col-sm-4">
<input type="radio" id="EmailAddress" name="choose" />
<label for="EmailAddress" class="col-form-label">EmailAddress</label>
</div>
<div class="col-sm-3">
<input type="radio" id="LoginID" name="choose" />
<label for="LoginID" class="col-form-label">LoginID</label>
</div>
<div class="col-sm-3">
<input type="radio" id="SIS_ID" name="choose"/>
<label for="SIS_ID" class="col-form-label">SIS_ID</label>
</div>
<div class="col-sm-12">
#Html.TextAreaFor(m => m.eNtsaAdmin.eNtsaTextAreaDisc, new { #class = "form-control", style = "font-size: medium; font-weight: bold; width:450px", id= "eNtsaTextAreaDisc" })
</div>
<hr />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter" id="btnNext">
Next
</button>
</div>
#foreach(var data in Model.regPeopleLists)
{
}
<div class="modal-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>EmailAddress</th>
<th>LoginID</th>
<th>SISID</th>
</tr>
</thead>
</table>
</div>
<script type="text/javascript">
$(document).ready(function () {
$(document).ready(function () {
// Fire when radio button clicked
$("#LoginID, #SIS_ID").bind("change", function () {
checkdata();
});
// Fire when we enter anything in the textbox
$("#eNtsaTextAreaDisc").bind("input", function () {
checkdata();
});
});
//here we check both radio button clicked and textbox filled with some information
function checkdata() {
if (($("#LoginID").prop("checked") || $("#SIS_ID").prop("checked")) && $("#eNtsaTextAreaDisc").val().length > 0) {
$("#btnNext").removeAttr("disabled");
}
else {
$("#btnNext").attr("disabled", "disabled");
}
}
</script>
Here is my Category.cs,
public class Category
{
public int Id { get; set; }
[Required, StringLength(100),Display(Name="Category Name")]
public string Name { get; set; }
[Display(Name="Category Description")]
public string Description { get; set; }
public bool IsActive { get; set; }
public IList<Style> Style { get; set; }
public IList<SubCategory> SubCategories { get; set; }
}
public class SubCategory
{
public int Id { get; set; }
public string Value { get; set; }
}
public class IndexModel : PageModel
{
[Microsoft.AspNetCore.Mvc.BindProperty]
public Category ViewModel { get; set; }
public void OnGet()
{
// You can fill your ViewModel property here.
}
public void OnPost()
{
// You can read your posted ViewModel property here.
}
}
And DbContext.cs
public DbSet<Category> Categories { get; set; }
public DbSet<SubCategory> SubCategory { get; set; }
And AddCategory.cshtml
#model UretimPerformans.Entity.Admin.IndexModel
#{
ViewData["Title"] = Localizer["addca"];
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
#section Scripts{
<link href="~/dist/plugins/bootstrap-switch/css/bootstrap3/bootstrap-switch.min.css" rel="stylesheet" />
<script src="~/js/jquery-3.5.1.js"></script>
<style>
td, tr {
text-align: center;
vertical-align: middle;
}
</style>
}
#section Scripts2{
<script src="~/dist/plugins/bootstrap-switch/js/bootstrap-switch.js"></script>
<script>
$("#btnSearch").click(function () {
var t = null;
t = $("#tab_logic tbody tr").get().map(function (tr) {
return $(tr).find("input").get().map(function (input) {
return input.value
})
})
$("#regTitle").html(t);
});
</script>
<script>
$(document).ready(function () {
var i = 1;
$("#add_row").click(function () {
$('#addr' + i).html("<td>" + (i + 1) + "</td><td><input name='name" + i + "' required type='text' placeholder='SubCategory-" + i + "' class='form-control input-md' /> </td><td><input name='mail" + i + "' type='checkbox' placeholder='IsActive' class='form-control'></td>");
$('#tab_logic').append('<tr id="addr' + (i + 1) + '"></tr>');
i++;
});
$("#delete_row").click(function () {
if (i > 1) {
$("#addr" + (i - 1)).html('');
i--;
}
});
});
$(function () {
$("input[data-bootstrap-switch]").each(function () {
$(this).bootstrapSwitch('state', $(this).prop('checked'));
});
})
</script>
}
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>#Localizer["addca"]</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a asp-action="Index" asp-controller="Home">#Localizer["anasayfa"]</a></li>
<li class="breadcrumb-item"><a asp-action="Index" asp-controller="Catalog">#Localizer["cat"]</a></li>
<li class="breadcrumb-item"><a asp-action="Categories" asp-controller="Catalog">#Localizer["ca"]</a></li>
<li class="breadcrumb-item active">#Localizer["addca"]</li>
</ol>
</div>
</div>
</div>
</section>
<section class="content">
<div class="card">
<div class="card-body">
<form asp-action="AddCategories" asp-controller="Catalog" method="post">
<div class="form-group row">
<span class="col-md-3">#Localizer["name"]</span>
<div class="col-md-9">
<input type="text" class="form-control" asp-for="ViewModel.Name" required />
</div>
</div>
<div class="form-group row">
<span class="col-md-3">#Localizer["desc"]</span>
<div class="col-md-9">
<textarea type="text" id="regTitle" class="form-control" asp-for="ViewModel.Description" required></textarea>
</div>
</div>
<div class="form-group row">
<span class="col-md-3">#Localizer["aktif"]</span>
<div class="col-md-9">
<input type="checkbox" asp-for="ViewModel.IsActive" checked data-bootstrap-switch data-off-color="danger" data-on-color="success">
</div>
</div>
<fieldset class="module">
<h4>#Localizer["alt"]</h4>
<button id="btnSearch">Click</button>
<a id="add_row" class="btn btn-default pull-left">Add Row</a>
<a id='delete_row' class="pull-right btn btn-default">Delete Row</a>
<hr />
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
#
</th>
<th class="text-center">
SubCategoryName
</th>
<th class="text-center">
IsActive
</th>
</tr>
</thead>
<tbody>
<tr id='addr0'>
<td>1</td>
<td>
<input asp-for="ViewModel.SubCategories[1].Value" />
#Model.ViewModel.SubCategories[1].Value
</td>
</tr>
<tr id='addr0'>
<td>
1
</td>
<td>
<input type="text" name='name0' placeholder='Name' class="form-control" />
</td>
<td>
<input type="checkbox" name='mail0' placeholder='Mail' class="form-control" />
</td>
</tr>
<tr id='addr1'></tr>
</tbody>
</table>
</div>
</div>
</fieldset>
<div class="card-footer">
<button type="submit" class="btn btn-primary">#Localizer["kaydet"]</button>
</div>
</form>
</div>
</div>
</section>
And CategoryController,
[HttpGet]
public IActionResult AddCategories()
{
return View();
}
[HttpPost]
public IActionResult AddCategories(Category entity)
{
if (ModelState.IsValid)
{
categoryRepository.AddCategory(entity);
TempData["success"] = "Başarıyla kaydedildi.";
return RedirectToAction("Categories");
}
else
{
return View(entity);
}
}
My codes are as above. What I want to do is add subcategories from the table at the bottom of the category when adding a category. but I could not set up the model. and I could not write the post method and reading method in indexmodel.
Please can you help me?
Thank you
Kind Regards
I don’t understand the meaning of name0 and name1..., neither Category nor SubCategory have this attribute. In addition, if you add SubCategoryName by adding a row in the table, this SubCategory class does not have the attribute 'IsActive'.
If you only want to add SubCategories through the rows of the table, you can follow this example.
Here I simulate some data.
public class IndexModel : PageModel
{
[Microsoft.AspNetCore.Mvc.BindProperty]
public Category ViewModel { get; set; }
public void OnGet()
{
ViewModel = new Category
{
Id = 1,
Description = "desc",
IsActive = false,
Name="name",
SubCategories=new List<SubCategory>
{
new SubCategory
{
Id=10,Value="val"
},
new SubCategory
{
Id=20,Value="val2"
},
new SubCategory
{
Id=30,Value="val3"
},
}
};
// You can fill your ViewModel property here.
}
}
I find discorrect asp-controller here.
Because the name in the form starts with 'ViewModel', the mapped model should be modified like this.
[HttpPost]
public IActionResult AddCategories(Category ViewModel)
{
//...
return Json(ViewModel);
}
Then, the result is as follows.
I'm trying to pass 5 optional values to my controller
public class ActivityManagementTwoFiltersModel
{
public string timeFilter { get; set; } = "Last 30 days";
public int numberOfItemsToReturn { get; set; } = 25;
public DateTime? dateStart { get; set; } = null;
public DateTime? dateEnd { get; set; } = null;
public Guid? districtId { get; set; } = null;
}
my controller is like this
public async Task<ActionResult> ActivityManagementTwo( ActivityManagementTwoFiltersModel filters)
my view:
#{using (Html.BeginForm("ActivityManagementTwo", "CallCenter", FormMethod.Get, new { id = "ActivityTwoForm" }))
{
<div class="row ">
<div class="col-md-12" style="float:right;">
<div class="dateWrapper">#{Html.RenderPartial("_DateFilter"); }</div>
</div>
</div>
<div class="row" style="margin-top: 10px; margin-bottom: 8px;">
<div class="col-md-3 ActivityManagementTwoHeader" style="font-size:12px; font-weight: bold">
Displaying Results #Model.Count() of #Model.Count()
</div>
<div class="col-md-3">
Items per page:
#Html.DropDownList("numberOfItemsToReturn", new List<SelectListItem> {
new SelectListItem { Value = "25", Text= "25"},
new SelectListItem { Value = "50", Text= "50"},
new SelectListItem { Value = "100", Text= "100"},
})
</div>
</div>
}
}
I want to hit my controller from the main view or partial view whenever one of the dropdown menu's is changed. I tried a JS function but it didn't submit the values
document.getElementById("numberOfItemsToReturn").addEventListener("change", function () {
document.getElementById("ActivityTwoForm").submit();
})
didn't work. How can I pass the controller the parameters from the drop down menu's on change?
edit: Here's my partial view. The partial View fields are being sent , it's only the numberOfItemsToReturn that are not
<table>
<tr>
<td style="text-align:right; vertical-align: top; width: 160px">
Time filter:
</td>
<td style="display:inline-block; width:150px" >
<input id="radio1" name="radioToggle" type="radio"> Recent
<select id="timeFilter" name="timeFilter" >
<option value="Last 30 days">at least 18</option>
</select>
<br />
<input id="radio2" name="radioToggle" class="radioTimeFilter" type="radio"> Date Range
<div id="dateContent" class="radio-content" style="display:none;">
<input id="txtDateOneFilter" type="text" style="width: 70px;" placeholder="Start Date" name="dateStart"/> to
<input id="txtDateTwoFilter" type="text" style="width: 70px;" placeholder="End Date" name="dateEnd" />
</div>
<br />
</td>
</tr>
</table>
Add [HttpPost] to the action
[HttpPost]
public async Task<ActionResult> ActivityManagementTwo( ActivityManagementTwoFiltersModel filters)
then fix your form
#{using (Html.BeginForm("ActivityManagementTwo", "CallCenter", FormMethod.Post))
Add Submit button to the form to test it
<input type="submit" value="Send" />
#Html.DropDownList(m => m.numberOfItemsToReturn, new List<SelectListItem> {
new SelectListItem { Value = "25", Text= "25"},
new SelectListItem { Value = "50", Text= "50"},
I'm a student using ASP.NET Core and related technologies for the first time. I've spent hours searching for a solution to this problem with no luck, so if anyone could help or point me at a tutorial to fix this, I would be very grateful.
My group and I are trying to build a web app to interface with an existing SQL database which has a lot of tables using concatenated primary keys. We can't change that. I used this tutorial to get our CRUD edit pages to even show, but if I try to submit any changes via that Edit page, I get an error like this:
No webpage was found for the web address: https://localhost:44311/GenCollectionSamplers/Edit
After some debugging, we're pretty sure this is a problem with the POST Edit method in the Controller getting null IDs, but we cannot figure out how to pass the correct IDs into the POST Edit method. The IDs are present in the GET Edit message.
Let me know if more code is needed.
Edit GET and POST from Controller:
// GET: GenCollectionSamplers/Edit/5
public async Task<IActionResult> Edit(double? peopleID, double? colID)
{
if (peopleID == null || colID == null)
{
return NotFound();
}
var genCollectionSamplers = await _context.GenCollectionSamplers.FindAsync(peopleID, colID);
if (genCollectionSamplers == null)
{
return NotFound();
}
ViewData["FkPeopleId"] = new SelectList(_context.GenPeople, "PkPeopleId", "PkPeopleId", genCollectionSamplers.FkPeopleId);
ViewData["FkCollectionId"] = new SelectList(_context.GenCollections, "CollectionId", "CollectionId", genCollectionSamplers.FkCollectionId);
return View(genCollectionSamplers);
}
// POST: GenCollectionSamplers/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(double peopleID, double colID, [Bind("FkPeopleId,FkCollectionId")] GenCollectionSamplers genCollectionSamplers)
{
//Causes error because peopleID and colID are 0
if (peopleID != genCollectionSamplers.FkPeopleId || colID != genCollectionSamplers.FkCollectionId)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(genCollectionSamplers);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!GenCollectionSamplersExists(genCollectionSamplers.FkPeopleId) || !GenCollectionSamplersExists(genCollectionSamplers.FkCollectionId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["FkPeopleId"] = new SelectList(_context.GenPeople, "PkPeopleId", "PkPeopleId", genCollectionSamplers.FkPeopleId);
ViewData["FkCollectionId"] = new SelectList(_context.GenCollections, "CollectionId", "CollectionId", genCollectionSamplers.FkCollectionId);
return View(genCollectionSamplers);
}
Model:
public partial class GenCollectionSamplers
{
[Required]
[Display(Name = "Fk People Id")]
public double FkPeopleId { get; set; }
[Required]
[Display(Name = "Fk Collection Id")]
public double FkCollectionId { get; set; }
[Required]
[Display(Name = "Fk Collection")]
public GenCollections FkCollection { get; set; }
[Required]
[Display(Name = "Fk People")]
public GenPeople FkPeople { get; set; }
}
Edit view:
#model {path removed}.Models.GenCollectionSamplers
#{
ViewData["Title"] = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
<h4>GenCollectionSamplers</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FkCollectionId" class="control-label"></label>
<input asp-for="FkCollectionId" class="form-control" />
<span asp-validation-for="FkCollectionId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FkPeopleId" class="control-label"></label>
<input asp-for="FkPeopleId" class="form-control" />
<span asp-validation-for="FkPeopleId" class="text-danger"></span>
</div>
<input type="hidden" asp-for="FkPeopleId" />
<input type="hidden" asp-for="FkCollectionId" />
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Part of Index view:
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => efModel.FkCollectionId)
</th>
<th>
#Html.DisplayNameFor(model => efModel.FkPeople)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FkCollection.CollectionId)
</td>
<td>
#Html.DisplayFor(modelItem => item.FkPeople.PkPeopleId)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { peopleID = item.FkPeopleId, colID = item.FkCollectionId }) |
#Html.ActionLink("Details", "Details", new { peopleID = item.FkPeopleId, colID = item.FkCollectionId }) |
#Html.ActionLink("Delete", "Delete", new { peopleID = item.FkPeopleId, colID = item.FkCollectionId })
</td>
</tr>
}
</tbody>
</table>
Why do you have the hidden fields on your Edit view:?
<input type="hidden" asp-for="FkPeopleId" />
<input type="hidden" asp-for="FkCollectionId" /
It is this that gets bound to the Model when you submit the HttpPost and since they do not have any values assigned, you are getting 0. Get rid of these two hidden fields. The rendered page will create the hidden fields at run-time (inspect your rendered markup for Edit page) along with __RequestVerificationToken that knows which instance of this Model should be validated and then updated.