Search code examples
javascripthtmlcssasp.net-mvcsignalr

How do I Make My Chat View Work Without Using Partial View


I am trying to add a private chat functionality using signalR in my project and I am stuck on creating a View with accessible model values to pass to server. I Have a list of doctors and when user clicks on doctor's link. it opens a chat partial view for consultation but i am not able to use model's values from partial view to use in parent view JS Although there are some suggestion about getting data from partial view from stack SO I also tried writing JS in partial view(by using @section) but its not allowed. and now I am thinking of getting rid of the partial view and combine both model into one and use it in parent view like when i click doctor name, change the values in chatbox for particular doctor and use that values in JS for chat. this is my Parent View,

@model E_HealthCare_Web.ViewModels.ConsultationViewModel
<section class="chat-wrapper">
    <section class="doctor-list-section">
        <div class="search-dr">
            @using (Html.BeginForm())
            {
                <input type="text" id="searchdr" name="searchdr" placeholder="Search Doctor" /><button type="submit" id="searchbtn"><i class="fa fa-search-plus"></i></button>
            }

        </div>
        <div class="drlist-overflowcontrol">
            @foreach (var doctor in Model.DoctorsList)
            {
                <div id="drlist" class="dr-profile-direction">
                    <div class="dr-profile">
                        @{
                            if (doctor.ProfileImagePath == null)
                            {
                                <img src="~/Images/ProfilePictures/dricon.png" alt="profile" />
                            }
                            else
                            {
                                <img src="@Url.Content(doctor.ProfileImagePath)" alt="profile" />
                            }

                        }
                    </div>
                    <div class="dr-name">
                        @{
                            string doctorName;
                            if (doctor.D_Name != null)
                            {
                                doctorName = doctor.D_UserName;
                            }
                            else
                            {
                                doctorName = doctor.D_UserName;
                            }
                        }

                        @Ajax.ActionLink(doctorName, "ChatBox", new { patientid = Model.id, doctorid = doctor.Id },
                       new AjaxOptions
                       {
                           UpdateTargetId = "chatbox",
                           InsertionMode = InsertionMode.Replace,
                           HttpMethod = "GET"
                       })
                    </div>
                </div>
            }
        </div>
    </section>
    <section class="chatbox-section">
        <div id="chatbox">
            <div class="chathere">
                <h1>Chat Here</h1>
            </div>            
        </div>
    </section>
</section>

and this is partial view(trying to get model values from here)

@model E_HealthCare_Web.ViewModels.ChatLoadViewModel

<div class="chatbox-upper">
    <input id="doctorUserName" type="hidden" value="@Model.doctor.D_UserName" />
    <div class="todoctor-profile">
        @{
            if (Model.doctor.ProfileImagePath == null)
            {
                <img src="~/Images/ProfilePictures/dricon.png" alt="profile" />
            }
            else
            {
                <img src="@Url.Content(Model.doctor.ProfileImagePath)" alt="profile" />
            }
        }
    </div>
    <div class="todoctor-name">
        <label id="drname">@Html.DisplayFor(q => q.doctor.D_UserName)</label>
    </div>
</div>
<div id="chatboxmiddle" class="chatbox-middle">
    <p id="patientmsg">Hello How are you</p>
    <p id="doctormsg">I am Fine How are you</p>
</div>
<div class="chatbox-lower">
    <div class="msg-btn-conatiner">
        <textarea id="chatmessage" placeholder="type message here.."></textarea>
        <button type="submit" title="send" id="Sendbtn">Send</button>
    </div>
</div>

