4

Alfresco 共有のフォームの場合、フォームの前の方にあるフィールドの値に応じてカスタム オプションが入力されるドロップダウン ボックスが必要です。

私のフォームには、少なくとも 2 つのフィールドがあります。最初のものは、一意のコードを入力する必要があるテキスト ボックスです。それが完了すると、2 番目の選択ボックスは、入力されたコードを使用してオプションをロードする必要があります。

この要件を裏付けるデータは、データ リストに保存されます。また、Web スクリプトを介して利用できるようにしました (の行に沿って/getOptions/{uniqueCode、有効なオプションの JSON 配列を返します。

現在、コード テキスト フィールドのステータス変更を監視し、ドロップダウン ボックスをリロードするフォームの一部を作成する方法に少し固執しています。私はいくつかのJavaScriptを考えることができますが、ファイルの変更/追加をどこから始めればよいかさえわかりません。

FDKselectone ftl を見つけた を調べました。残念ながら、これは固定オプションのみをサポートしています。

選択した回答に基づく私の実装

これは、私がすでに行っていたことと非常によく似ています。余分な往復を含めずに、サーバー側でこれを実行できることを望んでいました。これまでのところ、これは私が持っている最高のものです。

share-config-custom.xml

ここでフォームを定義し、selectone にしたいプロパティを独自のカスタム フィールド テンプレートにポイントします。これに、Web スクリプトへのパスを保持するパラメーターdsを渡します。dataSource

<config evaluator="node-type" condition="my:contentType">
      <forms>
         <form>
            <field-visibility>
               <show id="my:code" />
               <show id="my:description" />
            </field-visibility>
            <appearance>
               <set id="general" appearance="bordered-panel" label="General" />
               <field id="my:description" set="general">
                   <control template="/org/alfresco/components/form/controls/customSelectone.ftl">
                       <control-param name="ds">/alfresco/service/mark/cache/options</control-param>
                   </control>
               </field>
            </appearance>
        </form>
    </forms>

customSelectone.ftl

私のカスタム ftl には 3 つの主要なステップがあります。まず、share config custom から渡した ftl パラメータを受け取り、それをローカル変数に割り当てます。次に、html<select>ボックスをフィールドとして配置し、最後に、可能なオプションについて Web スクリプトへの呼び出しを実行します。

パラメータ

<#if field.control.params.ds?exists><#assign ds=field.control.params.ds><#else><#assign ds=''></#if>

html

<style type="text/css">
#${fieldHtmlId}-AutoComplete {
    width:${width}; /* set width here or else widget will expand to fit its container */
    padding-bottom:2em;
}
</style>

<div class="form-field">
   <#-- view form -->
   <#if form.mode == "view">
      <div class="viewmode-field">
         <#if field.mandatory && !(field.value?is_number) && field.value == "">
            <span class="incomplete-warning"><img src="${url.context}/components/form/images/warning-16.png" title="${msg("form.field.incomplete")}" /><span>
         </#if>
         <span class="viewmode-label">${field.label?html}:</span>
         <span class="viewmode-value">${field.value?html}</span>
      </div>
   <#else> 
   <#-- alternative:  if form.mode == "edit" -->
   <#-- Create/edit form -->
      <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label>
      <div id="${fieldHtmlId}-AutoComplete">
   <#-- Label to hold error messages from the javascript -->
      <p style="color:red" id="${fieldHtmlId}-scriptError"></p>
        <select id="${fieldHtmlId}" name="${field.name}" 
             <#if field.control.params.styleClass?exists>class="${field.control.params.styleClass}"</#if>
             <#if field.description?exists>title="${field.description}"</#if>
             <#if field.control.params.size?exists>size="${field.control.params.size}"</#if> 
             <#if field.disabled>disabled="true"</#if> >
   <#-- Add the field's current value if it has one as an option -->
             <option>${field.value}</option>
             </select>
          <div id="${fieldHtmlId}-Container"></div>       
      </div>
</div>

Javascript

<script type="text/javascript">//<![CDATA[
(function()
{
    <#-- This references the code field from the form model. For this, the -->
    <#-- share config must be set to show the field for this form. -->
    <#if form.fields.prop_my_code??>
        var code = "${form.fields.prop_my_code.value}";
    <#else>
        var code = 0;
    </#if>

    // get code
    if(code === null || code === "") {
        document.getElementById('${fieldHtmlId}-scriptError').innerHTML = 'No description available.';
        return;
    }

    // Create webscript connection using yui connection manager
    // Note that a much more elegant way to call webscripts using Alfresco.util is 
    // available in the answers here.
    var AjaxConnectionManager = {
        handleSuccess:function(o) {
            console.log('response: '+o.responseText);
            this.processResult(o);
        }, 

        handleFailure:function(o) {
            var selectBox = document.getElementById('${fieldHtmlId}');
            var i;

            document.getElementById('${fieldHtmlId}-scriptError').innerHTML = 'Descriptions not available.';
        }, 

        startRequest:function() {
            console.log('webscript call to ${ds} with params code='+code);
            YAHOO.util.Connect.asyncRequest('GET', "${ds}?typecode="+code, callback, null);
        },

        processResult:function(o) {
            var selectBox = document.getElementById('${fieldHtmlId}');
            var jso = JSON.parse(o.responseText);
            var types = jso.types;
            console.log('adding '+types.length+' types to selectbox '+selectBox);
            var i;

            for(i=0;i<types.length;i++) {
                // If the current field's value is equal to this value, don't add it.
                if(types[i] === null || types[i] === '${field.value}') {
                    continue;
                }
                selectBox.add(new Option(types[i], types[i]));
            }
        }
    }

    // Define callback methods
    var callback = {
        success:AjaxConnectionManager.handleSuccess,
        failure:AjaxConnectionManager.handleFailure,
        scope: AjaxConnectionManager
    };

    // Call webscript
    AjaxConnectionManager.startRequest();
})();
//]]></script>
<#-- This closes the form.mode != "create" condition, so the js is only executed when in edit/create mode. -->
</#if>
4

2 に答える 2

4

私は以前に同様の仕事をしていました。まず、構成 xml でカスタム テンプレートを定義する必要があります。

<config evaluator="node-type" condition="my:type">
    <forms>
        <form>
            <field-visibility>
                <show id="cm:name" />
                <show id="my:options" />
                <show id="cm:created" />
                <show id="cm:creator" />
                <show id="cm:modified" />
                <show id="cm:modifier" />
            </field-visibility>
            <appearance>
                <field id="my:options">
                    <control template="/org/alfresco/components/form/controls/custom/custom-options.ftl" />
                </field>
            </appearance>
        </form>
    </forms>
</config>

ここで何が起こるかというと、フォーム エンジンはtypecustom-options.ftlをレンダリングするために を探します。 データを表示するために必要な html と、もちろん、webscript からリストをロードする javascript クラスへの呼び出しが含まれます。だからこんな感じmy:optionsmy:typecustom-options.ftl

<#assign controlId = fieldHtmlId + "-cntrl">
<script type="text/javascript">//<![CDATA[
// Here you could call your webscript and load your list
</script>

<div id="${controlId}" class="form-field">
 <label for="${fieldHtmlId}">${msg("form.control.my-options.label")}:<#if field.mandatory><span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></#if></label>
 <select id="${fieldHtmlId}" name="${field.name}" tabindex="0"
       <#if field.description??>title="${field.description}"</#if>
       <#if field.control.params.size??>size="${field.control.params.size}"</#if> 
       <#if field.control.params.styleClass??>class="${field.control.params.styleClass}"</#if>
       <#if field.control.params.style??>style="${field.control.params.style}"</#if>>
 </select>
 <@formLib.renderFieldHelp field=field />
</div>
于 2013-06-25T16:51:32.887 に答える