1

I need to switch two different models in one view.

For that, I created a class that contains my two "subclasses" of my models.

So far so good, my problem is in converting these classes to .ToList(), I have an error that tells me that I can not convert a List<Events> into Events (which I understand perfectly).

Except that if in my main class (EventViewModel) I change and I say that my subclasses are lists, then when I go in my view I do not parivens more to access the elements of my subclasses.

Indeed, I have for example a @Html.LabelFor(model => model._Events.) Except that there is no way to find the desired element of my object, since it represents a list.

I still specify that results is of type IEnumerable and also that I need to recover several events by request.

To do this, I used this page (Two models in one view in ASP MVC 3), especially the second answer.

Controller

[Authorize]
[HttpGet]
public async Task<ActionResult> Index()
{
    ViewBag.sessionv = HttpContext.Session.GetInt32("idMember");
    FileMakerRestClient client = new FileMakerRestClient(serverName, fileName, userName, password);
    var toFind = new Models.EventsLines { Zkf_CTC = 1053 };
    var results = await client.FindAsync(toFind);

    Models.EventViewModel oEventViewModel = new Models.EventViewModel
    {
        _EventsLines = (from o in results select o).ToList()
    };

    ViewBag.JsonList = oEventViewModel;

    return View(oEventViewModel);
}


[Authorize]
[HttpGet]
public async Task<ActionResult> GetEventsDetails(int Id_Event, int Id_CTC)
{
    ViewBag.sessionv = HttpContext.Session.GetInt32("idMember");
    FileMakerRestClient client = new FileMakerRestClient(serverName, fileName, userName, password);
    var toFind = new Models.SubEventsLines { Zkp_WEB_SEL = ViewBag.sessionv, Zkf_CTC = Id_CTC, Zkf_EVL = Id_Event };
    var results = await client.FindAsync(toFind);

    Models.EventViewModel oEventViewModel = new Models.EventViewModel
    {
        _SubEventsLines = (from o in results select o).ToList()
    };

    Console.WriteLine(oEventViewModel);

    return Json(oEventViewModel);
}

    public class EventViewModel
    {
        public Events _Events { get; set; }
        public SubEvents _SubEvents { get; set; }
    }



**View**


@model jak.formulaire.Models.EventViewModel

