MVC Pass value from view to dynamic partial view - c#

I'm trying to make a partial view, which will add dynamically as much fields as I input. I input number of fields, then I want to choose days of week in formed fields and do some work with this data in controller, but I have a problem with passing amount of days in partial view.
Controller :
public class CoursesController : Controller
{
private SchoolContext db = new SchoolContext();
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "CourseId,Name,Language,LanguageProficiency,StartDate,EndDate,TeacherId,NumberOfLessonsPerWeek")] Course course)
{
if (ModelState.IsValid)
{
db.Courses.Add(course);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(course);
}
public ActionResult ShowDaysOfweek(int? countDays)
{
//countDays = 2;
ViewBag.CountDays = countDays;
var days = new List<DayOfWeek> { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
ViewBag.DaysOfWeek = new SelectList(days);
return PartialView("ShowDaysOfweek");
}
}
In this View I can add patial view by clicking button in script:
#model SchoolManagementSystem.Models.Course
#using (Ajax.BeginForm(new AjaxOptions { }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" }
<div class="form-group">
#Html.Label("Number Of Lessons Per Week", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-5">
#Html.TextBox("NumberOfLessonsPerWeek", null, htmlAttributes: new { #class = "form-control", #type = "number", #id = "numberOfLessonsPerWeek" })
</div>
<div>
<input type="button" value="Add days" id="Show" class="btn btn-default" />
</div>
</div>
<div id="ShowResults">
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<script type="text/javascript">
var url = '#Url.Action("ShowDaysOfweek", "Courses")';
$('#Show').on("click", function () {
var countDays = $('#numberOfLessonsPerWeek').val();
url += '/?countDays=' + countDays;
$('#ShowResults').load(url);
})
</script>
Partial view:
#for (var i = 0; i < ViewBag.CountDays; i++)
{
<div class="form-group">
#Html.Label("Day of week", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-5">
#Html.DropDownList("DaysOfWeek", (IEnumerable<SelectListItem>)ViewBag.DaysOfWeek, htmlAttributes: new { #class = "form-control", style = "height: 35px" })
</div>
</div>
}
Is it possible to do something? Thanks!

First create the hidden field with partial view url
<input type="hidden" value="#Url.Action("ShowDaysOfweek", "Courses", new { countDays= "numberOfLessonsPerWeek" })" id="hdnURLShowDaysOfweek" />
in javascript read the url and replace the parameter
<script type="text/javascript">
var url = $('#hdnURLShowDaysOfweek').val();
$('#Show').on("click", function () {
url = url.replace("numberOfLessonsPerWeek",$('#numberOfLessonsPerWeek').val());
$('#ShowResults').load(url);
})
</script>

Related

Can't load image to partial view in edit view

In my application, previously I had issue with loading data to the partial view. With help I resolved that it. But still there is some issue here. Now when create the request I use this partial view to add data and image for user.
#model Asp_PASMVC.Models.GeneralItms
#using Asp_PASMVC.Infrastructure
#{
var z = Model.Attachment_Description;
var a = Model.Attachment_Amount;
var x = Model.Attachment;
}
<li style="padding-bottom:15px">
#using (Html.BeginCollectionItem("GeneralItmsList"))
{
#Html.HiddenFor(model => model.TempID)
<div class="form-horizontal" id="quickForm" novalidate="novalidate">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="row">
<div class="col-md-5 col-sm-6">
<div class="form-group">
Select Item Description
<div class="col-md-10">
#Html.EditorFor(model => model.Attachment_Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Attachment_Description, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-3 col-sm-6">
<div class="form-group">
Attachment Amount
<div class="col-md-10">
<div class="input-group-prepend">
<span class="input-group-text">Rs.</span>
#Html.EditorFor(model => model.Attachment_Amount, new { htmlAttributes = new { #class = "form-control" } })
</div>
#Html.ValidationMessageFor(model => model.Attachment_Amount, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="col-md-3 col-sm-6">
<div class="form-group">
Attachment
<div class="col-md-10">
<input type="file" name="ImageData#(Model.TempID.ToString())" id="ImageData#(Model.TempID.ToString())" multiple="multiple" data-id="Img#(Model.TempID.ToString())" onchange="checkImage(this)" />
#Html.ValidationMessageFor(model => model.Attachment, "", new { #class = "text-danger" })
</div>
</div>
<img id="Img#(Model.TempID.ToString())" src="" alt="" width="100" height="100" class="ml-1" />
</div>
<button type="button" class="btn btn-danger" onclick="$(this).parent().remove();">Remove</button>
</div>
</div>
}
</li>
<script type="text/javascript">
$('.js-dropdown').select2({
width: '100%', // need to override the changed default
});
function checkImage(obj) {
var fileExtension = ['jpeg', 'jpg', 'png', 'gif', 'bmp'];
var ResponceImgId = $(obj).data('id');
if ($.inArray($(obj).val().split('.').pop().toLowerCase(), fileExtension) == -1) {
alert('error', 'Upload Error', 'Only .jpeg, .jpg, .png, .gif, .bmp formats are allowed.');
}
else {
var files = obj.files;
var reader = new FileReader();
name = obj.value;
reader.onload = function (e) {
$('#' + ResponceImgId).prop('src', e.target.result);
};
reader.readAsDataURL(files[0]);
}
}
</script>
When creating the request in the controller I have code like this
if (appRequest.GeneralItmsList != null)
{
foreach (GeneralItms item in appRequest.GeneralItmsList)
{
HttpPostedFileBase file = Request.Files["ImageData" + item.TempID];
item.Attachment = ConvertToBytes(file);
}
appRequest.General = new List<General>()
{
new General
{
GeneralItms = appRequest.GeneralItmsList,
}
};
}
and this method will convert the image to byte and pass to the controller to submit the data.
public ActionResult RetrieveImageG(int id)
{
var q = from temp in db.GeneralItms where temp.Id == id select temp.Attachment;
byte[] cover = q.First();
if (cover != null)
{
return File(cover, "image/jpg");
}
else
{
return null;
}
}
So Crete is working fine, and when in the edit view, I again called the same partial view to load the data inside the edit main view.
It's has 3 fields. Item Description , Amount and the attachment.
So It's loading the Item Description and amount properly, and it won't load the image again. Within the partial view I have put
#{
var z = Model.Attachment_Description;
var a = Model.Attachment_Amount;
var x = Model.Attachment;
}
to check is data passing to the view. attachment is shown in the Model.Attachment. But it won't show in the view. Can I get a help on this?
if you already happen to have the image loaded in your model: doing this way you can display the image
<img src="data:image;base64,#System.Convert.ToBase64String(Model.Attachment)" />

