Search code examples
vb.netmodel-view-controllercontrollervisual-studio-2017dropdownbox

Trying to activate a specific Controller function when an Item is selected from a Dropdown Box


new to .net programming. I'm using Visual Studios 2017, programming in vb.net, with a MVC setup (whatever that means), and html web page using Razor - i hope that's enough info for you. I'm updating someone else's code, so this is not being written from scratch. I'm trying to add a dynamic Grid (looks like an excel spreadsheet) on a Create screen where the first row/column item is a dropdownlist and the other columns in the row are the fields from a database table (sql server 2017 v18). The http:Get Create function in the Controller already exists to display the fields for the user to enter stuff (except for the grid) and the http:Post Create exists to put the data into the database. I figured out how to put a partial view on the screen so that it displays the dropdown box and (supposedly) the fields from the database table that I want to display. I doubt I got the grid right, but I do know that every time i select an item from the dropdown box, it automatically goes to the http:Post Create and not to the function I want it to go to so that I can get the data from the table to display the items I want. I've searched all over the web for an answer, but the only things i can find are Web Screens or C#/HTML coding for just a dropdownlist or just a button; nobody is connecting stuff like this program is.

I've searched the Beginform, the Partial, the Controller, the viewbag, the Model, the ViewModel, the overloads... you name it... I've looked it up. The documentation from Microsoft defines a term by using the word being defined in the definition, so that doesn't help me understand how to connect the objects together to do what I want.

I looked for examples that look like what I am doing, but nobody seems to be doing what I am; everything I've found has either talked about each individual piece or a solution in a single application software.

Is it possible that this platform does not support nesting one BeginForm inside another BeginForm? If this SHOULD work... I'm at a loss as to why it isn't working. ''''''''''''

AppointmentController:

<HttpGet()>
Public Function Create(memId As Integer?) As ViewResult

''' HTTP:GET -- Appointment Create - 
    Dim mem As Member = db.Members.Find(memId)
    ViewBag.MemID = memId
    ViewBag.DiagCodes = PopulateDiagCodesDropDownList()
    ViewBag.VADiagCdWebgrid = New DiagnosisCode
    ViewBag.NewAppResult = New MemberAppointmentResult With {.ResultID = db.MemberAppointmentResults.Count + 1}
    Return View()
End Function

        ''' HTTP:POST -- Appointment Create - Save button
        <HttpPost()>
        Public Function Create(memId As Integer, <Bind(Exclude:="model.EventHistory,model.Hospital,model.MemberAppointmentResults,model.MtfReason,model.DiagnosisCode")> model As AddAppointmentViewModel, examType As Integer, Optional button As String = Nothing) As ActionResult
            ViewBag.MemID = memId
            ViewBag.DiagCodes = PopulateDiagCodesDropDownList()
            Dim ev As New EventHistory With {
                .MemberID = memId,
                .EventDate = model.ScheduledVisitDate,
                .EventLoggedBy = GetCurrentUserId(),
                .EventSubcodeID = examType
            }
            Dim newAppt = New MemberAppointment
            With newAppt
                .EventHistory = ev
                .MemberEventID = db.EventHistories.Count + 1
                .ScheduledVisitDate = model.ScheduledVisitDate
                .ScheduledVisitTime = model.ScheduledVisitTime
                .HospitalID = model.HospitalID
                .ActualVisitDate = model.ActualVisitDate
                .ActualVisitTime = model.ActualVisitTime
                .IsVisitCompleted = model.IsVisitCompleted
                .CurrentDisabilityPercentage = model.CurrentDisabilityPercentage
                .MtfReasonCodeID = model.MtfReasonCodeID
            End With

            If ModelState.IsValid Then
                db.MemberAppointments.Add(newAppt)
                db.SaveChanges()

                Dim apptID As Integer = newAppt.AppointmentID