<div class="container">
    <div class="col-5" style="margin-top:2%">
        <h3>Registration History</h3>
        </div>
        @* Table of Events member *@
        <div>
            <table id="example" class="table table-hover" style="width:100%; margin-top:2%">
                <thead>
                    <tr>
                        <th scope="col">Event Name</th>
                        <th scope="col">Start Date</th>
                        <th scope="col">End Date</th>
                        <th scope="col">Status</th>
                        <th scope="col"></th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in Model._EventsLines)
                    {
                    <tr>
                        <td>@item.Event_Name</td>
                        <td>@item.Event_DateStart</td>
                        <td>@item.Event_DateEnd</td>
                        <td>@item.Event_Status</td>
                        <td><a href="#myModal" class="myModal" data-toggle="modal" data-target="#myModal" onclick="GetEventsDetails()" data-id="@item.Zkp">View Details</a></td>
                    </tr>
                    }
                </tbody>
            </table>
        </div>
    </div>

    @* Modal Details *@
    <div class="modal" role="dialog" id="myModal">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title" id="myModalTitle">Details : </h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">

                    <div id="myModalContent">
                        <div class="container" style="width:auto; margin-top:1%">
                            <div class="row col-12">
                                @foreach (var item in Model._EventsLines)
                                {
                                <div class="form-horizontal col-6" style="margin-left:-5%">

                                    @Html.HiddenFor(model => model._EventsLines.FirstOrDefault().Zkp, new { data_val = "false" })
                                    @Html.HiddenFor(model => model._EventsLines.FirstOrDefault().Zkf_CTC, new { data_val = "false" })
                                    <div class="form-check-inline col-12" style="margin-top:1%">
                                        <label class="control-label col-md-5" style="font-size:13px">Start Date</label>
                                        <input name="Event_StartDate" id="Event_StartDate" value="@item.Event_Name" class="form-control col-md-7" readonly="" />
                                        @*@Html.EditorFor(model => model._Events.FirstOrDefault().Event_Name, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Date Start", @id = "Event_StartDate" } })*@
                                    </div>
                                    <div class="form-check-inline col-12" style="margin-top:1%">
                                        <label class="control-label col-md-5" style="font-size:13px">End Date</label>
                                        @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_DateEnd, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Date End", @id = "Event_EndDate" } })
                                    </div>
                                    <div class="form-check-inline col-12" style="margin-top:1%">
                                        <label class="control-label col-md-5" style="font-size:13px">City</label>
                                        @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_City, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "City", @id = "Event_City" } })
                                    </div>
                                    <div class="form-check-inline col-12" style="margin-top:1%">
                                        <label class="control-label col-md-5" style="font-size:13px">Country</label>
                                        @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_Country, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Country", @id = "Event_Country" } })
                                    </div>
                                </div>
                                    <div class="form-horizontal col-6">
                                        <div class="form-check-inline col-12" style="margin-top:1%">
                                            <label class="control-label col-md-5" style="font-size:13px">Type</label>
                                            @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_Type, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Type", @id = "Event_Type" } })
                                        </div>
                                        <div class="form-check-inline col-12" style="margin-top:1%">
                                            <label class="control-label col-md-5" style="font-size:13px">Status</label>
                                            @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_Status, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Status", @id = "Event_Status" } })
                                        </div>
                                        <div class="form-check-inline col-12" style="margin-top:1%">
                                            <label class="control-label col-md-5" style="font-size:13px">Total Due</label>
                                            @Html.EditorFor(model => model._EventsLines.FirstOrDefault().Event_TotalDue, new { htmlAttributes = new { @class = "form-control col-md-7", @style = "font-size:13px, height:10px", @readonly = "", @placeholder = "Total Due", @id = "Event_TotalDue" } })
                                        </div>
                                    </div>

                                    }
                                    <div class="col-12">
                                        <div class="card border-primary" style="margin-top:5%; margin-left:-4%; width:113%">
                                            <div class="card-header"> <h6>Sub-Events</h6></div>
                                            <div class="card-body">
                                                <table id="SubEventsDatatables" class="display col-12">
                                                    <thead>
                                                        <tr>
                                                            <th scope="col">Name</th>
                                                            <th scope="col">Start Date</th>
                                                            <th scope="col">Status</th>
                                                            <th scope="col">Fees</th>
                                                        </tr>
                                                    </thead>
                                                </table>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>


    @section Scripts{

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
        <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>

        <script type="text/javascript">

            // Get the modal
            var modal = document.getElementById('myModal');
            // Get the button that opens the modal
            var btn = document.getElementById("myBtn");

            // Get the <span> element that closes the modal
            var span = document.getElementsByClassName("close")[0];

            // When the user clicks the button, open the modal
            //btn.onclick = function () {
            //    modal.style.display = "block";
            //}

            // When the user clicks on <span> (x), close the modal
            span.onclick = function () {
                modal.style.display = "none";
            }

            // When the user clicks anywhere outside of the modal, close it
            window.onclick = function (event) {
                if (event.target == modal) {
                    modal.style.display = "none";
                }
            }

            ////triggered when modal is about to be shown
            //$('#myModal').on('show.bs.modal', function (e) {

            //    GetEventsDetails();

            //    //get data-id attribute of the clicked element
            //    var id = $(this).data('id');
            //    //populate the textbox
            //    $(e.currentTarget).find('input[name="Event_StartDate"]').val('id');

            //});

            //once the modal has been shown
            $('#myModal').on('shown.bs.modal', function () {
                //Get the datatable which has previously been initialized
                var dataTable = GetEventsDetails();
                //recalculate the dimensions
                dataTable.columns.adjust().responsive.recalc();

                //get data-id attribute of the clicked element
                var id = $(this).data('id');
                //populate the textbox
                $(e.currentTarget).find('input[name="Event_StartDate"]').val('id');

            });

            $(document).ready(function () {
            });

            //$(function () {
            //    $(".myModal").click(function () {
            //        var my_id = $(this).data('id');
            //        $(".modal-body #hiddenValue").val(my_id);
            //    })
            //});


            function GetEventsDetails() {
                return $('#SubEventsDatatables').DataTable({
                    "paging": false,
                    "ordering": false,
                    "searching": false,
                    "info": false,
                    processing: true,
                    ajax: {
                        "url": '@Url.Action("GetEventsDetails", "Events")' + "/" + 1053 + "/" + 1454,
                        "type": "GET",
                        "datatype": "json",
            succes: function (data) {
                $("#Name").val(data['Name_cU']);
                $("#Name").val(data['Date']);
                $("#Name").val(data['Status']);
                $("#Name").val(data['Fee_cU']);
            },

        },
        columns: [
            { "data": "Name_cU" },
            { "data": "Date" },
            { "data": "Status" },
            { "data": "Fee_cU" },
        ]

    });
}
        </script>
    }
