So, I have a referral form for job application. Now when a job seeker selects a company from a company dropdown, I want to display the dropdown of coverletters just for that company (coverletters are already uploaded by candidate from another tab). Now for getting referred for Microsoft a person might have 3 coverletters.
Issue:
I want to know how to can I display the dropdown from ajax call and still keep the coverletter dropdown strongly bound to the Model.
Below is Non AJAX strongly Bound: shows all the coverletters irrespective of company selected)
View:
@model Bridge.ViewModels.ReferralViewModel
@using (Html.BeginForm())
{
<div class="form-group">
@Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.CompanyId, Model.Companies, new { @class = "form-control js-change", onchange = "companyChanged()" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoverLetterId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.CoverLetterId, new SelectList(Model.CoverLetters, "CoverLetterId", "CoverLetterName", Model.CoverLetters), new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Model:
public class ReferralViewModel
{
public int ReferralViewModelId { get; set; }
public int CompanyId { get; set; }
public IEnumerable<SelectListItem> Companies { get; set; }
public int CoverLetterId { get; set; }
public IEnumerable<CoverLetter> CoverLetters { get; set; }
}
Controller:
public ActionResult Create()
{
var viewModel = new ReferralViewModel
{
var candidateId = User.Identity.GetUserId();
Companies = _context.Companies.Select(x => new SelectListItem
{
Text = x.CompanyName,
Value = x.CompanyId.ToString()
}),
CoverLetters = _context.CoverLetters.Where(r => r.CandidateId == candidateId).ToList()
};
return View(viewModel);
}
Now AJAX Attempt:
Controller Action
public JsonResult ListOfCoverLetterByCompanyId(int companyId)
{
var coverletters = _context.CoverLetters
.Where(c => c.CompanyId == companyId)
.ToList();
var dropdown = new List<SelectListItem>();
foreach (var cl in coverletters)
{
dropdown.Add(new SelectListItem { Text = cl.CoverLetterName, Value = cl.CoverLetterId.ToString() });
}
return Json(dropdown, JsonRequestBehavior.AllowGet);
}
New View
@model Bridge.ViewModels.ReferralViewModel
@using (Html.BeginForm())
{
@Html.LabelFor(model => model.CompanyId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(m => m.CompanyId, Model.Companies, new { @class = "form-control js-change", onchange = "companyChanged()" })
</div>
</div>
@* Dropdown will appear here*@
<select id="CoverLetterId" name="CoverLetterId"></select>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
@section scripts{
<script>
function companyChanged() {
var companyId = $(".js-change").val();
$.ajax({
url: "/Referral/ListOfCoverLetterByCompanyId",
data: { companyId: companyId },
contentType: "application/json; charset-utf-8",
success: function (datas) {
$("#CoverLetterId").html("");
$.each(datas, function (i, data) {
$("#CoverLetterId ").append('<option value="' + data.Value + '">' + data.Text + '</option>');
});
},
error: function () {}
});
}
</script>
<script>
companyChanged();
</script>
}
New View Model
public class ReferralViewModel
{
public int ReferralViewModelId { get; set; }
public int CompanyId { get; set; }
public IEnumerable<SelectListItem> Companies { get; set; }
public int CoverLetterId { get; set; }
}
I think by following current code I lost the beauty of strongly bound Razor view. Dropdown is not bound to any property. Can I somehow make it strongly bound and use @Html.DropdownListFor