我有一个控制器,我在
里面创建了两个action-results public ActionResult ProductSearch(string term)
{
// Get Products from database
InvoiceDBEntities db = new InvoiceDBEntities();
var myproducts = (from E in db.Products
orderby E.Product ascending
select E.Product.Trim());
return this.Json(myproducts.Where(t => t.Contains(term)), JsonRequestBehavior.AllowGet);
}
public ActionResult DetailsFetch(string term)
{
InvoiceDBEntities db = new InvoiceDBEntities();
var mydetails = (from E in db.Products
orderby E.Product ascending
select new
{
Product = E.Product.Trim(),
Price = E.Price.ToString(),
UM = E.UM
}).ToArray();
return this.Json(mydetails.Where(t => t.Product.Contains(term)), JsonRequestBehavior.AllowGet);
}
和相应的脚本
//auto complete products
$('#itemName').autocomplete(
{
source: '/Invoices/ProductSearch'
});
//prefill some inputs
$("#UM").focus(function () {
var MySelection = $("#itemName").val().trim();
$.ajax({
type: "POST",
data: { term: MySelection },
url: "/Invoices/DetailsFetch/",
dataType: "json",
succes: function (data) {
$("#UM").val(data.UM);
$("#rate").val(data.Price);
},
error: function () {
//Manage errors if any
}
});
});
$("#itemName").blur(function () {
var MySelection = $("#itemName").val().trim();
$.ajax({
type: "POST",
data: { term: MySelection },
url: "/Invoices/DetailsFetch/",
dataType: "json",
succes: function (data) {
$("#UM").val(data.UM);
$("#rate").val(data.Price);
},
error: function () {
//Manage errors if any
}
});
});
//
第一部分(自动完成)工作良好。现在我希望在我的表单(或任何其他合适的事件)中输入下一个输入时执行下一个操作-结果并使用我获得的数据预先填充表单中的相关输入。我可以在浏览器中看到结果,所以操作-结果工作得很好,但没有更新任何相关输入。当我输入下一个输入(通过鼠标单击或键盘[tab])时,我在浏览器中看到的响应是:
[{"Product":"Serviciu de dezvoltare aplicatie WEB","Price":"1000.00","UM":"Buc."}]
我在应用程序的另一部分中使用了类似的概念,唯一的区别是事件是单击按钮,并且所有工作正常,相关输入预先填充了来自json响应的数据。
我能做错什么?
响应看起来像一个只有一项的数组。因此,获取第一项并使用属性值
success: function (data) {
if(data.length)
{
var item =data[0]; //Get first item in the array
$("#UM").val(item .UM);
$("#rate").val(item .Price);
}
},
但是你的数组可能有多个项目,因为你正在做Contains
方法调用来获取项目的子集。但是,如果您对获取单个项目的详细信息感兴趣,我建议您将唯一id (ProductId
?)传递给服务器,并获得与该id匹配的一条记录。你将返回一个对象而不是一个数组。在这种情况下,你可以使用原来的代码。如果传递的术语是集合的子字符串,
Contains方法将返回true。例如,如果您有一个名称为"MotorCar"的产品和另一个名称为"Car"的产品,当您发送"Car"作为术语值时,您的where条件将返回这两个记录。因此,您可能不想使用Contains
方法。
假设你的ProductName是唯一的,你可以直接检查ProductName是否与你发送的术语完全匹配。
public ActionResult DetailsFetch(string term)
{
var db = new InvoiceDBEntities();
var item = (from E in db.Products
orderby E.Product ascending
where E.Product
.Equals(term,StringComparison.CurrentCultureIgnoreCase)
select new
{
Product = E.Product.Trim(),
Price = E.Price.ToString(),
UM = E.UM
}).FirstOrDefault();
if(item!=null)
{
return Json(new {status="success",details= item }, JsonRequestBehavior.AllowGet);
}
return Json(new {status="error"}, JsonRequestBehavior.AllowGet);
}
现在,在您的成功事件处理程序中,您只需要检查响应json并根据需要使用详细信息
success: function (data) {
if(data.status===="success")
{
$("#UM").val(data.details.UM);
$("#rate").val(data.details.Price);
}
},
您也不需要收听其他文本框上的模糊/焦点事件,您可以使用自动完成的select
事件,使您的第二个ajax调用获得详细信息。
select: function (event, ui) {
var term = ui.item.label;
// make the call here
}
看一下如何在ASP中选择自动完成文本字段值时进行另一个ajax调用。Net MVC 4?查看详细的示例代码