0

I have the beginnings of an ASP.NET MVC3 application that is supposed to implement scheduling. I have the following in my model:

public class Schedule
{
    public int ScheduleID { get; set; }
    public bool isDisabled { get; set; }
    [DisplayName("For Delivery")]
    public bool isDeliver { get; set; }
    public int Count { get; set; }
    public virtual ICollection<TimeofDay> Times { get; set; }
    public virtual Location Location { get; set; }
    public int Week { get; set; }
    public int weekday { get; set; }
}

public class TimeofDay
{
    [Key]
    public int TimeID {get;set;}
    public DateTime Time { get; set; }
}

The model is supposed to accept 0 or more Time of Day entities that I pass by using JavaScript to create a new input field:

function createtimefield() {
    var TimeDiv = document.getElementById('timefields');
    var newDivInput = document.createElement("input");
    newDivInput.name = "Times";
    idText="Time" + GLOBAL_timeDivIdCount++;
    newDivInput.id = idText;
    newDivInput.value = "12:00 am";

    TimeDiv.appendChild(newDivInput);

}

My Controller will work file for accepting the data passed up until I add data to the time fields. This is supposed to create new entities in the TimeofDay table that gets generated by the model, and link back to the the ScheduleID. I don't want two interfaces to input this simple data, but can't seem to find the way to create both entities with MVC3 in a single action. Anyone have any ideas?

Andrew

(Thank you for reading)


As requested the controller was:

public ActionResult Create(Schedule schedule, string[] schedTimes)
    {
        if (ModelState.IsValid)
        {
            Schedule newschedule = db.Schedule.Add(schedule);
            db.SaveChanges();
            return RedirectToAction("Index");  
        }
         ......
     }

I now realize I need to create a view model that will encompass both my schedule class and an array of strings. I will create the schedule and then iterate through the array of strings and create TimeofDay objects

tereško
  • 58,060
  • 25
  • 98
  • 150
Andrew
  • 43
  • 1
  • 5
  • Can you please add the code snippet for your `Controller` or make it more informative? – Abdul Munim Oct 24 '11 at 06:17
  • are you using entity framework or DAL directly in your controller?! This is not good as you create a dependency from the MVC / UI layer to the DAL. see my answer here: http://stackoverflow.com/questions/7474267/mvc3-and-entity-framework/7474357#7474357 – Davide Piras Oct 25 '11 at 15:38
  • The first block of code is in my Model, as is the EF. Is there a better way? – Andrew Oct 25 '11 at 16:25

2 Answers2

0

for inputs to bind with times collection ur form fields need to have indexed names like

Times[0].TimeID // this would probably be hidden field
Times[0].Time
Times[1].TimeID
Times[1].Time
.
.
Times[n].TimeID
Times[n].Time

when you do this there might be other issues when deleting rows from the middle. there are lot of blog posts on this out there. Phil haack's post is my favorite as it explains in very simple way how can you have non sequential indices for list binding. For more links please look at my answer to this question

Community
  • 1
  • 1
Muhammad Adeel Zahid
  • 17,474
  • 14
  • 90
  • 155
  • Yeah, that was what came to me last night in a dream: that I might need to reference it as an array. I'll modify the Javascript as follows: newDivInput.name = "Times["+GLOBAL_timeDivCount+"]"; – Andrew Oct 24 '11 at 20:06
0

I attempted to create a view model to support this by extending my model as follows:

public class ScheduleCreate
{
    public Schedule schedule {get;set;}
    public string[] schedTimes {get;set}
}

I then modified my view by changing:

@model scheduler.Models.Schedule

to:

@model scheduler.Models.ScheduleCreate

I additionally changed all of the model.(parameter) to model.schedule.(parameter)

Then I changed my controller to:

public ActionResult Create(ScheduleCreate mod)
    {
        if (ModelState.IsValid)
        {
            Schedule newschedule = db.Schedule.Add(mod.schedule);
            if (mod.schedTime != null)
            {
                foreach (string instanceTime in mod.schedTimes)
                {
               newschedule.Times.Add(new {Time = DateTime.Parse(instanceTime) }); // unteseted
                }
            }
            db.SaveChanges();
            return RedirectToAction("Index");  
        }
        PopulateDropDown();
        return View(mod.schedule);

}
Andrew
  • 43
  • 1
  • 5
  • turns out I should have used a constructor for the Schedule class that will instaciate the Times as a list. – Andrew Oct 26 '11 at 17:45