Update user Profile in asp.net mvc model is not valid

I'm a beginner to ASP.NET MVC.
I want to update login user profile and I am having a problem. my code says model state is not valid. I've tried every possible solution which I know and also searched on Google.
I'm using Entity Framework and below is my code.
Table name: Userdb
Get action method in the controller:
public ActionResult EditProfile()
{
string username = User.Identity.Name;
Userdb user = db.Userdbs.FirstOrDefault(u => u.u_Email.Equals(username));
Userdb model = new Userdb();
// Personal Details
model.u_Firstname = user.u_Firstname;
model.u_lastname = user.u_lastname;
model.u_dob = user.u_dob;
model.u_mobile = user.u_mobile;
model.u_title = user.u_title;
// this to display data in texbox
ViewBag.u_Email = user.u_Email;
ViewBag.u_Firstname = user.u_Firstname;
ViewBag.u_lastname = user.u_lastname;
ViewBag.u_dob = user.u_dob;
ViewBag.u_mobile = user.u_mobile;
ViewBag.u_title = user.u_title;
// Education Details
model.Degree_level = user.Degree_level;
model.Degree_name = user.Degree_name;
model.Starting_date = user.Starting_date;
model.Completion_date = user.Completion_date;
// Address Details
model.country_name = user.country_name;
model.city_name = user.city_name;
model.Address = user.Address;
model.postal_code = user.postal_code;
// Social Link Details
model.S_fb_url = user.S_fb_url;
model.S_linkedin_url = user.S_linkedin_url;
model.S_github_url = user.S_github_url;
model.S_twitter_url = user.S_twitter_url;
return View(model);
}
Post action method in controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditProfile(Userdb editEntity)
{
if (ModelState.IsValid)
{
string username = User.Identity.Name;
// Get the userprofile
Userdb model =new Userdb();
// Personal Details
model.u_Firstname = editEntity.u_Firstname;
model.u_lastname = editEntity.u_lastname;
model.u_dob = editEntity.u_dob;
model.u_mobile = editEntity.u_mobile;
model.u_title = editEntity.u_title;
ViewBag.u_Email = editEntity.u_Email;
ViewBag.u_Firstname = editEntity.u_Firstname;
ViewBag.u_lastname = editEntity.u_lastname;
ViewBag.u_dob = editEntity.u_dob;
ViewBag.u_mobile = editEntity.u_mobile;
ViewBag.u_title = editEntity.u_title;
// Education Details
model.Degree_level = editEntity.Degree_level;
model.Degree_name = editEntity.Degree_name;
model.Starting_date = editEntity.Starting_date;
model.Completion_date = editEntity.Completion_date;
// Address Details
model.country_name = editEntity.country_name;
model.city_name = editEntity.city_name;
model.Address = editEntity.Address;
model.postal_code = editEntity.postal_code;
// Social Link Details
model.S_fb_url = editEntity.S_fb_url;
model.S_linkedin_url = editEntity.S_linkedin_url;
model.S_github_url = editEntity.S_github_url;
model.S_twitter_url = editEntity.S_twitter_url;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Home"); // or whatever
}
return View();
}
View
#model Applicant.Models.Userdb
#{
ViewBag.Title = "EditProfile";
Layout = "~/Views/Shared/_ProfileLayout.cshtml";
}
#using (Html.BeginForm("EditProfile", "Users"))
{
#Html.AntiForgeryToken()
<body>
<div class="container rounded bg-white mt-5 mb-5">
<div class="row">
<div class="col-md-3 border-right">
<div class="d-flex flex-column align-items-center text-center p-3 py-5"><img class="rounded-circle mt-5" width="150px" src="https://st3.depositphotos.com/15648834/17930/v/600/depositphotos_179308454-stock-illustration-unknown-person-silhouette-glasses-profile.jpg"><span class="font-weight-bold">#ViewBag.u_Firstname #ViewBag.u_lastname</span><span class="text-black-50">#ViewBag.u_Email</span><span> </span></div>
</div>
<div class="col-md-5 border-right">
<div class="p-3 py-5">
<div class="d-flex justify-content-between align-items-center mb-3">
<h4 class="text-right">Profile Settings</h4>
</div>
<h6>Personal Detail</h6>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Name</label>#Html.EditorFor(model => model.u_Firstname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_Firstname } })</div>
<div class="col-md-6"><label class="labels">Lastname</label>#Html.EditorFor(model => model.u_lastname, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_lastname } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6">
<label class="labels">Gender</label><br />
#Html.RadioButtonFor(model => model.u_Gender, "F")
Female
#Html.RadioButtonFor(model => model.u_Gender, "M")
Male
</div>
<div class="col-md-6"><label class="labels">Designation</label>#Html.EditorFor(model => model.u_title, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_title } })</div>
</div>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Mobile Number</label>#Html.EditorFor(model => model.u_mobile, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.u_mobile } })</div>
<div class="col-md-12"><label class="labels">Address</label>#Html.EditorFor(model => model.Addres, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Addres } })</div>
<div class="col-md-12"><label class="labels">Country</label>#Html.EditorFor(model => model.country_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.country_name } })</div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">City</label>#Html.EditorFor(model => model.city_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.city_name } })</div>
<div class="col-md-6"><label class="labels">Postal Code</label>#Html.EditorFor(model => model.postal_code, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.postal_code } })</div>
</div>
<hr />
<h6>Education Detail</h6>
<div class="row mt-3">
<div class="col-md-12"><label class="labels">Degree Name</label>#Html.EditorFor(model => model.Degree_name, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_name } })</div>
<div class="col-md-12"><label class="labels">Degree Level</label>#Html.EditorFor(model => model.Degree_level, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Degree_level } })></div>
</div>
<div class="row mt-2">
<div class="col-md-6"><label class="labels">Starting Date</label>#Html.EditorFor(model => model.Starting_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Starting_date } })</div>
<div class="col-md-6"><label class="labels">Completion Date</label>#Html.EditorFor(model => model.Completion_date, new { htmlAttributes = new { #class = "form-control", placeholder = #ViewBag.Completion_date } })</div>
</div>
<hr />
<div class="mt-5 text-center">
<input type="submit" value="Save Changes" class="btn" style="background-color:#5777ba; color:#fff;" />
</div>
</div>
</div>
<div class="col-md-4">
<div class="py-5">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Skills</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
<div class="">
<h6>Skills Detail</h6>
<div class="col-md-12"><label class="labels">Github Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Linkedin Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Twitter Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
<div class="col-md-12"><label class="labels">Facebook Link</label><input type="text" class="form-control" placeholder="experience" value=""></div>
</div>
</div>
</div>
</div>
</body>
}
There are several problems with your view, which could account for the invalid model. If you post the definition of Userdb, complete with any metadata class (if those are still being used) we could see for sure.
First, you aren't putting the necessary name attribute in all your plain input fields. This means they won't get posted to the server as data, so the model binder won't be able to automatically populate those fields in your model.
Second, you've used #Html.EditorFor() in several places, with the identical properties being referenced. This means that what you put in the text box labeled "Name" will be assigned to the u_Firstname field on your model -- but so will what you've put in the "Gender" and "City" fields!
That means that the actual Gender and City properties on your model won't be populated.
Third, you say u_Email is the primary key, but it isn't even posted back from this form.
This brings me to what I suspect the real source of the problem is: your model isn't being fully populated from the form on posting, because you're not collecting all the data. And I'd guess at least some of those properties have Required or other constraints on them that mean leaving them empty isn't allowed. (u_Email is a likely candidate, since it's the primary key.)
If you look at the contents of editEntity while debugging, it will probably be made very clear what's populated and what isn't.
replace this code
db.Entry(model).State = EntityState.Modified;
with
db.Entry(model).State = System.Data.Entity.EntityState.Modified;
the above whole code is true but the main problem is when you change the state of entity EntityState.Modified should be replaced with System.Data.Entity.EntityState.Modified; because EntityState is an object of System.Data.Entity* namespace

Submitting a form in asp .net MVC, various errors

[HttpGet]
public ActionResult TrafficDate()
{
CalendarModel model = new CalendarModel();
model.SelectedDate = DateTime.Today;
model.EditMode = false;
//model.TrafficDates = TrafficData.GeTrafficDatesPerMonth(model.SelectedDate);
return View(model);
}
// GET: TrafficDate
[HttpGet]
public ActionResult TrafficDate(DateTime date, bool editMode = false)
{
CalendarModel model = new CalendarModel();
model.SelectedDate = date;
model.EditMode = editMode;
//model.TrafficDates = TrafficData.GeTrafficDatesPerMonth(model.SelectedDate);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TrafficDate(CalendarModel model)
{
The topmost ActionResult was added because it kept complaining that there was no parameterless method. now it complains that there is an ambiguity between the two methods that have HttpGet in the tag above, when I switch the parameterless to be HttpPost instead, then I get the same thing between the two that are HttpPost.
I want my submit button to go to the bottom method of the three. but it seems it wants a parameterless method, does that mean the model is empty when I click submit?
here's a part of the .cshtml file
#model Intern.Models.CalendarModel
#{
ViewBag.Title = "Trafikkalender";
//Layout = "_Layout";
}
<script>
</script>
<form method="post" id="form">
<div id="hiddenFields" hidden="hidden">
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.SelectedDate)
#Html.HiddenFor(m => m.EditMode, new { id = "editMode" })
#Html.HiddenFor(m => m.SubmitMode, new { id = "submitMode" })
#Html.HiddenFor(m => m.RegisterPersonOnThisResourceId, new { id = "registerForResourceId" })
#Html.HiddenFor(m => m.PersonToRegister, new { id = "selectedPerson" })
#Html.HiddenFor(m => m.TimeFrom, new { id = "hiddenTimeFrom" })
#Html.HiddenFor(m => m.TimeTo, new { id = "hiddenTimeTo" })
#Html.HiddenFor(m => m.Message, new { id = "hiddenMessage" })
#Html.HiddenFor(m => m.NewTrafficType, new { id = "hiddenNewTrafficType" })
#Html.HiddenFor(m => m.NewTrafficText, new { id = "hiddenNewTrafficText" })
#Html.HiddenFor(m => m.NewTrafficNumTrains, new { id = "hiddenSelectedNewTrafficNumTrains" })
#Html.HiddenFor(m => m.NewTrafficNumConductors, new { id = "hiddenSelectedNewTrafficNumConductors" })
#Html.HiddenFor(m => m.CopyTraffic, new { id = "hiddenCopyTraffic" })
#Html.HiddenFor(m => m.NewTrafficDate, new { id = "hiddenNewTrafficDate" })
</div>
<div class="panel panel-default">
<div class="panel-body">
<div class="panel-heading">
<h1 id="header" class="page-header">Trafik - #((DayNames)((int)Model.SelectedDate.DayOfWeek)) den #Model.SelectedDate.Day #((MonthNames)Model.SelectedDate.Month) #Model.SelectedDate.Year</h1>
</div>
<div class="row">
<div class="col-md-8"></div>
<div class="col-md-4">
#Html.ActionLink("Föregående dag", "TrafficDate", new { date = Model.SelectedDate.AddDays(-1), editMode = Model.EditMode }, new { #class = "btn btn-primary" })
#Html.ActionLink("Nästa dag", "TrafficDate", new { date = Model.SelectedDate.AddDays(1), editMode = Model.EditMode }, new { #class = "btn btn-primary" })
</div>
</div>
</div>
</div>
<div class="panel">
#if (UserData.isInRole(Convert.ToInt32(User.Identity.Name), "Administratör"))
{
<div class="row">
<div class="col-lg-12">
#Html.ActionLink("Redigera dag(beta)", "ToggleEditMode", "TrafficDate", new { date = Model.TrafficDate.Date, editMode = Model.EditMode }, new { #class = "btn btn-primary" })
<input onclick="javascript: EditDay();" type="button" value="Redigera dag" id="editDayButton" name="editDayButton" class="btn btn-primary" />
<input onclick="javascript: CancelEditDay();" type="button" value="Avsluta redigering" id="cancelEditDayButton" name="cancelEditDayButton" class="btn btn-primary hidden" />
#Html.ActionLink(" ", "PrintDay", new { date = Model.SelectedDate.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) }, new { #class = "glyphicon glyphicon-print" })
</div>
</div>
}
#if (Model.EditMode)
{
<div class="panel panel-default">
<div class="panel-body">
#for (int ti = 0; ti < Model.TrafficDate.Traffics.Count; ti++)
{
<div class="panel panel-default form-group">
<div class="panel-heading">
#(Html.DropDownListFor(m => m.TrafficDate.Traffics[ti].TrafficType, TrafficData.GetTrafficTypes(Model.TrafficDate.Traffics[ti].TrafficType.ToString()), new { #class = "ddlTrafficType", #id = "ddlTrafficType_" + ti }))
#Html.CheckBoxFor(m => m.TrafficDate.Traffics[ti].Published, new { #class = "cbTrafficPublished", #id = "cbPublished_" + ti }) Publicerad
[<input type="button" value="Radera" class="deleteTraffic btn btn-link NoBorder NoBackGround" data-id="#Model.TrafficDate.Traffics[ti].Id" data-url="#Url.Action("DeleteTraffic")" data-confirm="Är du säker på att du vill radera denna trafik?" />]
<input type="button" class="saveTraffic btn btn-primary btn-sm float-right" value="Spara (#Model.TrafficDate.Traffics[ti].TrafficType.ToString())" data-url="#Url.Action("SaveTraffic")" data-id="#Model.TrafficDate.Traffics[ti].Id" data-confirm="Är du säker på att du vill skriva över de nuvarande inställningarna på denna trafik?" />
<input type="submit" class="btn btn-primary" value="Save traffic (beta)" />
</div>
the submit button is on the second to last line of the code cutout here.
is the problem in my .cshtml file? or have I defined the controller methods wrong in some way? the hiddenfields in the beginning was for a javascript I made to handle the saving of things, but I want to get rid of the javascript and make this the correct way.
Also. the form-group class in the code, I saw that in an example, is that important? do I need that in every div? or is it enough to have it in the div that surrounds the whole block of html involved in the thing I want to submit?
As discussed
[HttpGet]
public ActionResult TrafficDate(DateTime? date, bool? editMode = false)
{
return View();
}
Then remove the parameterless TrafficDate action leaving only your post.
I've tried locally and it seems ok
thanks

Passing a List of objects from Razor View to Controller only passes one item instead of the whole list

I want to pass a List of VoedingBindingModel to my controller by using an Editor Template, however I only receive the first entry of the List in the Controller, never all the entries.
The Controller:
public ActionResult Create()
{
ViewBag.fk_customVoedingId = new SelectList(customvoeding.GetAllCustomvoeding(), "customVoedingId", "customVoedingNaam");
ViewBag.fk_standaardVoedingId = new SelectList(standaardvoeding.GetAllStandaardvoeding(), "standaardVoedingId", "standaardVoedingNaam");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Datum,Tijd,VoedingCollection")]AgendaBindingModel agendaBindingModel)
{
//Do something
}
The Model:
public class AgendaBindingModel
{
[Required]
public List<VoedingBindingModel> VoedingCollection { get; set; }
//More properties
}
The View:
#using Website.Models
#model AgendaBindingModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>agenda</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Datum, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Datum, "{0:dd-MM-yyyy}", new { #class = "form-control-datepicker", placeholder = "DD-MM-YYYY", maxlength = "10" })
#Html.ValidationMessageFor(model => model.Datum, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Tijd, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Tijd, "{0:hh:mm}", new { htmlAttributes = new { #class = "form-control-timepicker", placeholder = "hh:mm", maxlength = "5" } })
#Html.ValidationMessageFor(model => model.Tijd, "", new { #class = "text-danger" })
</div>
</div>
<div id="CreateVoedingDiv0">
#Html.EditorFor(x => x.VoedingCollection[0])
</div>
<div id="CreateVoedingDiv1"hidden>
#Html.EditorFor(x => x.VoedingCollection[1])
</div>
<div id="CreateVoedingDiv2"hidden>
#Html.EditorFor(x => x.VoedingCollection[2])
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input value="Add" class="btn btn-default" onclick="ShowVoeding()" /> <input value="Remove" class="btn btn-default" onclick="HideVoeding()" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script>
var count = 1;
function ShowVoeding()
{
if (document.getElementById("CreateVoedingDiv" + count).hidden == true)
{
document.getElementById("CreateVoedingDiv" + count).hidden = false;
count++;
}
}
function HideVoeding()
{
count = count - 1;
if (document.getElementById("CreateVoedingDiv" + count).hidden == false) {
document.getElementById("CreateVoedingDiv" + count).hidden = true;
}
}
</script>
Partial class:
(customvoeding and standaardvoeding do the same thing, only customvoeding returns a collection of customvoeding and standaardvoeding returns a collection of standaardvoeding.
public partial class customvoeding
{
private static foodtrackerEntities1 db = new foodtrackerEntities1();
public static List<customvoeding> GetAllCustomvoeding()
{
db.Configuration.LazyLoadingEnabled = false;
return db.customvoeding.ToList();
}
}
You don't seem to be initializing the model and passing it to the view. In the action methods of your controller try adding:
var viewModel = new AgendaBindingModel();
viewModel.VoedingCollection = // TODO: Fill the list from your data source
return View(viewModel );
Try like this. I could not test, but if you like we can advance is this way:
To show all items:
<div id="group">
#for(int i = 0; i < AgendaBindingModel.VoedingCollection.Count; i++)
{
#Html.EditorFor(x => x.VoedingCollection[i])
}
To add new item:
<button onclick=newItem() >+</button>
</div>
<script>
function newItem(){
var div = document.createElement('div');
div.id = CreateNewItem;
div.innerHTML = '#Html.EditorFor(x => x.VoedingCollection[i])';
document.body.appendChild(div);
}
</script>
Your second and third html are broken.
<div id="CreateVoedingDiv2"hidden>
remove hidden
I found out what was preventing me from receiving more than one result:
You can NOT use #Html.EditorFor template for more than 1 value when you specify a template. It does not matter if you use different models or different templates, it just simply does not work.
To fix it, you have to use 'Html.BeginCollectionItem' library, which can be found here.

MVC: On button click do some database action and stay on same view

In my view currently I have a form and inside those forms I have three other forms, child form is submitted, i want it to forward some method in controller that just performs some database action but then i want to stay on the same page after the database action is performed.
#using System.Web.Mvc.Html
#using System.Web.UI.WebControls
#using DatePicker.Models.ViewModels.Appointment
#model DatePicker.Models.ViewModels.Appointment.CreateAppointmentSelectPersons
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
<link href="~/Content/themes/base/minified/jquery-ui.min.css" rel="stylesheet"/>
}
<h2>Create</h2>
#using(Html.BeginForm("Create","Appointment", FormMethod.Post,new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Step 2</h4>
<hr />
#Html.ValidationSummary()
#*ChildForm1*#
using (Html.BeginForm("AddAttendeeManual", "Attendee"))
{
#Html.HiddenFor(m=>m.SelectedManualEmail.AppointmentId)
<div class="form-group">
#Html.LabelFor(m => m.SelectedManualEmail.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-8 input-group">
#Html.TextBoxFor(m => m.SelectedManualEmail.Email, new { id = "Email", #class = "form-control",PlaceHolder="Email"}) <input type='submit' id="btnEmail" class="btn btn-default" value="Add>>" />
</div>
</div>
}
if (Model.IsSuperOfficeConnected)
{
#*ChildFrom2*#
using (Html.BeginForm("AddAttendeeSuperOffice","Attendee",FormMethod.Post))
{
#Html.HiddenFor(m => m.SelectedSuperOfficeEmail.FirstName, new { id = "SelectedSuperOfficeEmail_FirstName" })
#Html.HiddenFor(m => m.SelectedSuperOfficeEmail.LastName, new { id = "SelectedSuperOfficeEmail_LastName" })
#Html.HiddenFor(m=>m.SelectedSuperOfficeEmail.AppointmentId)
#Html.HiddenFor(m => m.SelectedSuperOfficeEmail.SuperOfficePersonId, new { id = "SelectedSuperOfficeEmail_SuperOfficePersonId" })
<div class="form-group">
#Html.LabelFor(m => m.SelectedSuperOfficeEmail.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-8 input-group">
#Html.TextBoxFor(m => m.SelectedSuperOfficeEmail.Email, new { id = "SelectedSuperOfficeEmail", #class = "form-control", PlaceHolder = "Search in SuperOffice" })
<input type='submit' id="btnEmail" class="btn btn-default" value="Add>>" />
</div>
</div>
}
}
if (Model.IsInternalAddressBookEmpty)
{
#*ChildForm3*#
using (Html.BeginForm("AddAttendeeInternalAddressBook", "Attendee"))
{
#Html.HiddenFor(m=>m.SelectedAddressBookPerson.FirstName)
#Html.HiddenFor(m=>m.SelectedAddressBookPerson.LastName)
#Html.HiddenFor(m=>m.SelectedAddressBookPerson.AppointmentId)
<div class="form-group">
#Html.LabelFor(m => m.SelectedAddressBookPerson.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-8 input-group">
#Html.TextBoxFor(m => m.SelectedAddressBookPerson.Email, new { id = "SelectedAddressBookPerson", #class = "form-control", PlaceHolder = "Search in AddressBook..." }) <input type='button' id="btnAddressBook" class="btn btn-default" value="Add>>">
</div>
</div>
}
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input class="btn btn-default" value="<<Previous"/>
<input type="submit" class="btn btn-default" value="Next>>" />
</div>
</div>
}
<style>
.ui-autocomplete-loading {
background: url('/Content/themes/base/images/ui-anim_basic_16x16.gif') no-repeat right center;
}
</style>
#section Scripts{
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/Scripts/jquery-ui-1.10.4.min.js")
<script type="text/javascript">
$(function () {
$("#SelectedSuperOfficeEmail").
autocomplete({
source: '/Appointment/SuperOfficePerson',
minLength: 1,
select: function (event, ui) {
$('#SelectedSuperOfficeEmail').val(ui.item.value);
$(#Html.IdFor(m => m.SelectedSuperOfficeEmail.FirstName)).val(ui.item.FirstName);
$(#Html.IdFor(m => m.SelectedSuperOfficeEmail.LastName)).val(ui.item.LastName);
$(#Html.IdFor(m => m.SelectedSuperOfficeEmail.SuperOfficePersonId)).val(ui.item.ExternalPersonId);
}
});
$("#SelectedAddressBookPerson").autocomplete({
source: '/Appointment/AddressBookPerson',
minLength: 1,
select: function(event,ui) {
$(#Html.IdFor((m=>m.SelectedAddressBookPerson.FirstName))).val(ui.item.FirstName);
$(#Html.IdFor(m=>m.SelectedAddressBookPerson.LastName)).val(ui.item.LastName);
},
});
});
</script>
}
this is what i've done in controller
[HttpPost]
public void AddAttendeeSuperOffice(CreateAppointmentSelectPersons superOfficePerson)
{
_attendeeRepository.AddSuperOfficeAttende(superOfficePerson.SelectedSuperOfficeEmail.AppointmentId,
superOfficePerson.SelectedSuperOfficeEmail.FirstName,
superOfficePerson.SelectedSuperOfficeEmail.LastName,
superOfficePerson.SelectedSuperOfficeEmail.Email,
superOfficePerson.SelectedSuperOfficeEmail.SuperOfficePersonId);
}
[HttpPost]
public void AddAttendeeInternalAddressBook(CreateAppointmentSelectPersons internalAddressbookPerson)
{
_attendeeRepository.AddInternalAddressBookAttendee(
internalAddressbookPerson.SelectedAddressBookPerson.AppointmentId,
internalAddressbookPerson.SelectedAddressBookPerson.FirstName,
internalAddressbookPerson.SelectedAddressBookPerson.LastName,
internalAddressbookPerson.SelectedAddressBookPerson.Email);
}
[HttpPost]
public void AddAttendeeManual(CreateAppointmentSelectPersons manualEmail)
{
_attendeeRepository.AddManualAttendee(manualEmail.SelectedManualEmail.AppointmentId,
manualEmail.SelectedManualEmail.Email);
}
so whenever my childfrom gets submitted, database action takes place but I get forwarded to different link.
I could use, return RedirectToAction but I don't want to load the whole page again, thats makes it kind of slow to load whole thing again.
I thought of using Partial Views but then partial view didn't really help me achieve what I get.
Is there someway to just stay on the same page and make a void call upon child form submission, so that i stay on same page. Maybe, just make the textbox of the child form empty?
It is better to submit child forms to controller using Ajax.
Assuming the below child form you want to submit,
using (Html.BeginForm("AddAttendeeInternalAddressBook", "Attendee", new{id="frm-child-address"}))
then
$('#mybutton').click(function(){
var postData= $('#frm-child-address').serialize();
$.post('/Attendee/AddAttendeeInternalAddressBook',{data:postData},function(res){
//based on server response do whatever you require
});
});
You can use #Ajax.BeginForm and add a javascript callback that would fire off after the controller's action (database call) has completed.
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
#using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "POST", OnSuccess = "done" }))
{
#* form *#
}
<script type="text/javascript">
function done(){
// The database call is complete.
}
</script>

Categories

Resources