MVC 4 Changing a field based on DropDownListFor selection - javascript

I have a form that has a dropdownlist that is made up of different course names and a textbox that will contain the number of the next course section based on the dropdown selection and its highest existing section number in the database. After a selection is made the javascript will get called, then call my controller method to figure out which section number it should be, and then fill the textbox.
My dropdownlist: Controller
ViewBag.CourseList = new SelectList(db.CourseLists, "CourseTitle", "CourseTitle");
My dropdownlist: View
#Html.DropDownListFor(model => model.CourseTitle,
new SelectList(#ViewBag.CourseList, "Value", "Text"), " -- Select Course -- ", new { #id = "CourseTitle", onchange = "CourseChange()" })
#Html.ValidationMessageFor(model => model.CourseTitle)
Textbox:
#Html.EditorFor(model => model.ClassNumber, new { #id = "ClassNumber" })
#Html.ValidationMessageFor(model => model.ClassNumber)
Javascript functions:
<script type="text/javascript">
function CourseChange() {
var courseTitle = $('#CourseTitle').val(); //Is always null
$.getJSON("NextClassNumber", courseTitle, updateClassNumber);
};
updateClassNumber = function (data) {
$('#ClassNumber').val(data);
};
</script>
When I make a change my method in my controller is called and passes back a value and sets my textbox, but the value for the selected item is coming through as null. Any ideas as to why?
::::EDIT::::
#model QIEducationWebApp.Models.Course
#{
ViewBag.Title = "Add New Course";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
$(function () {
$('#CourseTitle').on('change', function () {
var courseTitle = $(this).val();
$.ajax({
url: '#Url.RouteUrl(new{ action="NextClassNumber", controller="Course"})',
data: { courseTitle: courseTitle },
type: 'get'
}).done(function (data) {
$('#ClassNumber').val(data);
});
});
});
</script>
<h1 class="page-header">#ViewBag.Title</h1>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<table class="table">
<tr>
<th class="table-row">
Course Title:
</th>
<td class="table-row">
#Html.DropDownListFor(model => model.CourseTitle1,
#ViewBag.CourseList as SelectList, " -- Select Course -- ", new { #class="form-control", #id="CourseTitle" })
#Html.ValidationMessageFor(model => model.CourseTitle)
</td>
</tr>
<tr>
<th class="table-row">
Class Number:
</th>
<td class="table-row">
#Html.EditorFor(model => model.ClassNumber, new { #id = "ClassNumber" })
#Html.ValidationMessageFor(model => model.ClassNumber)
</td>
</tr>
<tr>
<th class="table-row">
Course Type:
</th>
<td class="table-row">
#Html.DropDownList("CourseType", " -- Select Type -- ")
#Html.ValidationMessageFor(model => model.CourseType)
</td>
</tr>
<tr>
<th class="table-row">
Start & End Date:
</th>
<td class="table-row">
#Html.EditorFor(model => model.CourseStartDate)
#Html.ValidationMessageFor(model => model.CourseStartDate)
</td>
<td class="table-row">
#Html.EditorFor(model => model.CourseEndDate)
#Html.ValidationMessageFor(model => model.CourseEndDate)
</td>
</tr>
<tr><td class="table-row-blank"></td></tr>
<tr>
<td class="table-row-button">
<input class="button" type="submit" value="Create" />
<input type="button" class="button" value="Cancel"
onclick="location.href='#Url.Action("Index")'" />
</td>
</tr>
</table>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}

your code should work fine if the select list is being generated correctly.
I would use part of the suggestion above and use
#Html.DropDownListFor(model => model.CourseTitle,
(SelectList)ViewBag.CourseList,
" -- Select Course -- ",
new { onchange = "CourseChange()" })
using another good suggestion already mentioned you can change your script to use on instead
<script type="text/javascript">
$(function () {
$('#CourseTitle').on('change', function () {
var courseTitle = $(this).val();
$.getJSON("NextClassNumber", courseTitle, function (data) {
$('#ClassNumber').val(data);
});
});
});
</script>
here is a dotnetfiddle example. DotNetFiddle

