我正在尝试创建一个用户可以添加多个产品的页面,每个产品可以有多个竞争对手。竞争对手的作品需要使用tagit生成。由于某种原因,tagit无法正常工作...... 这是淘汰赛模板:
<script type="text/html" id="product-template">
<tr>
<td style="width: 5%">
<input type="hidden" name="Products.Index" data-bind="value: Id"/>
</td>
<td style="width: 30%">
Product:<br/>
<select data-bind='options: ProductSource, optionsText: "Product", optionsCaption: "", value: Product, attr: { name: "Products[" + Id + "].Product" }'></select>
</td>
<td style="width: 30%; line-height: 100%; margin-top: 0; padding-top: 0">
Competitors:<br/>
<div id="tags_error" style="display: none;" class="ui-state-error-text">entries must be less than 50 characters each</div>
<ul class="tags" style="margin-top: 2px; padding-top: 0" data-bind="foreach: Competitors">
<li data-bind="text: $data" >
</li >
</ul>
<div style="font-size: 10px; color: GrayText; font-style: italic;">please separate tags using the comma or enter key</div>
@* <input type="text" value="" data-bind='attr: { name: "Products[" + $parent.Id + "].Competitors" }' />*@
</td>
<td style="width: 30%">
Positioning:<br/>
<select data-bind='options: PositioningSource, optionsText: "Positioning", optionsCaption: "", value:Positioning, attr: { name: "Products[" + Id + "].Positioning" }'></select>
</td>
<td style="width: 5%">
<a href="#" data-bind="click: $parent.removeProduct">
<img src="@Links.Content.Images.DeleteAlert_gif"/>
</a>
</td>
</tr>
这是我的淘汰模型视图:
$(document).ready(function () {
function ProductItem(id, product, positioning, competitors) {
var self = this;
self.Id = id;
self.Product = ko.observable(product);
self.Positioning = ko.observable(positioning);
self.Competitors = ko.observableArray(competitors);
self.Competitors.push( '1', '2', '3' );
self.errors = ko.validation.group(self);
}
function ProductsViewModel() {
var self = this;
var id = 0;
self.Products = [];
self.Products = ko.observableArray();
@if (Model.Products != null)
{
foreach (var item in Model.Products)
{
<text>self.Products.push(new ProductItem(id++, '@item.Product', '@item.Positioning', '@item.Competitors'));</text>
}
}
self.selectedProduct = ko.observable();
self.addProduct = function () {
self.Products.push(new ProductItem(id++));
};
self.removeProduct = function (product) {
self.Products.remove(product);
};
}
ko.validation.init({ insertMessages: true, decorateElement: true, errorClass: "error" });
ko.applyBindingsWithValidation(new ProductsViewModel());
});
这是标签设置:
$(function () {
var changed = function (e1, e2) {
var item = $(e2);
if (item.find('input').val().length > 50) {
setTimeout(function () { item.remove(); }, 50);
$('#tags_error').show();
setTimeout(function () { $('#tags_error').fadeOut(1000); }, 10000);
} else {
$('.tags, .tags input').addClass('ui-state-highlight');
}
};
$('.tags').tagit({
tagSource: '@Html.Raw(Url.Action(MVC.Marketing.Campaign.SearchTags()))',
removeConfirmation: true,
allowSpaces: true,
caseSensitive: false,
onTagAdded: changed,
onTagRemoved: changed,
placeholderText: 'enter a tag'
});
});
添加产品效果很好,只是竞争对手显示为列表而不是输入,我可以添加标签......
答案 0 :(得分:0)
解决方案。模板:
<script type="text/html" id="product-template">
<tr>
<td style="width: 5%">
<input type="hidden" name="Products.Index" data-bind="value: Id"/>
</td>
<td style="width: 30%">
Product:<br/>
<select data-bind='options: ProductSource, optionsText: "Product", optionsCaption: "", value:Product'></select>
<input data-bind='attr: { name: "Products[" + Id + "].Product", value: (Product() !== undefined) ? Product().Product : "" }' type="hidden" value="">
</td>
<td style="width: 30%; line-height: 100%; margin-top: 0; padding-top: 0">
Competitors:<br/>
<ul style="margin-top: 2px; padding-top: 0" data-bind="tagit:Competitors, productId:$data.Id"></ul>
<div style="font-size: 10px; color: GrayText; font-style: italic;">please separate competitors using the comma or enter key</div>
</td>
<td style="width: 30%">
Positioning:<br/>
<select data-bind='options: PositioningSource, optionsText: "Positioning", optionsCaption: "", value:Positioning'></select>
<input data-bind='attr: { name: "Products[" + Id + "].Positioning", value: (Positioning() !== undefined) ? Positioning().Positioning : "" }' type="hidden" value="">
</td>
<td style="width: 5%">
<a href="#" data-bind="click: $parent.removeProduct">
<img src="@Links.Content.Images.DeleteAlert_gif"/>
</a>
</td>
</tr>
淘汰赛模特:
<script type="text/javascript">
var ProductSource = [];
var index = 0;
$.ajax({
type: "GET",
url: '@Html.Raw(Url.Action(MVC.UserChoice.ForName()))',
data: { userChoiceName: '@UserChoiceKey.OpportunityProductInterest' },
cache: false,
success: function (data) {
data.forEach(function (item)
{ ProductSource.push({ Product: item.Text }); });
}
});
var PositioningSource = [];
var index = 0;
$.ajax({
type: "GET",
url: '@Html.Raw(Url.Action(MVC.UserChoice.ForName()))',
data: { userChoiceName: '@UserChoiceKey.WorkRequestProductPositioning' },
cache: false,
success: function (data) {
data.forEach(function (item)
{ PositioningSource.push({ Positioning: item.Text }); });
}
});
$(document).ready(function () {
function ProductItem(id, product, positioning, competitors) {
var self = this;
self.Id = id;
self.Product = ko.observable(product);
self.Positioning = ko.observable(positioning);
self.Competitors = ko.observableArray(competitors);
self.errors = ko.validation.group(self);
}
function ProductsViewModel() {
var self = this;
var id = 0;
self.Products = [];
self.Products = ko.observableArray();
@if (Model.Products != null)
{
foreach (var item in Model.Products)
{
<text>self.Products.push(new ProductItem(id++, '@item.Product', '@item.Positioning', '@item.Competitors'));</text>
}
}
self.selectedProduct = ko.observable();
self.addProduct = function () {
self.Products.push(new ProductItem(id++));
};
self.removeProduct = function (product) {
self.Products.remove(product);
};
}
ko.bindingHandlers.tagit = {
//https://github.com/aehlke/tag-it
init: function (element, valueAccessor, allBindingsAccessor) {
var options = {
allowSpaces: true,
caseSensitive: false,
showAutocompleteOnFocus: true,
tagSource: '@Html.Raw(Url.Action(MVC.Marketing.Campaign.SearchTags()))',
itemName: "Products[" + allBindingsAccessor.get('productId') + "].Competitors",
fieldName:""
};
var tags = allBindingsAccessor()["tagsSource"];
if (tags)
$.extend(options, {
autocomplete: { source: tags, delay: 0, minLength: 0 }
});
$(element).tagit(options);
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value;
$(element).tagit("removeAll");
for (var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
}
};
ko.validation.init({ insertMessages: true, decorateElement: true, errorClass: "error" });
ko.applyBindingsWithValidation(new ProductsViewModel());
});