this is Javascript for chat functionality

 <!--Script references. -->
    <!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
    <!--Reference the SignalR library. -->
    <script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="~/signalr/hubs"></script>
    <!--SignalR script to update the chat page and send messages.-->
    <script>
        $(document).ready(function () {
            // Reference the auto-generated proxy for the hub.
            var chat = $.connection.consultationHub;            
            var PatientUserName = '@Context.User.Identity.Name';
            // Create a function that the hub can call back to display messages.
            chat.client.addNewMessageToPage = function (message) {
                // Add the message to the page.
                $('#patientmsg').append('<p><strong>' + htmlEncode(message)
                    + '</strong></p>');
            };

            chat.client.addChatMessage = function (message) {
                // Add the message to the page.
                $('#chatboxmiddle').append('<p id = "patientid">'+ htmlEncode(message)+'</p>');
            };

            // Set initial focus to message input box.
            $('#chatmessage').focus();

            chat.client.showErrorMessage = function (message) {
                // Add the message to the page.
                $('#chatboxmiddle').append('<p id ="patientmsg">' + htmlEncode(message)
                    + '</p>');
                
            };

            /*$('body').on('click','#Sendbtn', function () { alert('live clicked'); });*/

            // Start the connection.
            $.connection.hub.start().done(function () {
                $('body').on('click', '#Sendbtn', function () {                    
                    // Call the Send method on the hub.
                    chat.server.sendChatMessage($('#doctorUserName').val(), $('#chatmessage').val());                    
                    // Clear text box and reset focus for next comment.
                    $('#chatmessage').val('').focus();
                });
            });
        });


        // This optional function html-encodes messages for display in the page.
        function htmlEncode(value) {
            var encodedValue = $('<div />').text(value).html();
            return encodedValue;
        }
    </script>

and these are my methods from controller

 public ActionResult Chat(int id, string searchdr)
        {
            ViewBag.patiendId = id.ToString();
            ConsultationViewModel model = new ConsultationViewModel();
            model.id = id;
            if (!String.IsNullOrEmpty(searchdr))
            {
                model.DoctorsList = context.Doctors.Where(q => q.D_UserName.ToUpper().Contains(searchdr.ToUpper())).ToList();
            }
            else
            {
                model.DoctorsList = context.Doctors.ToList();
            }
            model.CurrentPatient = context.Patients.Where(q => q.p_id == id).FirstOrDefault();
                       
            return View(model);
        }

      
        public ActionResult ChatBox(int patientid, int doctorid)
        {
            ChatLoadViewModel model = new ChatLoadViewModel();
            model.patient = context.Patients.Where(q => q.p_id == patientid).FirstOrDefault();
            model.doctor = context.Doctors.Where(q => q.Id == doctorid).FirstOrDefault();            
            return PartialView("_ChatBox",model);
        }

And these are my models

public class ConsultationViewModel
    {
        [HiddenInput(DisplayValue = false)]
        [Key]
        public int id { get; set; }

        [Display(Name = "Doctors")]
        public IEnumerable<Doctor> DoctorsList { get; set; }

        public Patient CurrentPatient { get; set; }
        
    }


    public class ChatBoxViewModel //ill be using it to save messages in the database 
    {   
        public string MessageText { get; set; }
        [DataType(DataType.Date)]
        public DateTime MessageDate { get; set; }                
        [DataType(DataType.Time)]
        public TimeSpan MessageTime { get; set; }
        public int SenderId { get; set; }
        public int RecieverId { get; set; }
        public string ConnectionID { get; set; }

    }

    public class ChatLoadViewModel
    {
        public Patient patient { get; set; }
        public Doctor doctor { get; set; }
    }

I am confused at what to do and how to do also please guide me to do it in a better way.


Solution

  • I think the session data helps you. It is made for storing any data that is needed by more than one action/view. It is a server store, so if you want to use it from JS, you have to send an Ajax request. (Are you going to use the data transferred from partial view in JS? Or is it a misunderstand?)

    Create two actions in your Home controller: first of them will add data to the session, and second will fetch data.

    public IActionResult SetChatData(object data)
    {            
        Session["chatData"] = data;
        return Json(data);
    }
    
    public IActionResult GetChatData()
    {
        return Json(Session["chatData"]);
    }
    

    Now you can use this methods when you want to write data to the session or fetch data from it. You just have to send an Ajax request:

    // This function should return the data you provided in parameter "data"
    function setChatData(data) {
        var result;
    
        $.ajax({
            url: "/Home/SetChatData",
            type: 'POST',
            dataType: 'json',
            data: JSON.stringify({ data: data }),
            contentType: 'application/json; charset=utf-8',
            async: false
        }).done(function(data) {
            result = data;
        });
    
        return result;
    }
    

    And this request fetches data:

    function getChatData() {
        var result;
    
        $.ajax({
            url: "/Home/GetChatData",
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            async: false
        }).done(function(data) {
            result = data;
        });
    
        return result;
    }