You can pass reference of dropdownlist from the onchange event :
onchange = "CourseChange"
and in js function:
function CourseChange(element) {
var selected = element.Value;
// or
var selected = $(element).val();
and a side note you don't need to construct SelectList again on View just cast it from ViewBag:
#Html.DropDownListFor(model => model.CourseTitle,
#ViewBag.CourseList as SelectList,
"-- Select Course --",
new { onchange = "CourseChange" })

Related

How to add or remove records from table on click add button, and send all table rows to controller on submit?

I'm sharing image of my task:
I have issue that, when I clicked on Add Button all fields data will display in table below, and I want to add multiple products to this table, also if user wants to remove any product from table then clicked on remove button.
After add products when user clicked on submit then all record send to controller method.
I'm sharing some code which I'm trying to do.
View Code
<div class="row">
<div class="col-md-12">
<div class="tile">
<div>
<h1><i class="fa fa-th-list"></i> Inventory</h1>
<p>Issu Products to Unit</p>
</div>
#Html.Partial("~/Views/Shared/_ErrorMsgPartial.cshtml")
<div class="tile-body">
<span style="color:red; font-weight:bold;">Note: Dont Enter Quantity Morethan Availabale Quantity</span>
#using (Html.BeginForm("IssueProduct", "Inventory", FormMethod.Post, new { #id = "formPost" }))
{
<table class="table table-hover table-bordered">
<thead>
<tr>
<th>Product</th>
<th>Available Qty</th>
<th>Issue Qunatity</th>
<th>Unit</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Html.DropDownList("productId", null, "Select One", htmlAttributes: new { #class = "form-control", id = "demoSelect" })
#Html.ValidationMessageFor(model => model.productId, "", new { #class = "text-danger" })
</td>
<td id="GetAvlbQty" style="font-weight: bold;color: red;text-align: center;">
#{Html.RenderPartial("GetAvlbQty", Model);}
</td>
<td>
#Html.EditorFor(model => model.invQty, new { htmlAttributes = new { #class = "form-control", id = "invcQty", #PlaceHolder = "Enter Quantity To Issue" } })
#Html.ValidationMessageFor(model => model.productId, "", new { #class = "text-danger" })
</td>
<td>
#Html.DropDownListFor(model => model.invUnit, new List<SelectListItem>
{
new SelectListItem{Text="Unit A",Value="Unit A"},
new SelectListItem{Text="Unit B",Value="Unit B"},
}, "Select Unit", htmlAttributes: new { #class = "form-control", id = "unit" })
#Html.ValidationMessageFor(model => model.invUnit, "", new { #class = "text-danger" })
</td>
<td>
#Html.EditorFor(model => model.invDescription, new { htmlAttributes = new { #class = "form-control", id = "descrip", #PlaceHolder = "Enter Description" } })
#Html.ValidationMessageFor(model => model.invDescription, "", new { #class = "text-danger" })
</td>
<td>
<button type="button" id="btnAdd" class="btn btn-outline-success btn-s classAdd">Add</button>
</td>
</tr>
</tbody>
</table>
<table id="tablePost" class="table table-hover table-bordered">
<thead>
<tr>
<th>Product</th>
<th>Available Qty</th>
<th>Issue Qunatity</th>
<th>Unit</th>
<th>Description</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
<input type="submit" class="btn btn-outline-success btn-sm" value="Save" />
}
</div>
</div>
</div>
</div>
Here is some jQuery code but it just add product to row. Not remove and also not send into controller. I don't need to send data through HIDDEN FIELDS.
$(document).ready(function () {
$("#btnAdd").on("click", function () {
var demoSelect = $("#demoSelect :selected").text();
var invcAvlbQty = $("#availableQty").val();
var invcQty = $("#invcQty").val();
var unit = $("#unit :selected").val();
var descrip = $("#descrip").val();
$("#tablePost > tbody").append("<tr><td>" +
demoSelect + "</td><td>" + invcAvlbQty + "</td><td>" + invcQty + "</td><td>" + unit + "</td><td>" + descrip + "</td></tr>");
});
});
How can I resolve this?
Create table from you want to add the record in list-
<div>
<table>
<tr>
<td><input type="text" id="txt1"/></td>
<td><input type="submit" id="btnAdd" value="Add"/></td>
</tr>
</table>
</div>
<div>
<table id="tbldata"> </table>
</div>
<div>
<input type="submit" id="btnsubmit" value="Save"/>
</div>
this function is used for add record in list on button add click
$('#btnAdd').click(function(){
if (!localStorage.count) {
localStorage.count = 0;
}
localStorage.count++;
var num = localStorage.count;
var TextVal=$('#txt1').val();
$('#tbldata').append('<tr id=' + num + '><td>'+TextVal+'</td>
<td><a
href="javascript:void(0)"
onclick="Removerow(' + num + ')" >Remove</a></td></tr>')
})
this function is used for remove the row from table in list
function Removerow(id)
{
$("#"+id+"").remove();
}
this function is used for get al the record from list added in table
$('#btnsubmit').click(function(){
GetRecord();
})
function GetRecord()
{
var table = $("#tbldata");
//find all table tr value usnig each loop
table.find('tr').each(function (i, el) {
var $tds = $(this).find('td'),
ItemName = $tds.eq(0).val();
SaveRecord(ItemName);
}
this function is used for save record in db
function SaveRecord(ItemName) {
$.ajax({
type: 'GET',
dataType: 'json',
url: "Controllername/actionname",
data: { _ItemName : ItemName },
success: function (Data) {
localStorage.clear();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
}
Hope it will help you.

Passing Data in wizard form without post back in MVC

Sorry for any mistake. I am new to MVC. I want to pass data from one wizard form to other in single view. Below is my controller side code which return list to view. In view there is wizard form where i make update some field in list and on next button i want to pass all changed data to next wizard form in table.
public ActionResult PlaceOrder()
{
OrderDetail ObjOrderDetails = new OrderDetail();
try
{
DataSet ds = new DataSet();
ds = GeneralHelper.GetUserDocumentDetail(1);
List<OrderModel> objOrder = ds.Tables[0].ToList<OrderModel>();
ObjOrderDetails.OrderDetails = objOrder;
}
catch (Exception ex)
{
throw ex;
}
return View(ObjOrderDetails);
}
Below is my view side Code
<div class="tab-content">
<div class="tab-pane" id="details">
<div class="row">
<div class="col-sm-12">
<h4 class="info-text">
Let's start with the basic details.</h4>
</div>
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-12">
<div class="persons">
<table class="table table-condensed table-hover" id="tblPurchaseOrders">
<tr>
<th>
Product Code
</th>
<th>
SKU
</th>
<th>
Product Name
</th>
<th>
Quantity
</th>
</tr>
#{
//To make unique Id int i = 0;
foreach (var item in Model.OrderDetails.ToList())
{
<tr>
<td>
#Html.EditorFor(o => o.OrderDetails[i].ProductCode, new { htmlAttributes = new { #class = "form-control", disabled = "disabled", #readonly = "readonly" } })
</td>
<td>
#Html.EditorFor(o => o.OrderDetails[i].SKU, new { htmlAttributes = new { #class = "form-control", disabled = "disabled", #readonly = "readonly" } })
</td>
<td>
#Html.EditorFor(o => o.OrderDetails[i].Name, new { htmlAttributes = new { #class = "form-control", disabled = "disabled", #readonly = "readonly" } })
</td>
<td>
#Html.EditorFor(o => o.OrderDetails[i].Quantity, new { #id = "Quantity_" + i })
</td>
</tr>
i++; } }
</table>
</div>
</div>
</div>
<hr />
</div>
</div>
</div>
<div class="tab-pane" id="captain">
<div class="row">
<div class="form-group">
<div class="col-md-12">
<table class="table table-condensed table-hover" id="tbOrderDetail">
<tr>
<th>
Product Code
</th>
<th>
SKU
</th>
<th>
Product Name
</th>
<th>
Quantity
</th>
</tr>
</table>
</div>
</div>
</div>
</div>
Below is my jquery code.
$('#rootwizard').bootstrapWizard({
onTabShow: function(tab, navigation, index) {
if (index == 1) {
$(".persons > table").each(function() {
var fields = $(this).find(":text");
alert(fields)
var name = fields.eq(-1).val();
var age = fields.eq(1).val();
alert(name);
});
}
}
});
I want to loop all rows of #tblPurchaseOrders and want to append all the rows to #tbOrderDetail where quantity is greater than 0.
You can do it like below:
$('#rootwizard').bootstrapWizard({
onTabShow: function(tab, navigation, index) {
if (index == 1) {
$('#tblPurchaseOrders').find('tr:has(td)').each(function() {
if (parseInt(($(this).find('#Quantity')).val()) > 0)
$(this).appendTo('#tbOrderDetail');
});
}
}
});
Online Demo (jsFiddle)

Value of other column in the row in dynamic row is not changing

I have a dynamic row here and I have created a drop down of product and I want that price is changed automatically when the drop down is selected.
<div>
#using (Html.BeginForm("SaveProduct", "Master", FormMethod.Post, new { #id = "frmProductDetail", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
// #Html.Hidden("ProductOrderId", Model.ProductOrderId)
// #Html.Hidden("ProductId", Model.ProductId)
<div class="row-fluid border-light-color">
<div class="padding-5">
<div class="span12">
<div class="clear"></div>
<div class="Col1">
<span>#Html.LabelFor("Customer Name"):</span>
</div>
<div class="Col2">
#Html.TextAreaFor(m => m.CustomerName, new { #name = "CustomerName", #id = "CustomerName", #class = "txtCustDetails" })
</div>
<div class="Col3">
<span>#Html.LabelFor("Contact Number"):</span>
</div>
<div class="Col4">
#Html.TextAreaFor(m => m.CustomerNumber, new { #name = "CustomerName", #id = "CustomerName", #class = "txtCustDetails" })
</div>
<div class="clear"></div>
<div class="Col1">
<span>#Html.LabelFor("FirstName"):</span>
</div>
<div class="row-fluid">
Add
</div>
<div class="row-fluid">
<table class="table table-bordered table-hover gridtable" id="tblProduct" showsequence="true">
<thead>
<tr>
<th style="width:20%">SR No.</th>
<th style="width:20%">Product Name</th>
<th style="width:20%">Rate</th>
<th style="width:20%">Quantity</th>
<th style="width:20%">Grand Total</th>
<th style="width:20%">Delete</th>
</tr>
</thead>
<tbody>
<tr id="0" style="display:none">
<td class="text-center"></td>
<td>
#Html.DropDownList("ProductId", Model.ProductName.ToSelectList(Model.ProductNameId.ToString(), "Name","Value"))
</td>
<td>
#Html.TextBoxFor(m=>m.priceDetail, new { #name = "ProductPrice1", #id = "ProductPrice1", #class = "txtCustDetails"})
</td>
<td>
#Html.TextBoxFor(m=>m.OrderQuantity, new { #name = "OrderQuantity", #id = "OrderQuantity", #class = "txtCustDetails"})
</td>
<td>
#Html.TextBoxFor(m=>m.GrandTotal, new { #name = "GrandTotal", #id = "GrandTotal", #class = "txtCustDetails"})
</td>
<td class="text-center vertical-middle">
<i class="icon-trash" ></i>
</td>
</tr>
<tr id="1">
<td class="text-center">1</td>
<td>
#Html.DropDownList("ProductId", Model.ProductName.ToSelectList(Model.ProductNameId.ToString(), "Name", "Value"))
</td>
<td>
#Html.TextBoxFor(m=>m.priceDetail, new { #name = "ProductPrice2", #id = "ProductPrice2", #class = "txtCustDetails"})
</td>
<td>
#Html.TextBoxFor(m=>m.OrderQuantity, new { #name = "OrderQuantity", #id = "OrderQuantity", #class = "txtCustDetails"})
</td>
<td>
#Html.TextBoxFor(m=>m.GrandTotal, new { #name = "GrandTotal", #id = "GrandTotal", #class = "txtCustDetails"})
</td>
<td class="text-center vertical-middle">
<i class="icon-trash" ></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
}
</div>
I am trying to do it through Jquery but I am having problem that the price changes automatically only in the first row and not in the other rows. Please help me so that it changes in every row individually.
var GetPriceUrl = BASEPATHURL + "/Master/GetPriceDetail";
jQuery(document).ready(function () {
jQuery('#btnAdd').on('click', function () { AddRow('#tblProduct') });
//jQuery('#btnSave').on('click', function () { SaveEmployees() });
jQuery('#tblProduct').on('click', "a[name='RemoveRow']", function () { RemoveRow(this) });
jQuery("#tblProduct tbody").sortable({
//handle: '.glyphicon-move',
update: function () {
Reorder('#tblProduct');
}
});
jQuery("select[name]*=ProductId").change(function () {
GetPriceByProductId(jQuery(this).val());
jQuery(this).css('border-color', '');
});
});
function AddRow(tableId) {
var row = jQuery(tableId + ' > tbody > tr:first').clone(true);
var index = parseInt(jQuery(tableId + ' > tbody > tr:visible').length);
jQuery("input, textarea, select", row).each(function () {
jQuery(this).attr("id", jQuery(this).attr("id") + "_" + (index + 1));
jQuery(this).val('');
});
jQuery(tableId).append(row);
jQuery(row).show().attr("id", index);
Reorder(tableId);
}
function RemoveRow(control) {
var tableId = "#" + jQuery(control).closest("table").attr("id");
jQuery(control).closest("tr").remove();
jQuery(tableId + ' > tbody > tr:visible').each(function (i, e) { jQuery(e).attr("id", i + 1) });
Reorder(tableId);
}
function Reorder(tableId) {
jQuery(tableId + '[showSequence = "true"] > tbody > tr:visible').each(function (i, e) {
jQuery(this).find("td:first").text(i + 1);
});
}
function GetPriceByProductId(ProductId) {
if (jQuery.trim(ProductId) != ""){
var postData = { ProductId: ProductId };
AjaxCall({
url: GetPriceUrl,
postData: postData,
httpmethod: 'POST',
calldatatype: 'JSON',
sucesscallbackfunction: 'OnSucessGetProductById'
});
}
}
function OnSucessGetProductById(response) {
jQuery("#ProductPrice2").val('');
jQuery("#ProductPrice2").val(response.priceDetail[0].ProductPrice);
}
Well I found the solution to this. Posting so that it may help others (sick of no response :( ). I saw that my AddRow function was incrementing the ProductId by 1. so firstly I took the Id of it and acquired its substring, then I concatenated it with the pricedetail so that it changes with every row. i have provided the function below.
jQuery("select[name]*=ProductId").change(function () {
var xyz = jQuery(this).attr("id");
Pro_Id = xyz.substring(xyz.lastIndexOf('_'));
GetPriceByProductId(jQuery(this).val());
jQuery(this).css('border-color', '');
jQuery('#btnSave').on('click', function () { InsertProductDetail(); });
jQuery('#btnUpdate').on('click', function () { InsertProductDetail(); });
});
function OnSucessGetProductById(response) {
//Jquery("input[name^='PriceDetail']").split('_').val("");
if (Pro_Id == "ProductId") {
jQuery("#ProductPrice").val('');
jQuery("#ProductPrice").val(response.priceDetail[0].ProductPrice);
}
else {
jQuery("#ProductPrice" + Pro_Id).val('');
jQuery("#ProductPrice" + Pro_Id).val(response.priceDetail[0].ProductPrice);
}
Pro_Id = "";
}
I hope this helps anyone in future. Thanks.

Run js scripts after partial update of div

I'm using dialog in asp.net mvc4 and jQuery 2.1.4.
I have index page like
#model IEnumerable<Osample.Models.Role_Privilege_Map>
#{
ViewBag.Title = "RolePrivilgeMapping";
}
<script>
$(document).ready(function () {
registerEditDialogBox();
$.ajaxSetup({ cache: false });
function registerEditDialogBox() {
$(".editRoleDialog").on("click", function (e) {
event.stopPropagation();
var url = $(this).attr('href');
var $this = $(this);
$("#dialog-edit").dialog({
title: 'Edit Role',
autoOpen: false,
resizable: false,
height: 150,
width: 400,
modal: true,
draggable: true,
open: function (event, ui) {
$(this).load(url);
},
close: function (event, ui) {
registerEditDialogBox();
}
});
$("#dialog-edit").dialog('open');
return false;
});
}
});
</script>
<div id="heading">
<h2>Role - Privilge Mapping</h2>
</div>
<div id="RolePrivilgeMappingWrapper">
<div class="float-left" id="roleWrapper">
#Html.Partial("_Role", sample.Models.DataProvider.DataProvider.GetRoleNames())
</div>
</div>
My role partial page is
#model IEnumerable<sample.Models.webpages_Roles>
#{
ViewBag.Title = "Index";
}
<div class="settingsTable" style="position: relative; width: 100%; margin: 0 auto">
<div style="width: 50%; margin: 0 auto">
<div style="width: 50%; margin: 0 auto">
<h2>Role</h2>
</div>
</div>
<p>
#Html.ActionLink("Create New Role", "OpenAddRoleDialog", "RolePrivilegeMapping", null, new { #class = "createRole actionHyperLink" })
</p>
<table id="tblRole">
<tr>
<th>Role ID</th>
<th>
#Html.DisplayNameFor(model => model.RoleName)
</th>
<th>Action</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.RoleId)
</td>
<td>
#Html.DisplayFor(modelItem => item.RoleName)
</td>
<td>
#Html.ActionLink("Edit", "OpenEditRoleDialog", "RolePrivilegeMapping", new { id = item.RoleId }, new { #class = "editRoleDialog actionHyperLink" }) |
#Html.ActionLink("Delete", "DeleteRole", "RolePrivilegeMapping", new { id = item.RoleId }, new { #class = "confirmDialog actionHyperLink" })
</td>
</tr>
}
</table>
<div id="dialog-edit" style="display: none">
</div>
</div>
My edit role partial page is
#model sample.Models.webpages_Roles
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/jqueryval")
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/jqueryUI")
<script type="text/javascript">
$.validator.unobtrusive.parse(document);
function roleEditSuccess() {
// $("#dialog-edit").dialog('close');
}
</script>
#using (Ajax.BeginForm("EditRole", "RolePrivilegeMapping",
new AjaxOptions { HttpMethod = "POST",UpdateTargetId="roleWrapper",OnSuccess="roleEditSuccess" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>webpages_Roles</legend>
#Html.HiddenFor(model => model.RoleId)
<div class="editor-label">
#Html.LabelFor(model => model.RoleName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.RoleName)
#Html.ValidationMessageFor(model => model.RoleName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
So the flow is like
Index is loaded with roles
Roles table is having edit action link
On clicking edit , jquery dialog box is opened and the edit page is shown
On saving the details are updated using ,
UpdateTargetId="roleWrapper"
Because the partial updating of role div, when the dialog box is closed i apply the jquery dialog plugin again, But the following error comes in
"Error: cannot call methods on dialog prior to initialization;
attempted to call method 'open' "
How to proceed here. Am in great problem.

Execute Script on Partial View

I have the following script in my Main View which works great to create cascading dropdownlists. However, I cannot get it to execute on the partial view after it is loaded. From what I have read online, it seems that I need some sort of Ajax call in the partial view (which I am completely clueless on how to write). Any Assistance would be greatly appreciated.
<script type="text/javascript">
$(function () {
$("#SelectedCollateralClass").change(function () {
var selectedItem = $(this).val();
var ddlTypes = $("#SelectedCollateralType");
var typesProgress = $("#types-loading-progress");
typesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetCollateralTypesByClass"))",
data: { "CollateralClassId": selectedItem },
success: function (data) {
ddlTypes.html('');
$.each(data, function (id, option) {
ddlTypes.append($('<option></option>').val(option.id).html(option.name));
});
typesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve types.');
typesProgress.hide();
}
});
});
});
</script>
My Main View is:
#model CollateralRowViewModel
<div class="APPLICATION">
#*#Html.Partial("_SideBarView.cshtml");
#Html.Partial("_CommentsView.cshtml");*#
<!-- Content ======================================================================================-->
<div class="container row">
#using (#Html.BeginForm())
{
<div class="col-xs-16">
<div class="hr">
<h3 class="inline-block"> Collateral</h3>
<a class="icon-add"></a>
</div>
<table class="dataentry">
<thead>
<tr>
<th>#Html.LabelFor(model => model.CollateralClass)</th>
<th>#Html.LabelFor(model => model.CollateralType)</th>
<th>#Html.LabelFor(model => model.Description)</th>
<th>#Html.LabelFor(model => model.MarketValue)</th>
<th>#Html.LabelFor(model => model.PriorLiens)</th>
<th>#Html.LabelFor(model => model.AdvanceRate)</th>
<th>#Html.Label("Grantor (if not Borrower)")</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span class="inputROW">
#Html.DropDownListFor(model => model.SelectedCollateralClass, Model.CollateralClass)
</span>
</td>
<td>
<span class="inputROW">
#Html.DropDownListFor(model=>model.SelectedCollateralType, Model.CollateralType)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model => model.Description)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model => model.MarketValue)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model => model.PriorLiens)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model => model.AdvanceRate)
</span>
</td>
<td>
<span class="inputROW Smargin_bottom">
#Html.TextBoxFor(model => model.GrantorFirstName)
</span>
<span class="inputROW">
#Html.TextBoxFor(model => model.GrantorMiddleName)
</span>
<span class="inputROW">
#Html.TextBoxFor(model => model.GrantorLastName)
</span>
</td>
<td class="minusRow">
<a class="btn btn-danger icon-subtract sm btn-xs" data-nodrag ng-click="remove(this)"></a>
</td>
</tr>
</tbody>
</table>
<div>
<input id="addBtn" type="button" value="Add New Collateral" />
</div>
</div>
}
</div> <!-- end container -->
<footer id="APPfooter">
<div class="pagination centerF">
<ul>
<li class="previous"></li>
<li class="next"></li>
</ul>
</div>
</footer>
</div><!-- end page content container-->
<script type="text/javascript" charset="utf-8">
$(function () {
$('.default').dropkick();
$( "#datepicker" ).datepicker();
});
</script>
<script>
$("#addBtn").on("click", function () {
$.get('#Url.Action("AddNewRow")', function (data) {
$("table").append(data);
});
});
</script>
<script type="text/javascript">
$(document).ready(
$(function () {
$("#SelectedCollateralClass").change(function () {
var selectedItem = $(this).val();
var ddlTypes = $("#SelectedCollateralType");
var typesProgress = $("#types-loading-progress");
typesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetCollateralTypesByClass"))",
data: { "CollateralClassId": selectedItem },
success: function (data) {
ddlTypes.html('');
$.each(data, function (id, option) {
ddlTypes.append($('<option></option>').val(option.id).html(option.name));
});
typesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve types.');
typesProgress.hide();
}
});
});
}));
</script>
My partial looks like:
#model CollateralRowViewModel
<tr>
<td>
<span class="inputROW">
#Html.DropDownListFor(model=>model.SelectedCollateralClass, Model.CollateralClass)
</span>
</td>
<td>
<span class="inputROW">
#Html.DropDownListFor(model=>model.SelectedCollateralType, Model.CollateralType)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model=>model.Description)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model=>model.MarketValue)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model=>model.PriorLiens)
</span>
</td>
<td>
<span class="inputROW">
#Html.TextBoxFor(model=>model.AdvanceRate)
</span>
</td>
<td>
<span class="inputROW Smargin_bottom">
#Html.TextBoxFor(model=>model.GrantorFirstName)
</span>
<span class="inputROW">
#Html.TextBoxFor(model=>model.GrantorMiddleName)
</span>
<span class="inputROW">
#Html.TextBoxFor(model=>model.GrantorLastName)
</span>
</td>
<td class="minusRow">
<a class="btn btn-danger icon-subtract sm btn-xs" data-nodrag ng-click="remove(this)"></a>
</td>
</tr>
The Controller Action is:
[AcceptVerbs(HttpVerbs.Get)]
public async Task<ActionResult> GetCollateralTypesByClass(Guid collateralClassId)
{
var collateralServiceProxy = base.ServiceProvider.CollateralServiceProxy;
var collateralTypes = await collateralServiceProxy.GetCollateralTypesByCollateralClassIdAsync(collateralClassId);
var selectCollateraltypes = (from t in collateralTypes
select new
{
id = t.Id.ToString(),
name = t.Name
}).ToList();
return Json(selectCollateraltypes, JsonRequestBehavior.AllowGet);
}
The Partial is being called by a button "Add New" as follows:
<script>
$("#addBtn").on("click", function () {
$.get('#Url.Action("AddNewRow")', function (data) {
$("table").append(data);
});
});
</script>
The Controller for the button is :
[HttpGet]
[Route("CreateRow")]
public async Task<ActionResult> AddNewRow()
{
var collateralClasses = await GetCollateralClasses();
var collateralTypes = await GetCollateralTypes();
var model = new CollateralRowViewModel();
model.CollateralClass.Add(new SelectListItem { Text = "-Please Select-", Value = "-1" });
foreach (var _class in collateralClasses)
{
model.CollateralClass.Add(new SelectListItem()
{
Value = _class.Value.ToString(),
Text = _class.Text.ToString()
});
}
model.CollateralType.Add(new SelectListItem { Text = "-Please Select-", Value = "-1" });
foreach (var type in collateralTypes)
{
model.CollateralType.Add(new SelectListItem()
{
Value = type.Value.ToString(),
Text = type.Text.ToString()
});
}
return PartialView("_newCollateralRow", model);
}
I got the answer. All I needed to do was to add new{#class = "ddlClass'} and new {#class = "ddlType"} to the Partial. Then I just copied the script to the Partial and changed the references from referencing the Id to referencing the new classes as below:
<script type="text/javascript">
$(function () {
$(".ddlClass").change(function () {
var selectedItem = $(this).val();
var ddlTypes = $(".ddlType");
var typesProgress = $("#types-loading-progress");
typesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetCollateralTypesByClass"))",
data: { "CollateralClassId": selectedItem },
success: function (data) {
ddlTypes.html('');
$.each(data, function (id, option) {
ddlTypes.append($('<option></option>').val(option.id).html(option.name));
});
typesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve types.');
typesProgress.hide();
}
});
});
});
</script>
I hope this helps someone else!

Categories