I'm using unobtrusive ajax inside a kendo window to update a form once it's been filled in. The form should update the Id's of the DOM elements dynamically and also show the relative data inside the form as returned from the controller.
Let's start, here is the window element that houses the partial view which is a form:
@model Requirement
@{
int localId = Model.Id;
}
<div class="window-content">
<form method="post" data-ajax-url="/Home/Process_Requirement" data-ajax="true" data-ajax-method="post" data-ajax-loading="#spinner" data-ajax-update="#update-form-requirement" data-ajax-success="form_requirement_success">
<div id="update-form-requirement">
<partial name="_Form_Requirement" />
</div><!--/update-panel-->
<div class="window-footer">
<div class="container">
<div class="row no-gutters">
<div class="col">
<button type="submit" class="input-submit float-right">Save</button>
</div>
</div>
</div>
</div>
</form>
</div>
_Form_Requirement
@model Requirement
@{
int localId = Model.Id;
}
<div class="tab-content">
<div class="tab-pane fade show active" id="form-requirement-basic-@localId" role="tabpanel" aria-labelledby="requirement-tab">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="text" id="Id_@localId" name="Id" asp-for="Id" readonly />
<input type="text" id="CreatedUser_@localId" asp-for="CreatedUser" readonly />
<div class="container">
<div class="row">
<div class="col">
<div class="form-group">
<label>Vessel Type</label>
<kendo-dropdownlist name="VesselType"
for="VesselType"
id="VesselType_@localId"
datatextfield="TypeName"
datavaluefield="Id"
min-length="3"
style="width: 100%"
value-primitive="true"
option-label="Select vessel type"
footer-template="<button class='dropdown-button k-icon k-i-plus-outline' data-object-title='Add vessel type' data-object-function='_Window_Vessel_Type' onclick='open_data_window(this, event)'></button>"
filter="FilterType.Contains">
<datasource type="DataSourceTagHelperType.Ajax" page-size="80">
<transport>
<read url="/Vessel/ReadVesselTypes" />
</transport>
</datasource>
<popup-animation>
<open duration="300" effects="fadeIn" />
<close duration="300" effects="fadeOut" />
</popup-animation>
</kendo-dropdownlist>
</div>
</div>
</div>
</div>
</div>
</div>
When the form is submitted the controller action does the following:
/Home/Process_Requirement
public IActionResult Process_Requirement(Requirement model)
{
//Define the partial view we want
string modal = "_Form_Requirement";
//If the Id is 0 then create a new requirement
if (model.Id == 0)
{
if (ModelState.IsValid)
{
try {
_requirementService.InsertRequirement(model);
var getData = _requirementService.GetRequirement(model.Id);
return PartialView(modal, getData);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
else
{
try
{
_requirementService.UpdateRequirement(model);
return PartialView(modal, model);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return PartialView(modal);
}
So, when you first open a window to create a new requirement the localId
is 0
because you're not editing one, that's expected behavior.
When you then fill in all the details and submit the form, the data is posted to the database and saved correctly but the model doesn't seem to update with the new data, for example the input for the Id remains as 0:
<input type="text" id="Id_@localId" name="Id" asp-for="Id" readonly />
yet the id for the input updates to the newly created id number. Why is this happening and can I do anything about it?
Is the Id primary key? If so, it is not recommend to change the primary key, you should add a new column to be the key.
This could be caused by the concurrency issues. I can't see your update code now, but you can
try to change your update code like this:
My Model:
And in partial, pass the key with a hidden field:
Result: