0

I have created a custom Dojo 1.9 widget that is intended to be a one-size-fits-all combobox where I can insert any dojo widget with a drop-down declaratively, so in my jsp page.

This is an example of a dojo Combobox that I'm hoping to replace with this Widget:

<div data-dojo-type="dojo/store/Memory"                                                
    data-dojo-id="machineNameStore"                                                    
    data-dojo-props="<s:property value='%{getNameJsonString()}'/>"></div>              
<s:set name="MachineName" value="machineSearchView.name"                               
    scope="request"></s:set>                                                           
<div data-dojo-type="dijit/form/ComboBox"                                              
    data-dojo-props="store:machineNameStore, searchAttr:'name', value:'${MachineName}'"
    name="machineSearchView.name" id="machineSearchView.name" />                       

This is the html code of my widget:

<div class="${baseClass}">
    <div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
    data-dojo-id="${dataStoreId}"
    data-dojo-props="${dataSourceData}"></div>
    <s:set name="${fieldName}" value="${searchViewFieldName}" scope="request"> <s:set>
    <div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
    data-dojo-props="store:${dataStoreId}, searchAttr:'${searchAttrName}', value: '${fieldName}'"
    name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>

This is the javascript code of my widget:

/**
 * Javascript for ExpandableSearchComponent
 */
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
        "dojo/text!./templates/ExpandableSearchComponent.html",
        "dijit/_WidgetsInTemplateMixin", "dojo/store/Memory",
        "dijit/form/ComboBox", "dijit/form/Select",
        "dijit/form/FilteringSelect"

], function(declare, _WidgetBase, _TemplatedMixin, template,
        _WidgetsInTemplateMixin, Memory) {

    return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
        templateString : template,
        fieldName : "",
        dataSourceData : "",
        dropDownType : "",
        searchAttrName : "",
        searchViewFieldName : ""
    });

});

And this is how the widget is called in the page:

<div data-dojo-type="js/widgets/ExpandableSearchComponent"                                                                                                                                                                                                            
    data-dojo-id="operatingSystemStore"                                                                                                                                                                                                                               
    data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>',
    fieldName:'machineName' , dataStoreId: 'machineNameDataStore',
    dropDownType: 'dijit/form/ComboBox', searchAttrName: 'name', 
    searchViewFieldName: 'machineSearchView.name'"></div>

This works for about 90% and makes me hopeful that I can make it work completely. My big bug right now before I start expanding on this so it has the appearance of what I want it to be is a problem with the dropdown value element.

As you can see, I have a request-scope servlet property which takes the name of the machine I'm searching for and passes it into the value of my combobox. I need to be able to add multiple instances of my Dojo Widget to my page, so I need to be able to make the name of this servlet property a variable. However, in my Dojo combobox value, I need to use this property I created as the value of the dojo property. So I essentially want to say "insert a JSP property into this page with name X", where X = ${fieldName} generated by Dojo. However, this means generating a servlet AFTER it has already been sent to the page and processed by Dojo.

I've checked other answers, like struts2 get property with dynamic value in jsp and the therein linked questions, but the problem is that those all use either <s:text> or <s:property>, but Dojo can't parse a widget where those are in the data-dojo-props tag. And if I just try to surround ${fieldName} with another ${}, that doesn't get parsed properly.

Is there a way to solve this problem?


Clarification as requested in comments:

  1. Desired behaviour: I want to use Dojo to generate the first HTML code snippet when I write the 4th snippet.
  2. Reproducible problem: I get the right snippet mostly, but when ${fieldName} is parsed by Dojo, it turns into machineName, which is what I want in the s:set, but in the Combobox, when entering it as the value, it's written down as a string literal machineName. I want to adjust my 2nd and 3rd snippet so instead of value: 'machineName', it reads value:'${machineName}' Like in the first snippet so it retrieves the request-scope parameter set in the s:set.
    The essence is that the current value of machineSearchView.name in my struts2 action should be preselected in the combobox. That's what I want to achieve. However, I also want to use multiple instances of this element in the same JSP page, which I think means I can't have them all have the same name.
Community
  • 1
  • 1
Nzall
  • 3,439
  • 5
  • 29
  • 59

1 Answers1

0

After doing some testing, I have found a solution to my problem. In effect, I have split off the servlet translation logic to the page itself, instead of trying to do so in Dojo.

html:

<div class="${baseClass}">
    <div data-dojo-type="dojo/store/Memory" data-dojo-attach-point="memoryNode"
    data-dojo-id="${dataStoreId}"
    data-dojo-props="${dataSourceData}"></div>    
    <div data-dojo-type="${dropDownType}" data-dojo-attach-point="dropDownNode"
    data-dojo-props="store:${dataStoreSearchProp}, name: '${searchViewFieldName}', value: '${valueSearchProp}'" name="${searchViewFieldName}" id="${searchViewFieldName}" ></div>
</div>

Javascript:

/**
 * Javascript for ExpandableSearchComponent
 */
define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
        "dojo/text!./templates/ExpandableSearchComponent.html",
        "dijit/_WidgetsInTemplateMixin", "dojo/store/Memory", "dojo/parser",
        "dijit/form/ComboBox", "dijit/form/Select",
        "dijit/form/FilteringSelect"

], function(declare, _WidgetBase, _TemplatedMixin, template,
        _WidgetsInTemplateMixin, Memory, parser) {

    return declare([ _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin ], {
        templateString : template,
        fieldName : "",
        searchProps : "",
        dataSourceData : "",
        dataStoreSearchProp: "",
        NameSearchProp:"",
        valueSearchProp:"",
        dropDownType : "",
        searchViewFieldName : "",
    });

});

How it's used:

<s:set var='machineName' value='machineSearchView.name'                                                                                                                                                                                                                                            
    scope='request'>                                                                                                                                                                                                                                                                               
</s:set>                                                                                                                                                                                                                                                                                           
<div data-dojo-type="js/widgets/ExpandableSearchComponent"                                                                                                                                                                                                                                         
    data-dojo-id="operatingSystemStore"                                                                                                                                                                                                                                                            
    data-dojo-props="dataSourceData: '<s:property value='%{getNameJsonString()}'/>', dataStoreSearchProp: 'machineNameDataStore', valueSearchProp: '${machineName}', dataStoreId:'machineNameDataStore', dropDownType: 'dijit/form/ComboBox', searchViewFieldName: 'machineSearchView.name'"></div>
</td>

However, because of business miscommunication, this is not the solution I will be going with in the end.

Nzall
  • 3,439
  • 5
  • 29
  • 59