2016-09-23 27 views
0

我有以下小部件HTML。Dijit/form /选择内部Dijit/TitlePane自定义小部件的一部分在错误位置打开下拉列表

<div class="expandableSearch"> 
    <div data-dojo-type="dijit/TitlePane" data-dojo-props="title:'${prefixTitle}', open:false" id="${containedWidgetId}titleNodePane"> 
     <div id="container" 
     class="${baseClass}Container" 
     data-dojo-attach-point="containerNode"></div> 
    </div> 
</div> 

与它背后的以下JavaScript:

/** 
* Javascript for ExpandableSearchComponent 
*/ 
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin", 
     "dojo/text!./templates/ExpandableSearchComponent.html", 
     "dijit/TitlePane", "dijit/_WidgetsInTemplateMixin", "dijit/registry", 
     "dojo/on", "dojo/aspect", "dojo/_base/lang", "dojo/dom", 
     "dojo/dom-attr", "js/utils/CommonUtils", "dijit/focus" ], function(declare, 
     _WidgetBase, _TemplatedMixin, template, TitlePane, 
     _WidgetsInTemplateMixin, registry, on, aspect, lang, dom, domAttr, 
     CommonUtils, focusUtil) { 

    return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], { 
     templateString : template, 
     prefixTitle : "", 
     containedWidgetId : "", 
     defaultValue : "", 

     startup : function() { 
      this.inherited(arguments); 
      var containedWidgetId = this.containedWidgetId; 
      var containedWidget = registry.byId(this.containedWidgetId); 
      if (typeof containedWidget === "undefined") { 
       containedWidget = dom.byId(this.containedWidgetId); 
      } 

      var titlePane = registry.byId(this.containedWidgetId 
        + "titleNodePane"); 
      this.own(on(titlePane, "Show", function() { 

       if (typeof containedWidget.loadAndOpenDropDown === "function") { 
        containedWidget._aroundNode = containedWidget.focusNode; 
        containedWidget.loadAndOpenDropDown(); 
       } 
       focusUtil.focus(dom.byId(containedWidgetId)); 
      })); 
      this.own(on(titlePane, "Hide", function() { 
       if (typeof containedWidget.closeDropDown === "function") { 
        containedWidget.closeDropDown(); 
       } 

      })); 

      this.own(on(containedWidget, "change", function(event) { 
       var newVal = ""; 
       if (typeof containedWidget.attr == "function" 
         && containedWidget.attr("displayedValue") !== null) { 
        newVal = containedWidget.attr("displayedValue"); 
       } 
       if (typeof event === "object") { 
        newVal = containedWidget.value; 
       } 
       var newTitle = this.prefixTitle + newVal; 
       if (newTitle.length > 35) { 
        newTitle = newTitle.substring(0, 32) + "..."; 
       } 
       titlePane.set("title", newTitle); 
       if (titlePane.open) { 
        titlePane.toggle(); 
       } 
      }.bind(this))); 

     }, 
     reset : function() { 
      var containedWidget = registry.byId(this.containedWidgetId); 
      if (typeof containedWidget === "undefined") { 
       containedWidget = dom.byId(this.containedWidgetId); 
      } 
      if (typeof containedWidget.set === "function" 
        && containedWidget.attr("displayedValue") !== null) { 
       containedWidget.set("value", this.defaultValue); 
      } 
      if (typeof containedWidget.set === "function" 
        && containedWidget.attr("displayedValue") === null) { 
       containedWidget.set("value", this.defaultValue); 
      } 
      if (typeof containedWidget.onChange !== "function") { 
       domAttr.set(containedWidget, "value", this.defaultValue); 
       if ("createEvent" in document) { 
        var evt = document.createEvent("HTMLEvents"); 
        evt.initEvent("change", false, true); 
        containedWidget.dispatchEvent(evt); 
       } else { 
        containedWidget.fireEvent("onchange"); 
       } 
      } 
     } 
    }); 

}); 

从本质上讲,HTML和Javascript的结合只是一个dijit/TitlePane有一些额外的JavaScript来

  1. 自动设置的标题窗格;
  2. Automaticaly打开和关闭底层元素,如果它有一个下拉菜单;
  3. 自动将焦点设置为包含的元素。

像这样来使用:

<div data-dojo-type="js/widgets/ExpandableSearchComponent" id="machineSearchView.operatingSystemExpandableSearch" 
    data-dojo-props="prefixTitle: '<s:property value="%{getText('label.machine.operatingSystem')}"/>: ', containedWidgetId: 'machineSearchView.operatingSystem', defaultValue: '-1'"> 
    <div data-dojo-type="dojo/store/Memory" 
     data-dojo-id="operatingSystemStore" 
     data-dojo-props="<s:property value='%{getOperatingSystemTypeCodeJsonString()}'/>"></div> 
    <s:set name="operatingSystem" value="machineSearchView.operatingSystem" 
     scope="request"></s:set> 
    <div data-dojo-type="dijit/form/Select" class="readOnlySelect" 
     data-dojo-props="store:operatingSystemStore, labelAttr: 'label', sortByLabel: false, value:'${operatingSystem}'" 
     name="machineSearchView.operatingSystem" id="machineSearchView.operatingSystem"></div> 
</div> 

当我打开它,它看起来像这样:

enter image description here

正如你所看到的,dijit/form/Select打开SelectMenuTitlePane组件而不是选择div本身。你可以看看SelectMenu旁边的选择。

由于我喜欢它看一个例子:

enter image description here

containedWidget._aroundNode = containedWidget.focusNode;是企图使其工作基础上https://davidwalsh.name/dijit-dropdowns,但它并没有帮助。我不知道还有什么我可以尝试。我已经试着去深入调试Dojo组件内部的狂欢,但无济于事?

我该如何解决这个问题?

回答

1

TitlePane在打开时播放动画。在“Show”事件上打开选择下拉菜单还为时过早,TitlePane容器尚未准备好。您需要等待动画完成。 TitlePane中的内部打开动画对象是_wipeIn,您可以在其onEnd()函数之后添加一个方面。

require([ 
 
    "dijit/TitlePane", 
 
    "dijit/form/Select", 
 
    "dojo/data/ObjectStore", 
 
    "dojo/store/Memory", 
 
    "dojo/on", 
 
    "dojo/aspect", 
 
    "dojo/domReady!" 
 
], function(TitlePane, Select, ObjectStore, Memory, on, aspect) { 
 

 
    var store = new Memory({ 
 
    data: [ 
 
     { id: "foo", label: "Foo" }, 
 
     { id: "bar", label: "Bar" } 
 
    ] 
 
    }); 
 

 
    var os = new ObjectStore({ objectStore: store }); 
 

 
    var s = new Select({store: os}); 
 
    s.startup(); 
 
    
 
    var tp = new TitlePane({title:"I'm a TitlePane", content: s, open: false}); 
 
    tp.placeAt("content"); 
 
    tp.startup(); 
 
    
 
    /* 
 
    // This does not work: 
 
    on(tp, "Show", function() { 
 
    s.loadAndOpenDropDown(); 
 
    }); 
 
    */ 
 
    
 
    // This works: 
 
    aspect.after(tp._wipeIn, "onEnd", function() { 
 
     s.loadAndOpenDropDown(); 
 
    }); 
 
    
 
    on(tp, "Hide", function() { 
 
     s.closeDropDown(); 
 
    }); 
 
});
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script> 
 
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css"> 
 
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css"> 
 

 
<div class="claro"> 
 
    <div id="content"></div> 
 
</div>