4

I am working with MVC 5, VB.NET, jQuery.

On one of my pages, I am calling an action using an ajax call, and trying to reload the html based on the result.

I am modifying two properties:

  1. Message
  2. Identifier

The message is being replaced with the the intended result, however, the Identifier is not.

Here's the code:

View:

@model CapitalLending.LoanScoreModel
    

<div class="container">
    <form id="scoring-form">
        <label class="text-danger">@Html.DisplayFor(model => model.ErrorMessage)</label>
        <label class="text-success">@Html.DisplayFor(model => model.SuccessMessage)</label>
        @Html.HiddenFor(model=>model.LoanId)
        <div class="row">
            <div class="col-lg-6 form-group">
                <div class="row col-lg-12">
                    @Html.LabelFor(model => model.Loan.ClientId, new {@class = "col-lg-6 col-md-6 col-sm-6"})
                    @Html.TextBoxFor(model => model.Loan.ClientId, new {@class = "form-control col-lg-6 col-md-6 col-sm-6"})
                </div>
                <div class="row col-lg-12">
                    @Html.LabelFor(model => model.ScoreIdentifier, new {@class = "col-lg-6 col-md-6 col-sm-6"})
                    @Html.TextBoxFor(model => model.ScoreIdentifier, new {@class = "form-control col-lg-6 col-md-6 col-sm-6"})
                </div>
                <div class="row col-lg-12">
                    @Html.LabelFor(model => model.Score, new {@class = "col-lg-6 col-md-6 col-sm-6"})
                    @Html.TextBoxFor(model => model.Score, new {@class = "form-control col-lg-6 col-md-6 col-sm-6"})
                </div>
            </div>
            <div class="col-lg-6">
                <div class="row col-lg-12">
                    @Html.LabelFor(model => model.OperatorScore, new {@class = "col-lg-6 col-md-6 col-sm-6"})
                    @Html.TextBoxFor(model => model.OperatorScore, new {@class = "form-control col-lg-6 col-md-6 col-sm-6"})
                </div>
                <div class="row col-lg-12">
                    @Html.LabelFor(model => model.OperatorComment, new {@class = "col-lg-6 col-md-6 col-sm-6"})
                    @Html.TextAreaFor(model => model.OperatorComment, new {@class = "form-control col-lg-6 col-md-6 col-sm-6"})
                </div>
            </div>
        </div>
        <div class="row">
            <div class="col-lg-3">
                <button name="get-identifier" value="get-identifier" class="ui btn btn-primary col-lg-6 col-md-6 col-sm-6" onclick="GetIdentifier()">Get Identifier</button>
            </div>
            <div class="col-lg-3">
                <button name="get-score" value="get-score" class="ui btn btn-primary col-lg-6 col-md-6 col-sm-6" onclick="GetScore()">Get Score</button>
            </div>

            <div class="col-lg-6 pull-right">
                <button name="submit-score" value="submit-score" class="ui btn btn-primary col-lg-3 col-md-3 col-sm-3 pull-right" onclick="SubmitScore()">Submit Score</button>
            </div>
        </div>
    </form>
    
</div>


<script type="text/javascript">

    $('form#scoring-form').submit(function(e) {
        e.preventDefault();
        return;
    });

    function GetIdentifier() {
        $.ajax({
            type: "GET",
            url: '/Scoring/create-scoring',
            cache: false,
            data: $('#scoring-form').serialize(),
            // dataType: 'text/json',
            success: function (result) {
               // console.log(result);
               $('#scoring').html(result);
            }
        });
    }
</script>

Note that the #scoring id is the parent div inside the parent view. This is just a partial view.

Controller:

<ActionName("create-scoring")>
Public Function CreateScoringFileForClient(oModel As LoanScoreModel) As ActionResult
    Dim oResult As ScoringResultModel = ScoringStrategy.CreateScoringFile(oModel)
    If oResult.IsSuccess Then
        If oResult.ResultFound Then
            oModel.ScoreIdentifier = oResult.ScoringModel.Identifier.ToString
            oModel.SuccessMessage = "Identifier Received"

            ScoringManager.SetLoanScoreIdentifier(oModel.LoanId, oModel.ScoreIdentifier)
           
            Return PartialView("_Scoring", oModel)
        Else
            Dim sErrorMessage = "No Reply From Scoring API"
            oModel.ErrorMessage = sErrorMessage
            Return PartialView("_Scoring", oModel)
        End If
    Else
        Dim sErrorMessage = "Couldn't call API"
        oModel.ErrorMessage = sErrorMessage
        Return PartialView("_Scoring", oModel)
    End If
