I need to search on the database, and load only the View, and not refresh the entire page. A function in Js calls my method on the controller, when clicking on search, and the controller returns the View.
function Pesquisa()
{
let campo = document.getElementsByName("campo");
let pesquisa = document.getElementsByName("EdtPesquisa");
let condicao = document.getElementsByName("pesquisa");
let scampo = Array();
let spesquisa = Array();
let scondicao = Array();
let sNomeGrid = ($(this).find("a").text());
for (var indice = 0; indice < pesquisa.length; indice++)
{
string = pesquisa[indice].value;
if (string.trim() != "")
{
scampo[indice] = campo[indice].id;
scondicao[indice] = condicao[indice].value;
spesquisa[indice] = pesquisa[indice].value;
}
}
window.location.href = "/MenuPrincipal/RetornarView?sNomeGrid=" + "Unidade" + "&listacampo=" + scampo + "&listacondicao=" + scondicao + "&listapesquisa=" + spesquisa;
Controller
public IActionResult RetornarView(string sNomeGrid, List<string> listacampo, List<string> listacondicao, List<string> listapesquisa)
{
var sWhere = "";
if (listacampo.Count > 0)
{
Pesquisa _Pesquisa = new Pesquisa();
sWhere = _Pesquisa.Pesquisar(listacampo, listacondicao, listapesquisa);
}
if (sNomeGrid == "Unidade")
{
var listaunidade = _UnidadeRepositorio.ListarMenu(sWhere);
return View("Unidade", listaunidade);
}
return View("MenuPrincipal");
}
View
#model IEnumerable<ApesWeb.Models.Classes.Unidade>
<div class="tabela-responsive">
<table id="tabela" class="tabela tabela-hover"
data-toggle="table">
<thead>
<tr>
<th id="idunidade" name="campo">#Html.DisplayNameFor(model => model.idunidade)</th>
<th id="sdescricao" name="campo">#Html.DisplayNameFor(model => model.sdescricao)</th>
<th id="sunidade" name="campo">#Html.DisplayNameFor(model => model.sunidade)</th>
<th id="sdigitavolume" name="campo">#Html.DisplayNameFor(model => model.sdigitavolume)</th>
<th id="spadraosistema" name="campo">#Html.DisplayNameFor(model => model.spadraosistema)</th>
</tr>
<tr>
<th>
<div class="inputWithIcon">
<select name="pesquisa" />
<input type="text" name="EdtPesquisa"/>
<i class="fa fa-search" aria-hidden="true" onclick="Pesquisa()"></i>
</div>
</th>
<th>
<div class="inputWithIcon">
<select name="pesquisa"/>
<input type="text" name="EdtPesquisa"/>
<i class="fa fa-search" aria-hidden="true" onclick="Pesquisa()"></i>
</div>
</th>
<th>
<div class="inputWithIcon">
<select name="pesquisa" />
<input type="text" name="EdtPesquisa"/>
<i class="fa fa-search" aria-hidden="true" onclick="Pesquisa()"></i>
</div>
</th>
<th>
<div class="inputWithIcon">
<select name="pesquisa" />
<input type="text" name="EdtPesquisa"/>
<i class="fa fa-search" aria-hidden="true" onclick="Pesquisa()"></i>
</div>
</th>
<th>
<div class="inputWithIcon">
<select name="pesquisa" />
<input type="text" name="EdtPesquisa"/>
<i class="fa fa-search" aria-hidden="true" onclick="Pesquisa()"></i>
</div>
</th>
</tr>
</thead>
<tbody>
#foreach (var Unidade in Model)
{
<tr>
<td>
#Html.DisplayFor(modelitem => Unidade.idunidade)
</td>
<td>
#Html.DisplayFor(modelitem => Unidade.sdescricao)
</td>
<td>
#Html.DisplayFor(modelitem => Unidade.sunidade)
</td>
<td>
#Html.DisplayFor(modelitem => Unidade.sdigitavolume)
</td>
<td>
#Html.DisplayFor(modelitem => Unidade.spadraosistema)
</td>
</tr>
}
</tbody>
</table>
Returns the View with the list to fill the Table, but in this process the entire page is refreshed.
You can use one of the following methods according to your needs:
Method I: If you want to use ViewData, try this:
#Html.Partial("~/PathToYourView.cshtml", null,
new ViewDataDictionary { { "VariableName", "some value" } })
And to retrieve the passed in values:
#{
string valuePassedIn = this.ViewData.ContainsKey("VariableName") ?
this.ViewData["VariableName"].ToString() : string.Empty;
}
Method II: If you just render a partial with just the partial name:
#Html.Partial("_SomePartial", Model)
Method II: Render PartialView using jQuery Ajax call:
Firstly wrap your body content in a div and assign any id to it in _Layout page:
<div id="div-page-content" class="page-content">
#RenderBody()
</div>
Here is the menu item used for rendering PartialView in _Layout page:
<ul class="sub-menu">
<li class="nav-item ">
<a href="#" onclick="renderPartial(event, 'Account', '_Register')" class="nav-link">
<span class="title">Create New User</span>
</a>
</li>
</ul>
Define the javascript function for click event in _Layout page:
function renderPartial(e, controller, action) {
e.preventDefault();
e.stopPropagation();
var controllerName = controller;
var actionName = action;
if (String(actionName).trim() == '') {
return false;
}
if (typeof (controllerName) == "undefined") {
return false;
}
var url = "/" + controllerName + "/" + actionName;
////Open url in new tab with ctrl key press
//if (e.ctrlKey) {
// window.open(url, '_blank');
// e.stopPropagation();
// return false;
//}
$.ajax({
url: url,
data: { /* additional parameters */ },
cache: false,
type: "POST",
dataType: "html",
success: function (data) {
var requestedUrl = String(this.url).replace(/[&?]X-Requested-With=XMLHttpRequest/i, "");
if (typeof (requestedUrl) == "undefined" || requestedUrl == 'undefined') {
requestedUrl = window.location.href;
}
// if the url is the same, replace the state
if (typeof (history.pushState) != "undefined") {
if (window.location.href == requestedUrl) {
history.replaceState({ html: '' }, document.title, requestedUrl);
}
else {
history.pushState({ html: '' }, document.title, requestedUrl);
}
}
$("#div-page-content").html(data);
},
error: function (data) { onError(data); }
});
};
Define your PartialView as shown below:
<div>
... partial view content goes here >
</div>
Add the Action metdod to the Controller as shown below:
[HttpPost]
[AllowAnonymous]
public PartialViewResult _Register(/* additional parameters */)
{
return PartialView();
}
Related
I'm working on ASP.NET Core web application where I have a table in my view that displays all requests. each record with drop-down populated with all analysts successfully from my database, So the manager can assign the analyst from drop-down then approve the request.
My questions:
Can I implement this using form for each record instead using JavaScript, I mean using only asp tags?
If that should done using JavaScript, Here is my attempt to implement this.
The following code is working only if the Analyst id is integer, but in my case the analyst id is string, so whenever I try to execute this, I got either "null" or "Zero" for the analyst id in the controller. Here is my ViewModel
public class RequestViewModel
{
public IEnumerable<Request> Requests { get; set; }
public IEnumerable<ApplicationUser> AnalystList { get; set; }
public Institution Institution { get; set; }
public string selectedAnalyst { get; set; }
}
Here is my controller
public async Task<IActionResult> ApproveRequest(int id, int Analystid)
{
Request Req = await _db.Request
.Include(c => c.Institution)
.FirstOrDefaultAsync(c => c.Id == id);
if (Req.Type == SD.TypeRegister)
{
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
Req.Institution.Seats = Req.Seats; // new
Req.Institution.AnalystId = Analystid.ToString(); //Here I want to get the id as string
}
else if (Req.Type == SD.TypeSeat)
{
Req.Institution.Seats += Req.Seats;
}
else if (Req.Type == SD.TypeSubscription)
{
Req.Institution.Seats = Req.Seats;
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
}
Req.isDone = true;
await _db.SaveChangesAsync();
return await CreateApproval(id, SD.StatusApproved);
}
Here is my View
#model TestApplication.Models.ViewModels.RequestViewModel
#using TestApplication.Extensions
#{
ViewData["Title"] = "Index";
}
<div class="tab-pane fade show active" id="Register" role="tabpanel" aria-labelledby="Register-tab">
Registration Requests
<div>
#if (Model.Requests.Count() > 0)
{
<table class="table table-striped">
<tr class="table-secondary">
<th>
Institution Name
</th>
<th>
Date
</th>
<th>
Actual seat
</th>
<th>
Seats
</th>
<th>
New Seat
</th>
<th>
Choose Analyst
</th>
<th>
Accept / Reject
</th>
<th>
Details
</th>
<th>
</th>
</tr>
#foreach (var item in Model.Requests)
{
#if (item.Type == "Register" && item.Institution.Status == "Pending") #*need one*#
{
<tr>
<td>
#Html.DisplayFor(m => item.Institution.Name)
</td>
<td>
#Html.DisplayFor(m => item.Date)
</td>
<td>
#Html.DisplayFor(m => item.Institution.Seats)
</td>
<td>
#Html.DisplayFor(m => item.ActualSeats)
</td>
<td>
#Html.DisplayFor(m => item.Seats)
</td>
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" asp-items=" Model.AnalystList.ToSelectListItem(Model.selectedAnalyst)" class="form-control">
<option selected value="">--- Choose ---</option>
</select>
</td>
<td>
<a class="btn btn-info" asp-controller="Request" asp-action="ApproveRequest" asp-route-id="#item.Id"> accept </a>
<a class="btn btn-info" asp-controller="Request" asp-action="RejectRequest" asp-route-id="#item.Id"> Reject </a>
</td>
<td>
<button type="submit" class="btn btn-success anchorDetail" data-target="#modal-#item.Institution.Id" data-toggle="modal">
View Details
</button>
</td>
<td>
<div class="modal fade" id="modal-#item.Institution.Id" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog-centered modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-success text-light justify-content-center">
<h5 class="modal-title">Request Details</h5>
</div>
<div class="modal-body justify-content-center" id="MyModalContent">
#await Html.PartialAsync("_RequestDetails", item)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">إغلاق</button>
</div>
</div>
</div>
</div>
</td>
</tr>
}
}
</table>
}
else
{
<p>No Institutions Exists...</p>
}
</div>
</div>
#section scripts
{
<script>
function accept(id) {
var aid = $('#selectedAnalyst_' + id).val()
location.href = "/Request/ApproveRequest?id=" + id + "&Analystid=" + aid
}
var PostBackURL = '/Request/RequestDetails';
$(function () {
$(".anchorDetail").click(function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
$.ajax({
type: "GET",
url: PostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
cache: false,
datatype: "json",
success: function (data) {
$('#MyModalContent').html(data);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
})
</script>
}
<div class="modal fade" id="MyModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div id='MyModalContent'></div>
</div>
If you want to pass #item.id and $('#selectedAnalyst_' + id).val() to controller with form,you can do like this.Here is a demo worked(put form outside dropdownlist and button):
<form method="post"
asp-controller="Request"
asp-action="ApproveRequest"
asp-route-id="#item.Id">
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" class="form-control">
<option selected value="">--- Choose ---</option>
<option selected value="1">1</option>
<option selected value="2">2</option>
<option selected value="3">3</option>
</select>
</td>
<td>
<button type="submit">Accept</button>
</td>
</form>
Controller(change Analystid to selectedAnalyst,so that you can bind asp-for="selectedAnalyst",and if you want to get string parameter,you can change it to string selectedAnalyst):
public IActionResult ApproveRequest(int id,string selectedAnalyst)
{
return Ok();
}
result:
So I'm trying to hide the Company Name <th> column when the employee drop down is selected.
I have this jQuery function that I've been trying to figure out for sometime now and cant seem to get it working. I've tried to walk though script with FF debugger but nothing happens, with no errors. Im kind of lost on where to take it from here.
DropDown
#using (Html.BeginForm())
{
#Html.DropDownList("SearchStatus", new SelectList(ViewBag.SearchStatusList, "Value", "Text", ViewBag.SelectedItem), new { #class = "form-control", #onchange = "form.submit();" })
}
jQuery
<script type="text/javascript">
$("#SearchStatus").on("change", function () {
if ($("#SearchStatus option:selected").val() == 0) {
$("#hidden_div").hide();
} else {
$("#hidden_div").show();
}
});
VIEW
#model PagedList.IPagedList<Login.Models.EditProfile>
#using PagedList.Mvc;
#{
ViewBag.Title = "Pending Accounts";
}
<link href="~/Content/PagedList.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.js"></script>
<style>
... deleted CSS that was here
</style>
<h2>Pending Accounts</h2>
#using (Html.BeginForm())
{
#Html.DropDownList("SearchStatus", new SelectList(ViewBag.SearchStatusList, "Value", "Text", ViewBag.SelectedItem), new { #class = "form-control", #onchange = "form.submit();" })
}
<br />
<table class="table grid">
<tr>
<th>
<b>Options</b>
</th>
<th>
First Name:
</th>
<th>
Last Name:
</th>
<th>
Email:
</th>
<th>
Phone Number:
</th>
<th id="hidden_div" style="display: none;">
Company Name:
</th>
<th></th>
</tr>
#foreach (var item in Model.ToList())
{
<tr>
<td>
<div class="btn-group">
<button type="button" id="bootstrap-ok" class="btn btn-default btn-sm icon-success">
<span class="glyphicon glyphicon-ok "></span>
</button>
<button type="button" id="bootstrap-danger" class="btn btn-default btn-sm icon-danger">
<span class="glyphicon glyphicon-remove "></span>
</button>
</div>
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.EmailAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.PhoneNumber)
</td>
#if (item.CompanyName != null)
{
<td>
#Html.DisplayFor(ModelItem => item.CompanyName)
</td>
}
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("PendingAccounts", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
#if (Request.IsAuthenticated)
{
using (Html.BeginForm("Logout", "User", FormMethod.Post, new { id = "logoutForm" }))
{
Logout
}
}
<script type="text/javascript">
$("#SearchStatus").on("change", function () {
if ($("#SearchStatus option:selected").val() == 0) {
$("#hidden_div").hide();
} else {
$("#hidden_div").show();
}
});
you can get the value of the dropdown by using $(yourDropdown).val() and not selecting the options. So try this:
$("#SearchStatus").on("change", function () {
if ($("#SearchStatus").val() == 0) {
$("#hidden_div").hide();
} else {
$("#hidden_div").show();
}
});
I have a local amp setup where I am trying to push angular $log messages to a txt file. But I keep getting a javaScript error. Here is the error
angular.js:9101 TypeError: $scope.todos.push is not a function
Here is my code:
angular.module('Todo', []).factory('myhttpserv', function($http) {
return $http.get('storage.txt').error(function(status) {
console.log(status)
});
}).controller('TodoController', function($scope, myhttpserv, $http) {
$scope.appTitle = "MyTodoList",
myhttpserv.then(function(response) {
$scope.todos = (response.data !== null) ? response.data : [];
var httpPost = function() {
$http.post('save.php', JSON.stringify($scope.todos)).error(function(status) {
console.log(status)
});
};
$scope.addTodo = function() {
$scope.todos.push({
text: $scope.todoText,
doneProd: false,
doneDev: false
});
$scope.todoText = ''; //clear the input after adding
httpPost();
};
$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo) {
count += todo.doneProd && todo.doneDev ? 0 : 1;
});
return count;
};
$scope.archive = function() {
var rusure = confirm("Are you sure you want to remove the completed tasks from the list?");
if (rusure) {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo) {
if (!todo.doneProd || !todo.doneDev)
$scope.todos.push(todo);
});
httpPost();
}
};
$scope.delete = function(idx) {
var rusure = confirm("Are you sure you want to remove the task from the list?");
if (rusure) {
$scope.todos.splice(idx, 1);
httpPost();
}
};
$scope.edit = function(idx) {
var changes = prompt("Please make the changes below", $scope.todos[idx].text);
if (changes != null) {
$scope.todos[idx].text = changes;
httpPost();
}
};
$scope.checkboxClick = function() {
httpPost();
};
$('.splash, .container').fadeToggle();
});
});
<div class="splash">
<h2>Loading</h2>
</div>
<div class="container">
<header class="app-header">
<h1 class="app-title" data-ng-bind="appTitle"></h1>
</header>
<section class="app-body">
<table>
<thead>
<tr>
<th>
TITLE
</th>
<th></th>
<th></th>
<th class="chk">
PROD
</th>
<th class="chk">
DEV
</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="todo in todos track by $index">
<td>
<span class="done-{{ todo.doneProd && todo.doneDev }}" data-ng-bind="todo.text"></span>
</td>
<td>
<a data-ng-click="delete($index)"><i class="fa fa-times"></i></a>
</td>
<td>
<a data-ng-click="edit($index)"><i class="fa fa-pencil-square-o"></i></a>
</td>
<td class="chk">
<input type="checkbox" data-ng-model="todo.doneProd" data-ng-change="checkboxClick()">
</td>
<td class="chk">
<input type="checkbox" data-ng-model="todo.doneDev" data-ng-change="checkboxClick()">
</td>
</tr>
</tbody>
</table>
<section class="archive-control">
<span>{{ remaining() }} of {{ todos.length }} remaining</span>
<a class="fr" href="" data-ng-click="archive()" data-ng-show="remaining() < todos.length">Remove Completed Items</a>
</section>
<form data-ng-submit="addTodo()" class="todo-form">
<input type="text" data-ng-model="todoText" placeholder="Enter new task item" />
<br />
<input type="submit" value="Add Task" />
</form>
</section>
</div>
here is my php file and I do have my storage.txt in the folder also:
<?php
$data = file_get_contents("php://input");
$myfile = fopen("log.txt", "w") or die("Unable to open file!");
fwrite($myfile, $data);
fclose($myfile);
?>
$scope.fetchStatus = function (job) {
$http
.get('http://gtrapi/pool/checkStatus/' + sessionId + '/' + job.jobId)
.success(function (response) {
job[job.jobId] = response;
if (response.status !== 'InProgress') {
$scope.refreshDataTimeout = $timeout($scope.fetchStatus(job), 1000);
}
})
.error (function () {
});
};
Here is my HTML code
<div ng-repeat="job in gtrLogs" class="each-log">
<div class="row job-id">
<div class="col-xs-2">
Job ID: {{job.jobId}}
</div>
<div class="col-xs-10">
End Point: {{job.changes.endpoint}}
</div>
</div>
<div class="each-job" ng-init="fetchStatus(job)">
<div class="job-header row">
<span class="col-xs-6">Job Status: <strong>{{job[job.jobId].status}}</strong>
<span class="glyphicon" ng-class="{'glyphicon-refresh spin' : job[job.jobId].status === 'InProgress', 'glyphicon-ok' : job[job.jobId].status === 'submitted', 'glyphicon-remove' : job[job.jobId].status === 'Aborted'}"></span>
</span>
<span class="col-xs-6">
<span class="glyphicon glyphicon-stop pull-right" ng-click="stopLogs()" tooltip="Stop Action"></span>
<span class="glyphicon glyphicon-repeat pull-right" ng-click="rollBack()" tooltip="Roll Back"></span>
</span>
</div>
<div class="logs-progress">
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th>
Message
</th>
<th>
Time
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in job[job.jobId].logs">
<td>{{row.msg}}</td>
<td>{{row.time | date:'yyyy/MM/dd HH:mm:ss'}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
I have to update the data every second and placed $timeout in the function. But because the function is being called multiple times from the HTML the calls are nested.
How Do I keep polling with respect to the same job.
Since you have a unique jobid, use can use that to maintain an array of key value pairs where your job id can correspond to a unique counter.
var counters = [];
$scope.fetchStatus = function (job) {
$http
.get('http://url:9090/gtrapi/pool/checkStatus/' + sessionId + '/' + job.jobId)
.success(function (response) {
job[job.jobId] = response;
if (response.status !== 'InProgress') {
updateCounter(job.jobId);
$scope.refreshDataTimeout = $timeout($scope.fetchStatus(job), 1000);
}
})
.error (function () {
});
};
function updateCounter(jobId) {
var exists = false,
jobId = parseInt(jobId);
for (var i in counters) {
if (counters[i].id === jobId) {
projects[i].counter++;
exists = true;
break;
}
}
if (!exists) {
counters.push({id: jobId, counter: 0});
}
}
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!