这是我的第一个模板:
<script type="text/html" id="Testing">
<!-- ko if: $data.CLASSIFICATION_NAME().toLowerCase() == 'general' -->
<!-- ko if: $data.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.NumberRange -->
<li>
<div class="divFilterRow">
<div class="divFilterCol">
<input type="checkbox" data-bind="checked: ISATTRIBUTESELECTED, attr:{'id': ATTRIBUTE_NAME}, click: function(){checkedCallback($data); return true; }" />
</div>
<div class="divFilterCol divFilterCph">
<label data-bind=" text: ATTRIBUTE_NAME, attr:{'for': ATTRIBUTE_NAME,'attributetooltip': ATTRIBUTE_DESCRIPTION}"></label>
<a class="iClose" href="javascript:void(0);" data-bind=" click: $data.removeSelectedAttribute , style: {display: ISATTRIBUTESELECTED() ? 'block' : 'none'}"></a>
</div>
</div>
<div class="iClearBoth" />
<div data-bind=" visible: ISATTRIBUTESELECTED">
<div data-bind=" template: {name: 'sliderTemplate',foreach: filterSliderValues} "></div>
</div>
</li>
<!-- /ko -->
<!-- ko if: $data.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.MultipleChoiceList -->
<li>
<div class="divFilterRow">
<div class="divFilterCol">
<input type="checkbox" data-bind="checked: ISATTRIBUTESELECTED, attr:{'id': ATTRIBUTE_NAME}, click: function(){checkedCallback($data); return true; }" />
</div>
<div class="divFilterCol divFilterCph">
<label data-bind="text: ATTRIBUTE_NAME, attr:{'for': ATTRIBUTE_NAME,'attributetooltip': ATTRIBUTE_DESCRIPTION }"></label>
<a class="iClose" href="javascript:void(0);" data-bind="click: $data.removeSelectedAttribute , style: {display: ISATTRIBUTESELECTED() ? 'block' : 'none'}"></a>
</div>
</div>
<div class="iClearBoth" />
<div data-bind="visible: ISATTRIBUTESELECTED">
<div data-bind=" template: {name: 'sliderTemplate',foreach: filterSliderValues} "></div>
</div>
<div data-bind="visible: ISATTRIBUTESELECTED">
<div data-bind="dialog: {'autoOpen': false, 'title': ATTRIBUTE_NAME,'modal': true,
'resizable': false, width: 950, draggable: false, closeOnEscape: false
@*,buttons: {
'Apply': function () {
$(this).dialog('close');
}
} *@
},
dialogVisible: isDialogOpen"
class="iSmallDialog" >
<div class="HelpBar" style="display: block; margin-bottom: 12px;">
<div class="divHelpContent" data-bind="text: ATTRIBUTE_DESCRIPTION">
</div>
</div>
<div style="padding-top: 5px; padding-bottom: 10px;">
Please select options from the list below:
</div>
<div style="overflow-y: auto; max-height: 200px;" class="ListOptions">
<ul data-bind="sortable: { template: 'TestingTemplate', data: filterListOptions },class:'ui-sortable'"></ul>
</div>
<div class="iDialogSubmit">
<button data-bind="click: $data.onDialogCloseCallback,enable: isOptionsSelected" class="active">TestingApply</button>
<button class="btnInactive" data-dismiss="modal" data-bind="click: $data.onDialogClose" aria-hidden="true">TestingCancel</button>
</div>
</div>
</div>
</li>
<!-- /ko -->
<!-- /ko -->
</script>
这是我的第二个模板:
<script id="TestingTemplate" type="text/html">
<li><label data-bind="text: Value, attr:{'for': Value().replace(/ /g,'_')}"></label></li>
</script>
以下是我称呼它的方式:
<div class="LHSListItem">General</div>
<div class="contentDivWithPadding fixHeightAccordian">
<div class="divAccordianContent" id="divAttributes_General">
<ul data-bind="template: { name : 'Testing', foreach : filterData} "></ul>
</div>
</div>
</li>
以下是我的输出:
当我拖动Active
或Out of Study
时,输出结果如下:
这是我的模特:
var extendedAttributeMapping = {
//'ignore': ["ISATTRIBUTESELECTED"],
create: function (options) {
var extendedAttributeModel = ko.mapping.fromJS(options.data);
//drop down for SECTION attribute
extendedAttributeModel.selectedFilterStateforSection = ko.observable();
// extendedAttributeModel.sectionCounter = ko.observable("2509");
extendedAttributeModel.removeSelectedAttribute = function (modelObject) {
modelObject.ISATTRIBUTESELECTED(false);
if(modelObject.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.MultipleChoiceList)
{
modelObject.isDialogOpen(false);
extendedAttributeModel.onAttributeUncheckCallback(modelObject);
//modelObject.OptionsCountLabel("");
//modelObject.isOptionsSelected(false);
//modelObject.OptionsSelectedCount(0);
}
if(modelObject.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.NumberRange)
{
extendedAttributeModel.resetSlider(modelObject);
}
sltModel.getsectionCount();
$(document).trigger('OnApplyAttribute');
};
extendedAttributeModel.resetSlider = function(modelObject){
var minCurrentVal = modelObject.filterSliderValues()[0].MINCURRENT();
var maxCurrentVal = modelObject.filterSliderValues()[0].MAXCURRENT();
modelObject.filterSliderValues()[0].min(minCurrentVal);
modelObject.filterSliderValues()[0].max(maxCurrentVal);
};
//jquery UI Dialog custom Helper events
extendedAttributeModel.onDialogCloseCallback = function(modelObject){
//alert("Callback");
//debugger;
modelObject.isDialogOpen(false);
if(modelObject.ATTRIBUTE_CODE().toLowerCase() == "section")
{
extendedAttributeModel.getSectionAttributeOptionsOnApply(modelObject);
}
else
{
extendedAttributeModel.getOptionsOnApply(modelObject);
}
sltModel.getsectionCount();
extendedAttributeModel.setDefaultModified(modelObject);
$(document).trigger('OnApplyAttribute');
};
extendedAttributeModel.onDialogOpen = function(){
extendedAttributeModel.isDialogOpen(true);
//modelObject.isDialogOpen(true);
//modelObject.ISATTRIBUTESELECTED(true);
};
//SECTION ATTRIBUTE IMPLEMENETATION- EXTENDED MODEL
//SECTION CHECKBOXES SELECTION
extendedAttributeModel.getSectionAttributeOptionsOnApply = function(modelObject) {
var totalSelected = 0;
var selectedAttributeID = modelObject.ATTRIBUTE_ID();
ko.utils.arrayForEach(modelObject.filterddlSectionListOptions(), function(outeritem) {
// sltModel.setSectionAttributeOriginalStateName(outeritem);
if(outeritem.sectionList().length > 0)
{
ko.utils.arrayForEach(outeritem.sectionList(),function(item){
if (item.isSectionSelected()) {
totalSelected++;
// outeritem.isSelected(true);
//highlight selected states
}
item.SavedSectionCheckedState(item.isSectionSelected());
});
}
});
extendedAttributeModel.OptionsCountLabel("(" + totalSelected + ")");
extendedAttributeModel.OptionsSelectedCount(totalSelected);
if(totalSelected > 0)
extendedAttributeModel.isOptionsSelected(true);
else
{
extendedAttributeModel.isOptionsSelected(false);
extendedAttributeModel.ISATTRIBUTESELECTED(false);
}
};
//ali method code starts
extendedAttributeModel.isTaskSelected = function(task) {
return task === self.selectedTask();
};
//ali method code ends
extendedAttributeModel.OnSectionAttributeOptionSelect = function(modelObject,parentObject){
//SavedSectionCheckedState
//isSectionModified
//isSectionSelected
//sectionId
//sectionName
//stateCode
modelObject.isSectionModified(true);
var totalSelected=0;
ko.utils.arrayForEach(parentObject.filterddlSectionListOptions(), function(outeritem) {
if(outeritem.sectionList().length > 0)
{
ko.utils.arrayForEach(outeritem.sectionList(),function(item){
if (item.isSectionSelected()) {
totalSelected++;
}
});
}
});
//sections selected per state
var sectionSelectedPerState=0;
ko.utils.arrayForEach(parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].sectionList(), function(item) {
if (item.isSectionSelected()) {
sectionSelectedPerState++;
}
});
parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].sectionSelectedCount = (sectionSelectedPerState);
var indexCounter = parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].Text().indexOf("(");
var stateNameWithCount = 0;
if(indexCounter > -1)
{
stateNameWithCount = parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].Text().substring(0,indexCounter);
}
else{
stateNameWithCount = parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].Text();
}
if(sectionSelectedPerState == 0)
parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].Text($.trim(stateNameWithCount));
else
parentObject.filterddlSectionListOptions()[sltModel.SectionAttributeStateIndex()].Text($.trim($.trim(stateNameWithCount) + " ("+sectionSelectedPerState+")"));
//sections selected per state
if(totalSelected > 0)
{
parentObject.isOptionsSelected(true);
}
else
{parentObject.isOptionsSelected(false);}
};
extendedAttributeModel.getSectionAttributeOptionsSelectedCount = function(modelObject) {
var totalSelected = 0;
var perStateCounter = 0;
var selectedAttributeID = modelObject.ATTRIBUTE_ID();
ko.utils.arrayForEach(modelObject.filterddlSectionListOptions(), function(outeritem) {
if(outeritem.sectionList().length > 0)
{
ko.utils.arrayForEach(outeritem.sectionList(),function(item){
//if user unchecks checked and press cancel
if(item.isSectionModified()) {
item.isSectionSelected(item.SavedSectionCheckedState());
//if(!item.SavedSectionCheckedState())
//sltModel.setSectionAttributeOriginalStateName(outeritem);
}
if (item.isSectionSelected()) {
totalSelected++;
perStateCounter++;
}
});
}
sltModel.setSectionAttributeOriginalStateName(outeritem,perStateCounter);
perStateCounter = 0;
});
//setting the state name for selected sections
extendedAttributeModel.OptionsCountLabel("(" + totalSelected + ")");
extendedAttributeModel.OptionsSelectedCount(totalSelected);
if(totalSelected > 0)
extendedAttributeModel.isOptionsSelected(true);
else
{
extendedAttributeModel.isOptionsSelected(false);
extendedAttributeModel.ISATTRIBUTESELECTED(false);
}
};
//END OF SECTION ATTRIBUTE IMPLEMENETATION- EXTENDED MODEL
extendedAttributeModel.OnOptionSelect = function(modelObject,parentObject){
modelObject.isModified(true);
var totalSelected=0;
ko.utils.arrayForEach(parentObject.filterListOptions(), function(item) {
if(modelObject.childObjects()==null)
{
if (item.isSelected()) {
totalSelected++;
}
}
});
//Get All the child elements for the selected item
//if the selected option is checked then check all the child options
//else vice versa
if(modelObject.childObjects()!=null){
var isChecked = modelObject.isSelected();
ko.utils.arrayForEach(modelObject.childObjects(), function(item) {
//item.isModified(true);
item.isSelected(isChecked);
totalSelected++;
});
}
if(totalSelected > 0)
{
parentObject.isOptionsSelected(true);
}
else
{parentObject.isOptionsSelected(false);}
};
//new event added for the child options
extendedAttributeModel.OnChildOptionSelect = function(modelObject,parentContext, parentContextParentObject, parentObject){
modelObject.isModified(true);
var totalChildSelected=0;
ko.utils.arrayForEach(parentObject.childObjects(), function(item) {
if (item.isSelected())
{
totalChildSelected++;
}
});
if(totalChildSelected == parentObject.childObjects().length)
{
parentObject.isSelected(true);
}
else
{
parentObject.isSelected(false);
}
if(totalChildSelected > 0)
{
parentContextParentObject.isOptionsSelected(true);
}
else
{
parentContextParentObject.isOptionsSelected(false);
}
};
//eof child option event
extendedAttributeModel.setDefaultModified = function(modelObject){
if(modelObject.ATTRIBUTE_CODE().toLowerCase() == "section")
{
ko.utils.arrayForEach(modelObject.filterddlSectionListOptions(), function(outeritem) {
if(outeritem.sectionList().length > 0)
{
ko.utils.arrayForEach(outeritem.sectionList(),function(item){
item.isSectionModified(false);
});
}
});
}
else
{
ko.utils.arrayForEach(modelObject.filterListOptions(),function(elem){
elem.isModified(false);
});
}
};
//instead of using click event , binding applied to observable property itself to show PopUp
// extendedAttributeModel.ISATTRIBUTESELECTED.subscribe(function(value) {
extendedAttributeModel.checkedCallback = function(modelObject,SOURCE){
if(SOURCE == "LABEL")
{
modelObject.ISATTRIBUTESELECTED(true);
}
if(modelObject.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.MultipleChoiceList)
{
extendedAttributeModel.setDefaultModified(modelObject);
if(modelObject.ISATTRIBUTESELECTED())
{
modelObject.isDialogOpen(true);
//if(modelObject.ATTRIBUTE_DISPLAY_TYPE.toLowerCase()=="list")
//{
//}
}
else
{
modelObject.isDialogOpen(false);
extendedAttributeModel.onAttributeUncheckCallback(modelObject);
sltModel.getsectionCount();
$(document).trigger('OnApplyAttribute');
}
}
if(modelObject.ATTRIBUTE_DISPLAY_TYPE().toLowerCase() == AttributeEnum.NumberRange)
{
if(!modelObject.ISATTRIBUTESELECTED())
{
extendedAttributeModel.resetSlider(modelObject);
}
sltModel.getsectionCount();
$(document).trigger('OnApplyAttribute');
}
};
// },extendedAttributeModel);
extendedAttributeModel.onDialogClose = function(modelObject){
//alert("Close");
//debugger;
modelObject.isDialogOpen(false);
if(modelObject.ATTRIBUTE_CODE().toLowerCase() == "section")
{
extendedAttributeModel.getSectionAttributeOptionsSelectedCount(modelObject);
}
else
{
extendedAttributeModel.getOptionsSelectedCount(modelObject);
}
};
//Helper functions for label count selected Options
extendedAttributeModel.OptionsCountLabel = ko.observable();
extendedAttributeModel.OptionsSelectedCount = ko.observable();
extendedAttributeModel.isOptionsSelected = ko.observable();
extendedAttributeModel.getOptionsSelectedCount = function(modelObject) {
debugger;
var totalSelected = 0;
var selectedAttributeID = modelObject.ATTRIBUTE_ID();
ko.utils.arrayForEach(modelObject.filterListOptions(), function(item) {
//Checkbox is checked but cancel button clicked
//if (item.isSelected() && item.isModified()) {
// item.isSelected(item.SavedCheckedState());
//}
//if user unchecks checked and press cancel
if(item.isModified()) {
item.isSelected(item.SavedCheckedState());
}
if (item.isSelected()) {
totalSelected++;
}
});
extendedAttributeModel.OptionsCountLabel("(" + totalSelected + ")");
extendedAttributeModel.OptionsSelectedCount(totalSelected);
if(totalSelected > 0)
extendedAttributeModel.isOptionsSelected(true);
else
{
extendedAttributeModel.isOptionsSelected(false);
extendedAttributeModel.ISATTRIBUTESELECTED(false);
}
};
extendedAttributeModel.getOptionsOnApply = function(modelObject) {
debugger;
var totalSelected = 0;
var selectedAttributeID = modelObject.ATTRIBUTE_ID();
var i=0;
ko.utils.arrayForEach(modelObject.filterListOptions(), function(item) {
if(modelObject.filterListOptions()[i].childObjects()==null)
{
if (item.isSelected()) {
totalSelected++;
}
}
//Get All the child elements for the selected item
//if the selected option is checked then check all the child options
//else vice versa
if(modelObject.filterListOptions()[i].childObjects()!=null){
//var isChecked = modelObject.filterListOptions()[i].isSelected();
//if(isChecked){
ko.utils.arrayForEach(modelObject.filterListOptions()[i].childObjects(), function(item) {
if( item.isSelected())
{
totalSelected++;
}
});
//}
}
//if (item.isSelected()) {
// totalSelected++;
//}
item.SavedCheckedState(item.isSelected());
i++;
});
extendedAttributeModel.OptionsCountLabel("(" + totalSelected + ")");
extendedAttributeModel.OptionsSelectedCount(totalSelected);
if(totalSelected > 0)
extendedAttributeModel.isOptionsSelected(true);
else
{
extendedAttributeModel.isOptionsSelected(false);
extendedAttributeModel.ISATTRIBUTESELECTED(false);
}
};
//extendedAttributeModel.getOnlySelectedCount = function(modelObject) {
// var totalSelected = 0;
// var selectedAttributeID = modelObject.ATTRIBUTE_ID();
// ko.utils.arrayForEach(modelObject.filterListOptions(), function(item) {
// if (item.isSelected()) {
// totalSelected++;
// }
// });
// return totalSelected;
//};
extendedAttributeModel.onAttributeUncheckCallback = function(modelObject) {
if(modelObject.ATTRIBUTE_CODE().toLowerCase() == "section")
{
ko.utils.arrayForEach(modelObject.filterddlSectionListOptions(), function(outeritem) {
sltModel.setSectionAttributeOriginalStateName(outeritem,-1);
if(outeritem.sectionList().length > 0)
{
ko.utils.arrayForEach(outeritem.sectionList(),function(item){
item.isSectionSelected(false);
});
}
});
}
else
{
ko.utils.arrayForEach(extendedAttributeModel.filterListOptions(), function(item) {
item.isSelected(false);
if(item.childObjects()!=null){
ko.utils.arrayForEach(item.childObjects(), function(item) {
item.isSelected(false);
});
}
});
}
extendedAttributeModel.OptionsCountLabel("");
extendedAttributeModel.OptionsSelectedCount(0);
extendedAttributeModel.isOptionsSelected(false);
};
return extendedAttributeModel;
}
};
};
简而言之,它复制了拖动一个选项。请告诉我我错过了什么?
答案 0 :(得分:1)
您似乎正在使用knockout-sortable库。我过去曾遇到过模板在任何元素之外都有空格的问题 - 它在项目页面上也有说明:
注意2:使用命名模板时,如果您确保模板中只有一个顶级节点且没有周围的文本节点,那么您将在浏览器中获得最佳结果。在顶级节点内,您可以自由使用空白/文本节点。所以,你会想要:
<!-- good - no text nodes surrounding template root node -->
<script id="goodTmpl" type="text/html"><li data-bind="text: name">
<span data-bind="text: name"></span>
</li></script>
<!-- bad -->
<script id="badTmpl" type="text/html">
<li>
<span data-bind="text: name"></span>
</li>
</script>