**---this section is where the grid would be looped through to add the data to the table (i haven't gotten this far yet)**
                Return RedirectToAction("Index", New With {.id = memId})
            End If
            Return View(model)
        End Function

**---this function is the one I want the dropdown to go to when an Item is selected**

''' HTTP:Post -- Appointment Create. - Add Diagnosis code to the screen before saving the new appointment data
<HttpPost()>
Public Function AddDiagCodeResult(DiagCodes As Integer, <Bind(Include:="ResultID")> result As MemberAppointmentResult) As ActionResult
    'pass in the Diagcodes value that was selected and create a memory place holder that looks like the MemberAppointmentResults table
    'make sure that the DiagCodes variable contains a value
    If DiagCodes = 0 OrElse DiagCodes = Nothing Then
        Return View() 'just go back to the view you were just on
    End If
   'Grab the diagnostic code record
    Dim DiagCodeModel As IEnumerable(Of DiagnosisCode) = From s In db.DiagnosisCodes
                                                         Where s.VADiagnosisCode = DiagCodes
                                                         Order By s.VADiagnosticCodeID
                                                         Select s

    ViewBag.VADiagCdWebgrid = DiagCodeModel.FirstOrDefault
    'find the record in MemberAppointmentResults associated with the selected Diagnosis Code
    Dim VADiag = ViewBag.VADiagCdWebgrid.Find(DiagCodes)
    'Create a boolean to identify that the selected Diagnosis code is in the memberappointmentresults table
    Dim diagCodeExists As Boolean = False
    For Each VADiagCode As MemberAppointmentResult In VADiag.MemberAppointmentResults
        'Identify that the selecte Diagnosis codes is already in the viewmodel
        If VADiagCode.DiagnosisCode.VADiagnosisCode = DiagCodes Then
            diagCodeExists = True
        End If
    Next
    'lets not add duplicate values if we can keep from it.
    If diagCodeExists = False Then
        'determine how many rows already exist and add another one
        result.ResultID = VADiag.VADiagCdWebgrid.Count + 1
        'save the selected Diagnosis Code
        'result.VADiagnosticCodeID = DiagCodeModel.DiagnosticCode
        'get the diagnosis code id from the diagnosis code table
        result.VADiagnosticCodeID = db.DiagnosisCodes.Find(DiagCodes).VADiagnosticCodeID
        'get the diagnosis code description from the diagnosis code table
        'result.DiagnosticCodeDescription = db.DiagnosisCodes.Find(DiagCodes).DiagnosisCodeDescription
        'if that worked, add the new row to the viewmodel
        If ModelState.IsValid Then
            VADiag.Add(result)
        End If
    End If
    ViewBag.NewAppResult = New MemberAppointmentResult With {.ResultID = db.MemberAppointmentResults.Count + 1}
    Return View("Create", VADiag)
End Function

Private Function PopulateDiagCodesDropDownList() As SelectList
    Dim diagCodesQuery = db.DiagnosisCodes.OrderBy(Function(d) d.VADiagnosisCode).Select(Function(d) New With {d.VADiagnosticCodeID, .VADiagnosisCode = d.VADiagnosisCode & " - " & d.DiagnosisCodeDescription}).ToList()
    Return New SelectList(diagCodesQuery, "VADiagnosticCodeID", "VADiagnosisCode")
End Function

Create.vbhtml

@Imports System.Web.Mvc.Html
@Imports PtdrWeb.CompleteValidationAndFormatting
@ModelType PtdrWeb.AddAppointmentViewModel
@Code
    ViewData("Title") = "Create Member Appointment"
End Code
<br>
<div Class="row">
    <div Class="three columns">
        <strong>Create Member Appointment</strong>
    </div>
</div>
<br>
<hr />
@Using Html.BeginForm("Create", "Appointment", New With {.memId = ViewBag.MemID}, FormMethod.Post, New With {.autocomplete = "off"})
    @Html.AntiForgeryToken()
**---all the other fields are listed here... this part actually works**

**---the next line activates a partial view (or screen)**
    @<div Class="row">
        @Html.Partial("AddDiagCdResult", ViewBag.NewAppResult)
    </div>
   @<hr />
End Using

AddDiagCdResult.vbhtml

@ModelType PtdrWeb.MemberAppointmentResult
@Using Html.BeginForm("AddDiagCodeResult", "Appointment")
    @<div class="zebra_stripe_rows">
        <h4>Diagnosis Codes:</h4>
        <hr />
        <div class="row">
            <div class="five columns">
                <strong>Select Diagnostic Codes</strong>
            </div>
            <div class="one column">
                @Html.LabelFor(Function(model) model.ResultID, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="one column">
                @Html.LabelFor(Function(model) model.AppointmentID, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="one column">
                @Html.LabelFor(Function(model) model.VADiagnosticCodeID, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="one column">
                @Html.LabelFor(Function(model) model.DiagnosisCode.VADiagnosticCodeID, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="two columns">
                @Html.LabelFor(Function(model) model.DiagnosisCode.VADiagnosisCode, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="two columns">
                @Html.LabelFor(Function(model) model.DiagnosisCode.DiagnosisCodeDescription, htmlAttributes:=New With {.class = "control-label col-md-2"})
            </div>
            <div class="two columns">        </div>
        </div>
**---this is where the grid should be displayed**
        <div class="grid-container">
            <div class="five columns">

**---this is the dropdownlist that I want to go to the AddDiagCodeResult function in the Appointment Controller when an Item in the dropdown is selected.**
                @Html.DropDownList("DiagCodes", Nothing, New With {.onchange = "this.form.submit()", .style = "width:575px;"})
            </div>
            <div class="one column">
                @Html.DisplayFor(Function(model) model.ResultID, New With {.htmlAttributes = New With {.class = "grid-item"}})
             </div>
            <div class="one column">
                @Html.DisplayFor(Function(model) model.AppointmentID, New With {.htmlAttributes = New With {.class = "grid-item"}})
            </div>
            <div class="one column">
                @Html.DisplayFor(Function(model) model.VADiagnosticCodeID, New With {.htmlAttributes = New With {.class = "grid-item"}})
            </div>
            <div class="one column">
                @Html.DisplayFor(Function(model) model.DiagnosisCode.VADiagnosticCodeID, New With {.htmlAttributes = New With {.class = "grid-item"}})
            </div>
            <div class="two column">
                @Html.DisplayFor(Function(model) model.DiagnosisCode.VADiagnosisCode, New With {.htmlAttributes = New With {.class = "grid-item"}})
            </div>
            <div class="two columns">
                @Html.DisplayFor(Function(model) model.DiagnosisCode.DiagnosisCodeDescription, New With {.htmlAttributes = New With {.class = "grid-item"}})
            </div>
            <div class="two columns">
                @Html.ActionLink("Remove", "DiagnosisCodeRemove", "Appointment", New With {.id = Model.ResultID}, New With {.class = "secondary button row"})
            </div>
        </div>
    </div>

End Using

AddAppointmentViewModel.vb

Public Class AddAppointmentViewModel
    Public Property AppointmentID As Integer
    Public Property MemberEventID As Integer
    Public Property ScheduledVisitDate As Date
    <VisitTime()>
    Public Property ScheduledVisitTime As TimeSpan?
    Public Property HospitalID As Integer
    Public Property ActualVisitDate As Date?
    <VisitTime()>
    Public Property ActualVisitTime As TimeSpan?
    Public Property ActualHospitalID As Integer?
    Public Property IsVisitCompleted As Boolean
    Public Property CurrentDisabilityPercentage As Byte?
    Public Property MtfReasonCodeID As Integer
    Public Overridable Property EventHistory As EventHistory
    Public Overridable Property Hospital As Hospital
    Public Overridable Property MemberAppointmentResults As ICollection(Of MemberAppointmentResult) = New HashSet(Of MemberAppointmentResult)
    Public Overridable Property MtfReason As MtfReason
    Public Property DiagCodes As Integer
    Public Overridable Property VADiagCdWebgrid As ICollection(Of DiagnosisCode) = New HashSet(Of DiagnosisCode)
End Class

DiagnosisCode.vb

Partial Public Class DiagnosisCode
    Public Property VADiagnosticCodeID As Integer
    Public Property VADiagnosisCode As String
    Public Property DiagnosisCodeDescription As String
    Public Overridable Property MemberAppointmentResults As ICollection(Of MemberAppointmentResult) = New HashSet(Of MemberAppointmentResult)
End Class

MemberAppointmentResult.vb

Partial Public Class MemberAppointmentResult
    Public Property ResultID As Integer
    Public Property AppointmentID As Integer
    Public Property VADiagnosticCodeID As Integer
    Public Overridable Property DiagnosisCode As DiagnosisCode
    Public Overridable Property MemberAppointment As MemberAppointment
End Class

MemberAppointment.vb

Partial Public Class MemberAppointment
    Public Property AppointmentID As Integer
    Public Property MemberEventID As Integer
    Public Property ScheduledVisitDate As Date
    Public Property ScheduledVisitTime As Nullable(Of System.TimeSpan)
    Public Property HospitalID As Integer
    Public Property ActualVisitDate As Nullable(Of Date)
    Public Property ActualVisitTime As Nullable(Of System.TimeSpan)
    Public Property ActualHospitalID As Nullable(Of Integer)
    Public Property IsVisitCompleted As Boolean
    Public Property CurrentDisabilityPercentage As Nullable(Of Byte)
    Public Property MtfReasonCodeID As Integer
    Public Overridable Property EventHistory As EventHistory
    Public Overridable Property Hospital As Hospital
    Public Overridable Property MemberAppointmentResults As ICollection(Of MemberAppointmentResult) = New HashSet(Of MemberAppointmentResult)
    Public Overridable Property MtfReason As MtfReason
End Class

Solution

  • Another way to do this is to have multiple Using/End Using statements to cover the different sections that need to activate different controller methods. You wouldn't have to have to activate an Html.Partial statement, all the code could be in the one View file.