locked
for loop with in foreach loop is not working properly RRS feed

  • Question

  • User210895818 posted

    Hi I am trying to filter students based on department id. First, use foreach loop to get the list of department id, within foreach loop use for loop to get filtered list of students based on foreach department id. But the problem is in for loop condition as model compared continuously till the last department id from foreach loop

    Her is my View Model

        public class StdListModel
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public string CNIC { get; set; }       
            public int Depart_ref_id { get; set; }
            public string Registration { get; set; }
            public string RollNo { get; set; }        
            public string DepartName { get; set; }
        }
    

    Controller Code

            public ActionResult AllotRegistration()
            {
                ViewBag.DepartmentList = Context.Departments.Where(a => a.Description == "Academic").ToList();
    
                List<StdListModel> model = new List<StdListModel>();
                var query = (from e in Context.StdEnrollments
                             join d in Context.StdDetails on e.StdReg_ref_id equals d.ID
                             join s in Context.DegreePrograms on e.DegreeProgram_ref_id equals s.ID
                             where s.StartYear == "2019" && e.Program_ref_id == 1 && e.Status == "Active"
                             select new StdListModel
                             {
                                 ID = e.ID,
                                 Registration = e.Resgistration,
                                 RollNo = e.RollNo,
                                 Name = d.Name,
                                 Depart_ref_id = e.Depart_ref_id,
                                 DepartName = e.Department.DepartName
                             }).ToList();
                foreach (var item in query)
                {
                    model.Add(new StdListModel()
                    {
                        ID = item.ID,
                        Registration = item.Registration,
                        RollNo = item.RollNo,
                        Name = item.Name,
                        Depart_ref_id = item.Depart_ref_id,
                        DepartName = item.DepartName
                    });
                }
                return View(model);
            }
    

    here is my View code:

    @model List<GCWUS.Models.StdListModel> 
    @{ int j = 0; } @foreach (var item in @ViewBag.DepartmentList) { j++; <div class="panel panel-default" style="margin-top:5px;"> <div class="panel-heading" style="background-color:cornflowerblue;"> <h4 class="panel-title"> <a data-toggle="collapse" data-parent="#accordion" href="#collapse-@j" aria-expanded="false" style="color:white"> @item.DepartName </a> </h4> </div> <div id="collapse-@j" class="panel-collapse collapse"> <div class="panel-body"> @using (Html.BeginForm()) { <table id="dynamic-table" class="table table-striped table-bordered table-hover" name="StudentDetail"> <thead> <tr> <th>Registration</th> <th>Roll No</th> <th>Student Name</th> </tr> </thead> <tbody> @for (int i = 0; i < Model.Where(a => a.Depart_ref_id == item.ID).Count(); i++) { <tr> @Html.HiddenFor(model => model[i].ID) <td> @Html.DisplayFor(model => model[i].Registration) <td> @Html.DisplayFor(model => model[i].RollNo) </td> <td> @Html.DisplayFor(model => model[i].Name) </td> </tr> } </tbody> </table> <p> <input type="submit" value="Submit" /> </p> } </div> </div> </div> }

    Please help if anyone has any idea, Thanks

    Friday, November 8, 2019 4:19 PM

Answers

  • User475983607 posted

    Ridzi

    Thanks for your help i have tried with Viewmodel like you suggested as:

    public class DepartmentalStudent
        {
            public List<StdListModel> Students { get; set; }
            public List<Department> Department { get; set; }
        }

    Your code is nothing like the object model I shared above.  Your code is a single class with two generic List<T> properties. There is no relationship between the the two List<T> properties in the object model.  

    Example

            [HttpGet]
            public IActionResult Index()
            {
                List<DepartmentViewModel> list = new List<DepartmentViewModel>();
                DepartmentViewModel dept = new DepartmentViewModel();
    
                dept.DepartmentId = 1;
                dept.Name = "Department 1";
                dept.stdList.Add(new StdListModel() { ID = 1, Name = "Some Name" });
                dept.stdList.Add(new StdListModel() { ID = 2, Name = "Another Name" });
                list.Add(dept);
    
                dept = new DepartmentViewModel();
                dept.DepartmentId = 2;
                dept.Name = "Department 2";
                dept.stdList.Add(new StdListModel() { ID = 3, Name = "Some Name" });
                dept.stdList.Add(new StdListModel() { ID = 4, Name = "Another Name" });
                list.Add(dept);
    
    
                return View(list);
            }
    <div>
        @foreach(var item in Model)
        {
            <h1>@item.Name</h1>
            <ul>
                @for (int i = 0; i < item.stdList.Count(); i++)
                {
                <li>
                    @Html.DisplayFor(model => item.stdList[i].Name)
                </li>           
                }
            </ul>
        }
    </div>
    

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 8, 2019 7:32 PM
  • User665608656 posted

    Hi Ridzi,

    For your question, I have replied in your previous thread https://forums.asp.net/t/2161352.aspx.

    You can refer to this link  https://forums.asp.net/post/6284326.aspx  and hope it can help you.

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 11, 2019 3:20 AM

