我正在尝试使用Knockout JS创建一个主细节页面,如下图所示
我有一个问题是从详细信息中获取bootstrap模态的值。例如,在辅助客户端列单击“浏览”按钮后,将在引导模式中显示辅助客户端列表。
单击选择链接后,我无法将值(SubsidiaryClientID,SubsidiaryClientNo和Name)返回到父页面。如何获取这些值并设置为父页面?
以下是代码:
查看:Create.cshtml
<form action="~/Invoice/CreateKO" method="post">
<div class="form-horizontal">
<hr />
<div class="form-group">
<label class="control-label col-md-2">Office</label>
<div class="col-md-10">
<select name="OfficeID" id="OfficeID" class="form-control" data-bind="options: Offices, optionsText: 'Name', optionsValue: 'OfficeID', optionsCaption: '-- Please Select --', value: OfficeID"></select>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Client</label>
<div class="col-md-10">
<input type="hidden" name="ClientID" id="ClientID" data-val-required="The Client field is required."
data-val-number="The field Client must be a number." data-val="true" data-bind="value: ClientID" />
<div class="form-inline">
<input type="text" name="ClientName" id="ClientName" readonly="readonly" value="" class="form-control" style="width: 280px" />
<button type="button" class="btn btn-primary" data-bind="click: browseClient, enable: OfficeID()">...</button>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed">
<thead>
<tr>
<th></th>
<th>Subsidiary Client</th>
<th>Firm's Matter</th>
<th>eBilling Matter</th>
<th>Invoice No</th>
<th>Attachment</th>
</tr>
</thead>
<tbody data-bind="foreach: Invoices, visible: Invoices().length > 0">
<tr>
<td><a href="#" data-bind="click: $parent.removeInvoice">Remove</a></td>
<td>
<input type="hidden" data-bind="value: SubsidiaryClientID" />
<input type="text" class="form-control" data-bind="value: SubsidiaryClientNo" readonly="readonly" />
<input type="text" class="form-control" data-bind="value: SubsidiaryClientNo" readonly="readonly" />
<button type="button" class="btn btn-primary" data-bind="click: browseSubsidiaryClient">...</button>
</td>
<td>
<input type="text" class="form-control" data-bind="value: FirmMatterNo" readonly="readonly" />
<input type="text" class="form-control" data-bind="value: FirmMatterDescription" readonly="readonly" />
<input type="text" class="form-control" data-bind="value: FirmMatterLocation" readonly="readonly" />
<input type="text" class="form-control" data-bind="value: LocationDescription" readonly="readonly" />
<button type="button" class="btn btn-primary" data-bind="click: browseFirmMatter">...</button>
</td>
<td>
<input type="hidden" data-bind="value: ClientMatterID" />
<input type="text" class="form-control" data-bind="value: ClientMatterNo" readonly="readonly" />
<input type="text" class="form-control" data-bind="value: ClientMatterDescription" readonly="readonly" />
<button type="button" class="btn btn-primary" data-bind="click: browseClientMatter">...</button>
</td>
<td>
<input type="text" class="form-control" data-bind="value: InvoiceNo" />
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<a href="#" data-bind="click: addInvoice">Add Row..</a>
<br />
<br />
<div class="form-group">
<div class="col-md-12">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
</div>
</form>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<!-- Client Modal -->
@{ Html.RenderPartial("~/Views/Client/_Modal.cshtml"); }
<!-- SubsidiaryClient Modal -->
@{ Html.RenderPartial("~/Views/SubsidiaryClient/_Modal.cshtml"); }
<!-- LookupFirmMatter Modal -->
@{ Html.RenderPartial("~/Views/LookupFirmMatter/_Modal.cshtml"); }
<!-- ClientMatter Modal -->
@{ Html.RenderPartial("~/Views/ClientMatter/_Modal.cshtml"); }
@section Scripts {
@Scripts.Render("~/bundles/knockout")
<script>
function Invoice() {
var self = this;
self.SubsidiaryClientID = ko.observable();
self.SubsidiaryClientNo = ko.observable();
self.SubsidiaryClientName = ko.observable();
self.FirmMatterNo = ko.observable();
self.FirmMatterDescription = ko.observable();
self.FirmMatterLocation = ko.observable();
self.LocationDescription = ko.observable();
self.ClientMatterID = ko.observable();
self.ClientMatterNo = ko.observable();
self.ClientMatterDescription = ko.observable();
self.InvoiceNo = ko.observable();
self.browseSubsidiaryClient = function () {
if ($("#ClientID").val() == "0") {
alert("Please select client");
$("#btnLookupClient").focus();
return false;
}
$.ajax({
type: "GET",
url: '@Url.Content("~/SubsidiaryClient/Lookup?officeID=")' + $("#OfficeID").val() + '&clientID=' + $("#ClientID").val(),
cache: false
}).done(function (data) {
if (!data.message) {
$("#lookup-subsidiaryclient-container").html(data);
$("#subsidiaryClientModal").modal({ show: true, backdrop: true });
} else {
$("#subsidiaryClientModal").modal("hide");
alert(data.message);
}
});
};
self.browseFirmMatter = function () {
};
self.browseClientMatter = function () {
};
}
function InvoiceCreateViewModel() {
var self = this;
// Non-editable data
self.Offices = ko.observableArray();
// Editable data
self.OfficeID = ko.observable();
self.ClientID = ko.observable(0);
self.Invoices = ko.observableArray([]);
// Operations
self.browseClient = function () {
$.ajax({
type: "GET",
url: '@Url.Content("~/Client/LookupHasEBilling?c_officeID=")' + $("#OfficeID").val(),
cache: false
}).done(function (data) {
if (!data.message) {
$("#lookup-client-container").html(data);
$("#clientModal").modal({ show: true, backdrop: true });
} else {
$("#clientModal").modal("hide");
alert(data.message);
}
});
}
self.addInvoice = function () {
self.Invoices.push(new Invoice());
};
self.removeInvoice = function (invoice) {
self.Invoices.remove(invoice);
}
}
$(document).ready(function () {
var invoiceCreateViewModel = new InvoiceCreateViewModel();
$.getJSON("@Url.Content("~/Office/GetOffices")", null, function (data) {
invoiceCreateViewModel.Offices(data);
});
ko.applyBindings(invoiceCreateViewModel);
$("#subsidiaryClientModal").on("click", "#btnSubmitSubsidiaryClient", function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "@Url.Content("~/SubsidiaryClient/Lookup")",
data: {
officeID: $("#OfficeID").val(),
clientID: $("#ClientID").val(),
filterField: $("#SubsidiaryClientFilterField").val(),
filterOperator: $("#SubsidiaryClientFilterOperator").val(),
filterValue: $("#SubsidiaryClientFilterValue").val()
},
cache: false
}).done(function (data) {
$("#lookup-subsidiaryclient-container").html(data);
});
});
});
function setClient(clientID, name) {
document.getElementById("ClientID").value = clientID;
document.getElementById("ClientName").value = name;
$("#clientModal").modal("hide");
}
function setSubsidiaryClient(subsidiaryClientID, subsidiaryClientNo, name) {
document.getElementById("SubsidiaryClientID").value = subsidiaryClientID;
document.getElementById("SubsidiaryClientNo").value = subsidiaryClientNo;
document.getElementById("SubsidiaryClientName").value = name;
$("#subsidiaryClientModal").modal("hide");
}
</script>
}
查看:_Modal.cshtml(SubsidiaryClient&#39;模式)
<div class="modal fade" id="subsidiaryClientModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Lookup Subsidiary Client</h4>
@using (Html.BeginForm())
{
<div class="form-inline">
<div class="form-group">
@Html.DropDownList("SubsidiaryClientFilterField",
new List<SelectListItem>
{
new SelectListItem { Text = "Subsidiary Client No", Value = "SubsidiaryClientNo" },
new SelectListItem { Text = "Name", Value = "Name" }
},
new { @class = "form-control" })
</div>
<div class="form-group">
@Html.DropDownList("SubsidiaryClientFilterOperator",
new List<SelectListItem>
{
new SelectListItem { Text = "Contains", Value = "Contains" },
new SelectListItem { Text = "Does Not Contain", Value = "Does Not Contain" },
new SelectListItem { Text = "=", Value = "=" },
new SelectListItem { Text = "<>", Value = "<>" },
new SelectListItem { Text = ">", Value = ">" },
new SelectListItem { Text = "<", Value = "<" },
new SelectListItem { Text = ">=", Value = ">=" },
new SelectListItem { Text = "<=", Value = "<=" }
},
new { @class = "form-control" })
</div>
<div class="form-group">
@Html.TextBox("SubsidiaryClientFilterValue", null, new { @class = "form-control", @placeholder = "Enter keyword" })
</div>
<input type="submit" id="btnSubmitSubsidiaryClient" value="Search" class="btn btn-primary" />
</div>
}
</div>
<div class="modal-body" id="lookup-subsidiaryclient-container">
</div>
</div>
</div>
</div>
控制器:
public ActionResult Lookup(short officeID, int clientID, string filterField, string filterOperator, string filterValue, int? page)
{
var subsidiaryClients = db.SubsidiaryClients.Where(sc => sc.OfficeID == officeID && sc.ClientID == clientID);
if (!string.IsNullOrEmpty(filterValue))
{
if ("Contains".Equals(filterOperator))
{
subsidiaryClients = subsidiaryClients.Where(filterField + ".Contains(@0)", filterValue);
}
else if ("Does Not Contain".Equals(filterOperator))
{
subsidiaryClients = subsidiaryClients.Where("!" + filterField + ".Contains(@0)", filterValue);
}
else
{
subsidiaryClients = subsidiaryClients.Where(filterField + " " + filterOperator + " @0", filterValue);
}
}
subsidiaryClients = subsidiaryClients.OrderBy(sc => sc.Name);
ViewBag.officeID = officeID;
ViewBag.clientID = clientID;
ViewBag.filterField = filterField;
ViewBag.filterOperator = filterOperator;
ViewBag.filterValue = filterValue;
var pagedSubsidiaryClients = subsidiaryClients.ToPagedList(page ?? 1, Global.RowsPerPage);
var subsidiaryClientsVM = Mapper.Map<IEnumerable<SubsidiaryClient>, IEnumerable<SubsidiaryClientViewModel>>(pagedSubsidiaryClients.ToArray());
var pagedSubsidiaryClientsVM = new StaticPagedList<SubsidiaryClientViewModel>(subsidiaryClientsVM, pagedSubsidiaryClients.GetMetaData());
return PartialView("_Lookup", pagedSubsidiaryClientsVM);
}
部分视图显示SubsidiaryClient的数据:
<table class="table table-striped table-hover table-condensed">
<tr>
<th></th>
<th>Subsidiary Client No</th>
<th>Name</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td><a href="javascript:setSubsidiaryClient('@item.SubsidiaryClientID', '@item.SubsidiaryClientNo', '@item.Name.Replace("'", "\\'")')" class="glyphicon glyphicon-ok-sign"></a></td>
<td>@Html.DisplayFor(modelItem => item.SubsidiaryClientNo)</td>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
</tr>
}
</table>
答案 0 :(得分:1)
抱歉Willy,我已经在asp .net上工作了,所以我只提供了一个敲门和html的示例代码。希望这可以帮助你
<强> HTML 强>
// Parent Page Code
<!-- ko foreach: ClientList -->
<!-- ko if: isActive -->
<div class="col-xs-12">
<div class="col-xs-4" data-bind="text: SubsidiaryClientID"></div>
<div class="col-xs-4" data-bind="text: SubsidiaryClientNo"></div>
<div class="col-xs-4" data-bind="text: SubsidiaryClientName"></div>
</div>
<!-- ko -->
<!-- /ko -->
// Modal Box List
<!-- ko foreach: ClientList -->
<div class="col-xs-12" data-bind="click: $parent.Add">
<div class="col-xs-4" data-bind="text: SubsidiaryClientID"></div>
<div class="col-xs-4" data-bind="text: SubsidiaryClientNo"></div>
<div class="col-xs-4" data-bind="text: SubsidiaryClientName"></div>
</div>
<!-- /ko -->
<强>敲除强>
// Child view-model for Client List
SubsidiaryClientVM = function(){
this.SubsidiaryClientID = ko.observable();
this.SubsidiaryClientNo = ko.observable();
this.SubsidiaryClientName = ko.observable();
this.isActive = ko.observable(false);
}
// Parent view model
vm = function(){
var self = this;
this.ClientList = ko.observableArray();
// fill the array on search etc...
this.onSearch = function(){
self.ClientList(jQuery.map(data.Clients, function (item) {
return new SubsidiaryClientVM(item);
}));
}
this.Add = function(item){
ko.utils.arrayForEach(self.ClientList, function(list){
if(list.SubsidiaryClientID == item.SubsidiaryClientID){
list.isActive(!list.isActive());
}
});
}
}
答案 1 :(得分:0)
您可以在每一行定义自己的属性,并将该ro分配给js函数。
像这样:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cs1="https://defaultnamespace/abc" xmlns:cs2="https://defaultnamespace1/abc" exclude-result-prefixes="cs1 cs2">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="cs1:Report">
<xsl:for-each select="cs1:Conversion/cs1:Type">
<xsl:element name="Converting">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<xsl:element name="LastOne">
<xsl:value-of select="cs1:Last"/>
</xsl:element>
</xsl:template>
<xsl:template match="cs2:Report">
<xsl:for-each select="cs2:Conversion/cs2:Type">
<xsl:element name="Converting">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
<xsl:element name="LastOne">
<xsl:value-of select="cs2:Last"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>