Korpin
  • 323
  • 6
  • 24
  • I'm assuming by this: "Except that if in my main class (EventViewModel) I change and I say that my subclasses are lists" you are referring to this line: `_Events = (from o in results select o).ToList()` ? – Matt M Nov 28 '18 at 16:22
  • Nope, i refer to my class EventModelView where i tried to change Event to List _Events – Korpin Nov 28 '18 at 16:35
  • I understand. For clarity, you should include that code block in your question. To access each item in a list, you need to iterate over it in your view: `@foreach(var item in Model._Events)` Are you just trying to list them all in a tabular format? – Matt M Nov 28 '18 at 16:45
  • Yep, the _Events list would be in a grid and _Subevents in a grid (who's in a modal). When you click on a _Event.Name it opens a modal with all the _SubEvents (im not sure how to pass the good id in my modal yet but this is my final goal). – Korpin Nov 28 '18 at 16:59
  • I'm not sure what "parivens" means in the phrase "I go in my view I do not parivens more to access the elements of my subclasses"... – Heretic Monkey Nov 28 '18 at 21:08

1 Answers1

2

Based on your last comment, you would just need to change your EventViewModel to something like this (although it sounds like you've already done this):

public class EventViewModel
{
    public List<Events> _Events { get; set; }
    public List<SubEvents> _SubEvents { get; set; }
}

Then, in your view, you can just do something like this (but obviously using the properties of an _Events type):

<table>
   <thead>
     <tr>
       <td>Name</td>
       <td>Start Date</td>
     </tr>
   </thead>
   <tbody>
    @foreach(var item in Model._Events)
    {
      <tr>
       <td>@item.Name</td>
       <td>@item.StartDate</td> 
      </tr>
    }
   </tbody>
</table>

EDIT

I would suggest something like this then. Build the table like I showed before (updated to match your model as best I can). Use a button with the "data-" attribute that contains some identifier for that Event. Use javascript to handle the click of the button and call a method on your controller that will get the subevents for the selected event (even return a partial view). In the success function, populate the html of the modal with the subevents and display the modal. When you say "datatables", are you referring to datatables.net?

<table id="example" class="table table-hover" style="width:100%; margin-top:2%">


<thead>
        <tr>
           <th></th>
           <th scope="col">Event Name</th>
           <th scope="col">Start Date</th>
           <th scope="col">End Date</th>
           <th scope="col">City</th>
           <th scope="col">Country</th>
           <th scope="col">Type</th>
           <th scope="col">Status</th>
           <th scope="col">Total Due</th>
         </tr>
        </thead>
<tbody>
    @foreach(var item in Model._Events)
    {
      <tr>
       <td><button data-id="@item.Id">View Details</button></td>
       <td>@item.Event_Name</td> 
       <td>@item.Event_DateStart</td> 
       <td>@item.Event_DateEnd</td> 
       <td>@item.Event_City</td> 
       <td>@item.Event_Country</td> 
       <td>@item.Event_Type</td> 
       <td>@item.Event_Status</td> 
       <td>@item.Event_TotalDue</td> 
      </tr>
    }
    </tbody>
     </table>

You're probably better off posting a new question(s) to accomplish the rest of your goals. Hopefully, this will get you going in the right direction.

Matt M
  • 3,699
  • 5
  • 48
  • 76
  • Thanks for your reply, i'm using datatables and i'm not declare the tbody. Could you explain me how can i do with datatables? And also in my modal, i tried to use the foreach but i have Html.LabelFor which not understand @item.Event_Name. I've edited my view to let you see it all. – Korpin Nov 28 '18 at 17:43
  • Html.LabelFor(model => model._Events.FirstOrDefault().Event_Name , "Start Date", htmlAttributes: new { @class = "control-label col-md-5", style = "font-size:13px" }) --> Is it the good way to use it (had to delete the '@' to post the comment)? – Korpin Nov 28 '18 at 17:55
  • @Korpin I don't understand what you're trying to do with the modal. You want to show a list of all the events in the modal? I thought you were trying to display the subevents in a modal. – Matt M Nov 28 '18 at 18:53
  • A have a grid with all the Events who show up directly when i load the page. When i click on a eventname it opens a modal with all the Subevents (who are actually linked to an event). – Korpin Nov 28 '18 at 19:05
  • Thanks for your help already, have to say that it helped me! Just one quick question, in my modal i need to show the event details on the left part and the sub-events of the event on the right part. For now on, i can only click on the "view details" button for the first event (and it shows the 2 events details on the left side). I think smth's wrong with my id i try to pass.. I've edited my code if you could help me it could be great! – Korpin Nov 29 '18 at 09:18
  • @Korpin Is Zkp_WEB_EVL the id of a single _Event? – Matt M Nov 29 '18 at 15:33
  • Thanks for your answer! Yep it is, actually i just have edited my code to lee you see because i made some changes! I think i'm really close to reach my goal.. My problem is passing the parameter! Zkp means 'z' for dev variables and 'kp' for key primay. – Korpin Nov 29 '18 at 15:48
  • @Korpin Instead of having the "View Details" button toggle the modal view, use the onclick event to get the id of the item that was clicked, make an ajax call to a controller method that gets the subevents for that event and returns a partial view (replace the modal's body with the result), and trigger the modal view via javascript. Make sense? If you need help with this part, you should post a new question. – Matt M Nov 29 '18 at 16:48
  • Okey, i'm gonna try to do it! I'll comment later with the result! If its negative i'll post a new question! Thanks again for your help dude. – Korpin Nov 30 '18 at 12:24
  • Yeah! It works and now i have a partial view to load the event details part of my modal. Gonna try the second part now with another partial view to show a grid with the subevents! – Korpin Nov 30 '18 at 17:30
  • Glad to hear it. Good luck! – Matt M Nov 30 '18 at 18:36