All replies

  • User475983607 posted

    As far as I can tell there is nothing in the code that related the outer loop to the inner loop.  The standard pattern is to create a ViewModel that represents the UI you wish to present.

    Friday, November 8, 2019 5:31 PM
  • User210895818 posted

    he standard pattern is to create a ViewModel that represents the UI you wish to present.

    Please check I have updated my post

    Friday, November 8, 2019 5:50 PM
  • User-474980206 posted

    this code:

                @for (int i = 0; i < Model.Where(a => a.Depart_ref_id == item.ID).Count(); i++)
                                            {
                                                <tr>
                                                    @Html.HiddenFor(model => model[i].ID)
                                                    <td>
                                                        @Html.DisplayFor(model => model[i].Registration)
                                                    <td>
                                                        @Html.DisplayFor(model => model[i].RollNo)
                                                    </td>
                                                    <td>
                                                        @Html.DisplayFor(model => model[i].Name)
                                                    </td>
                                                </tr>
    
                             

    counts the number that match, then displays the that count of entries (whether they match or not). you probably wanted something more like:

    @var items = Model.Where(a => a.Depart_ref_id == item.ID);
    for (int i = 0; i < items.Count(); i++)
    {
       <tr>
            <td>
               @Html.HiddenFor(m => items[i].ID)
               @Html.DisplayFor(m => items[i].Registration)
           </td>
           <td>
               @Html.DisplayFor(m => items[i].RollNo)
           </td>
           <td>
               @Html.DisplayFor(m => items[i].Name)
           </td>
       </tr>
    }
    

    by I agree with the above, its better to fix your model

     

    Friday, November 8, 2019 5:55 PM
  • User210895818 posted

    counts the number that match, then displays the that count of entries (whether they match or not). you probably wanted something more like:

    i have already tried this, but the values does not indexed and return null model on POSt action.

    its better to fix your model

    can you please guide me how to do this

    Thanks

    Friday, November 8, 2019 6:21 PM
  • User475983607 posted

    As far as I can tell you want to group StdListModel by Department.  The object model can follow the pattern illustrated below.

    public class DepartmentViewModel
    {
        public int DepartmentId { get; set; }
        public string Name {get; set;}
        public List<StdListModel> stdList { get; set; }
    
        public DepartmentViewModel()
        {
            stdList = new List<StdListModel>();
        }
    }
    
    public class StdListModel
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string CNIC { get; set; }
        public int Depart_ref_id { get; set; }
        public string Registration { get; set; }
        public string RollNo { get; set; }
    }

    Fill a list of...

    List<DepartmentViewModel> departments

    ... and pass it to the View.  Then your nested loop construct will work.  In MVC, a View Model is used for presentation.  The model should mirror the UI.

    Edit added public to the list property...

    Friday, November 8, 2019 6:36 PM
  • User210895818 posted

    mgebhard

    and pass it to the View.  Then your nested loop construct will work.

    Thanks for your help i have tried with Viewmodel like you suggested as:

    public class DepartmentalStudent
        {
            public List<StdListModel> Students { get; set; }
            public List<Department> Department { get; set; }
        }

    pass this model to view student list is sorted department wise through as:

    @model pp.Models.DepartmentalStudent
    
    ..
    //Same Code
    ..
    @{
    var std = Model.Students.Where(f => f.Depart_ref_id == item.ID).ToList();
         for (int i = 1; i < std.Count(); i++)
           {
             <tr>                                                                                                      
              <td>
               <input type="hidden" value="@std[i].ID" name="ID"/>
               <input type="hidden" value="@std[i].Registration" name="Registration"/>                 
              </td>
              <td>
                @Html.DisplayFor(model => std[i].RollNo)
              </td>
              <td>
                @Html.DisplayFor(model => std[i].Name )
              </td>
            </tr>
          }
    }

    But now the issue input names are not indexed and on post method values are not passing. can you guide me in this regard also as Hidden id and Registration input generated as

    <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="std_1__ID" name="std[1].ID" type="hidden" value="1">
    <input id="std_1__Registration" name="std[1].Registration" type="text" value="">

    Thanks

    Friday, November 8, 2019 7:09 PM
  • User475983607 posted

    Ridzi

    Thanks for your help i have tried with Viewmodel like you suggested as:

    public class DepartmentalStudent
        {
            public List<StdListModel> Students { get; set; }
            public List<Department> Department { get; set; }
        }

    Your code is nothing like the object model I shared above.  Your code is a single class with two generic List<T> properties. There is no relationship between the the two List<T> properties in the object model.  

    Example

            [HttpGet]
            public IActionResult Index()
            {
                List<DepartmentViewModel> list = new List<DepartmentViewModel>();
                DepartmentViewModel dept = new DepartmentViewModel();
    
                dept.DepartmentId = 1;
                dept.Name = "Department 1";
                dept.stdList.Add(new StdListModel() { ID = 1, Name = "Some Name" });
                dept.stdList.Add(new StdListModel() { ID = 2, Name = "Another Name" });
                list.Add(dept);
    
                dept = new DepartmentViewModel();
                dept.DepartmentId = 2;
                dept.Name = "Department 2";
                dept.stdList.Add(new StdListModel() { ID = 3, Name = "Some Name" });
                dept.stdList.Add(new StdListModel() { ID = 4, Name = "Another Name" });
                list.Add(dept);
    
    
                return View(list);
            }
    <div>
        @foreach(var item in Model)
        {
            <h1>@item.Name</h1>
            <ul>
                @for (int i = 0; i < item.stdList.Count(); i++)
                {
                <li>
                    @Html.DisplayFor(model => item.stdList[i].Name)
                </li>           
                }
            </ul>
        }
    </div>
    

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, November 8, 2019 7:32 PM
  • User665608656 posted

    Hi Ridzi,

    For your question, I have replied in your previous thread https://forums.asp.net/t/2161352.aspx.

    You can refer to this link  https://forums.asp.net/post/6284326.aspx  and hope it can help you.

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 11, 2019 3:20 AM