End Function

I made sure that with breakpoints that the identifier is not empty, and that it's being returned with Return PartialView("_Scoring", oModel).

When the call ends, and the result is returned, the only change I am seeing is the message shown, but the TextBox is not modified:

Result after Ajax Call

I have identified the problem after I called console.log(result) inside the success ajax function, and I found out that the message is being added, but the Identifier is not, and I can't find the solution to that so far.

What could be causing this problem ? And how to fix it ?

Update:

I have tried adding this to my view:

<label class="text-danger">@Html.DisplayFor(model => model.ScoreIdentifier)</label>

under the other two labels.

When I get the result back in ajax, the label is shown with the correct value, but the text box is not being updated.

EDIT:

Following Swati's comment, I've tried adding the @value to html attributes like this:

@Html.TextBoxFor(model => model.ScoreIdentifier, new { @class = "form-control col-lg-6 col-md-6 col-sm-6", @id = "identifier", @readonly = "readonly", @value = Model.ScoreIdentifier })

This also didn't update the value on ajax reply.. however, if I use Model.ScoringIdentifier somewhere else in the view, it will show the real value.. I have a feeling it has something to do with @Html.TextBoxFor...

To answer Chandan's request, here's the models I am using:

Public Class LoanScoreModel
    Public property Id As Integer
    Public property LoanId As Integer
    Public property ScoreIdentifier As String
    Public property Score As Double
    Public property IdentifierDateAcquired As DateTime
    Public property ScoreDateAcquired As DateTime
    Public property OperatorScore As Double
    Public property OperatorScoreDateAcquired As DateTime
    Public property OperatorComment As String
    Public property OperatorUserId As Guid
    Public Property Loan As Loan
    Public Property ErrorMessage As String = ""
    Public Property SuccessMessage As String = ""
End Class

Public Class ScoringResultModel
    Public Property IsSuccess As Boolean
    Public Property ResultFound As Boolean
    Public Property ErrorMessage As String
    Public Property ScoringModel As ScoringModel
End Class

Public Class ScoringModel
    Public Property Identifier As Guid
    Public Property Score As Double
End Class
Paul Karam
  • 4,052
  • 8
  • 30
  • 53

1 Answers1

0

While editing the question last time, and saying that I have a feeling it has something to do with @Html.TextBoxFor..., I followed up by doing some more searches on how to make sure the Text Box will be refreshed after an Ajax call.

I landed up on these two questions on SO:

TextBoxFor is not refreshing after postback
How to update the textbox value @Html.TextBoxFor(m => m.MvcGridModel.Rows[j].Id)

Quoting from second question:

That's because HTML helpers such as TextBoxFor first look in the ModelState when binding their values and only after that in the model. So if in your POST action you attempt to modify some value that was part of the initial POST request you will have to remove it from the ModelState as well if you want those changes to take effect in the view.

In the end, since I am using an HTML helper, I had to clear my model state before returning the model, so my controller was changed to this:

<ActionName("create-scoring")>
Public Function CreateScoringFileForClient(oModel As LoanScoreModel) As ActionResult
    Dim oResult As ScoringResultModel = ScoringStrategy.CreateScoringFile(oModel)
    ModelState.Clear() 'https://stackoverflow.com/questions/11341545/how-to-update-the-textbox-value-html-textboxform-m-mvcgridmodel-rowsj-id
    oModel.ErrorMessage = ""
    oModel.SuccessMessage = ""
    If oResult.IsSuccess Then
        If oResult.ResultFound Then
            oModel.ScoreIdentifier = oResult.ScoringModel.Identifier.ToString
            oModel.SuccessMessage = Resources.Resources.IdentifierReceived

            ScoringManager.SetLoanScoreIdentifier(oModel.Loan.ID, oModel.ScoreIdentifier)
           
            Return PartialView("_Scoring", oModel)
        Else
            Dim sErrorMessage = Resources.Resources.ProblemAPINoResult
            oModel.ErrorMessage = sErrorMessage
            Return PartialView("_Scoring", oModel)
        End If
    Else
        Dim sErrorMessage = Resources.Resources.ProblemAPINoSuccess
        oModel.ErrorMessage = sErrorMessage
        Return PartialView("_Scoring", oModel)
    End If
End Function

Which fixed the problem, and now my text box is being refreshed with new data after call.

Paul Karam
  • 4,052
  • 8
  • 30
  • 53