Categories
ajax asp.net-mvc asp.net-mvc-5 jquery vb.net

Return PartialView(“view”, model) with Ajax is updating the labels but not the text boxes, even for same property

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

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.