-->

Alfresco community 5.1.x workflow form add input f

2019-01-20 18:18发布

问题:

I am using Alfresco Community 5.1.x. I want to create a custom workflow using kickstart in that one of the forms I have + button when + button add text fields dynamically. Is this possible? How?

回答1:

I hope you will get some idea from this control.

On Share configration,

        <field id="myco:userDetails" set="userDetails" label="User Details" >
            <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
       </field>

userdetails.ftl

<style>
   .yui-dt{
   border: 1px solid #ccc;
   font-weight: normal;
   }
   .yui-dt th {
   margin: 0;
   padding: 0;
   border: none;
   border-right: 1px solid #CBCBCB;
   border-bottom: 1px solid #CBCBCB;
   background: #D8D8DA url(sprite.png) repeat-x 0 0;
   }
   .yui-dt th {
   margin: 0;
   padding: 0;
   border: none;
   border-right: 1px solid #CBCBCB;
   border-bottom: 1px solid #CBCBCB;
   background: #D8D8DA url(sprite.png) repeat-x 0 0;
   }
   .yui-dt td {
   border-top: 1px solid #ccc!important;
   padding: 5px 10px!important;
   }
   .yui-dt td:last-of-type,.yui-dt th:last-of-type {
   border-right: 0px solid #CBCBCB;
   }
   .yui-dt td:last-of-type {
   border-top: 0px solid #CBCBCB;
   }
   .yui-dt-liner {
   margin: 0;
   padding: 0;
   padding: 4px 10px 4px 10px!important;
   }
   .set-title {
   font-size: 116%;
   border-bottom: 1px solid #eeeeee;
   padding-bottom: 0.1em;
   margin-bottom: 0.6em;
   margin-top: 0.2em;
   }
   .buttons{
   background:#fff;
   border:1px solid #ddd;
   padding:4px;
   cursor:pointer;
   }
   .buttons:hover{
   background:#EAE8E8;
   }
   .hyperlink{
   color: blue!important;
   text-decoration: underline!important
   padding:5px;
   }
</style>
<@link href="${url.context}/res/components/workflow/workflow-form.css" group="workflow"/>
<#include "/org/alfresco/components/form/controls/common/utils.inc.ftl" />
<div class="form-field">
   <#if form.mode == "view" || (form.mode == "edit" && field.disabled)>
   <div class="viewmode-field">
      <span class="viewmode-label">${field.label?html}:</span>
      <span class="viewmode-value">
         <div id="divUserList">
            <label>User List:</label>
            <table id="tblUserList" class="yui-dt " style="width:100%">
               <tr>
                  <td>First Name </td>
                  <td>Last Name</td>
                  <td> Email-Id</td>
                  <td>Actions</td>
               </tr>
               <tr id="placeHolderRow">
                  <td colspan="4"><span>No user details are requested.</span></td>
               </tr>
            </table>
         </div>
      </span>
   </div>
   <#else>
   <div id="divUserList">
      <div id="divButtonContainer">
         <label>First Name : <span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></label>
         <input type="text" id="txtFirstName" style="margin-bottom:10px;">
         <label>Last Name : <span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></label>
         <input type="text" id="txtLastName" style="margin-bottom:10px;">
         <label>Email-Id : <span class="mandatory-indicator">${msg("form.required.fields.marker")}</span></label>
         <input type="text" id="emailId" style="margin-bottom:20px;">    <br>        
         <input class="buttons" id="btnAdd" onclick="javascript:addRows();return false;" type="button" value="Add another user" />            
         <input class="buttons" style="background:#fff" id="btnClear" onclick="javascript:clearControls();return false;" type="button" value="Clear all users" />            
      </div>
      <div class="set-title" style="margin-top:20px;"> User List:</div>
      <table id="tblUserList" class="yui-dt " style="width:100%">
         <tr>
            <th style="background: #D8D8DA;padding-left: 10px;padding-right: 10px;padding-top: 5px;padding-bottom: 5px;" class="yui-dt-liner">First Name </th>
            <th style="background: #D8D8DA;padding-left: 10px;padding-right: 10px;padding-top: 5px;padding-bottom: 5px;" class="yui-dt-liner">Last Name</th>
            <th style="background: #D8D8DA;padding-left: 10px;padding-right: 10px;padding-top: 5px;padding-bottom: 5px;" class="yui-dt-liner">  Email-Id</th>
            <th style="background: #D8D8DA;padding-left: 10px;padding-right: 10px;padding-top: 5px;padding-bottom: 5px;" class="yui-dt-liner">Actions</th>
         </tr>
         <tr id="placeHolderRow">
            <td class="yui-dt-liner" colspan="4" style="border-right:none;">
               <span>No user details are requested.</span>
            </td>
         </tr>
      </table>
   </div>
   <#-- Keep the hidden control, to sent the values to the repo -->
   <input type="hidden" id="${fieldHtmlId}" name="${field.name}" />
   </#if>
</div>
<script>    
   updateControlMode();
   function updateControlMode()
   {      
       var readOnly = "${field.disabled?c}";
       if (readOnly =="true")
       {
           document.getElementById("tblUserList").innerHTML  = '${field.value}';       
           var table = document.getElementById("tblUserList");
           for (var i = 0;i<table.rows.length; i++) {
               var row = table.rows[i];
               for (var j = 0;j<row.cells.length;  j++) {
                   var col = row.cells[j];
                   if (j == 3)
                   {
                       col.parentNode.removeChild(col);  //Removing the action column in readOnly mode
                   }
              }  
           }

       }
   }
   function clearControls()
   {
       document.getElementById("txtFirstName").value="";
       document.getElementById("txtLastName").value="";
       document.getElementById("emailId").value="";

   }

   function deleteRow(btn) {
     var row = btn.parentNode.parentNode;
     row.parentNode.removeChild(row);
     var table = document.getElementById("tblUserList");
     var rowLength = table.rows.length;
     if (rowLength ==1 ) //Only Table header is present
     {
       var placeHolderRow = table.insertRow(rowLength);
       var cell1 = placeHolderRow.insertCell(0);
       cell1.colspan="4";
       cell1.innerHTML="No  user details are requested."    
     }
   }
   function addRows()
   {
       var placeHolderRow = document.getElementById("placeHolderRow");
       if (placeHolderRow)
           placeHolderRow.remove();

       var firstName = document.getElementById("txtFirstName").value;
       var lastName =document.getElementById("txtLastName").value;
       var emailId = document.getElementById("emailId").value;

       if (!(firstName || lastName || emailId || firstName.value.trim().length == 0  || lastName.value.trim().length || emailId.value.trim().length))
       {
           alert("Please enter all the values");
           return false;
       }

       var table = document.getElementById("tblUserList");
       var rowLength = table.rows.length;
       // Create an empty <tr> element and add it to the 1st position of the table:
       var row = table.insertRow(rowLength);
       row.id = Alfresco.util.generateDomId();


       // Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
       var cell1 = row.insertCell(0);
       var cell2 = row.insertCell(1);
       var cell3 = row.insertCell(2);
       var cell4 = row.insertCell(3);

       // Add some text to the new cells:
       cell1.innerHTML = document.getElementById("txtFirstName").value;
       cell1.style="color:red";
       cell2.innerHTML = document.getElementById("txtLastName").value;
       cell3.innerHTML = document.getElementById("emailId").value;
       cell4.innerHTML ="<a class='hyperlink' style='margin-right:10px' href='#' onclick='javascript:editRow(this);return false;'> Edit </a>  <a href='#' class='hyperlink' onclick='javascript:deleteRow(this);return false;'> Delete </a> ";

       /* Set the content */
       document.getElementById("${fieldHtmlId}").value = table.outerHTML.replace(/(\r\n|\n|\r)/gm,"");
       clearControls();
   }

   function clear()
   {
       document.getElementById("txtFirstName").value="";
       document.getElementById("txtLastName").value="";
       document.getElementById("emailId").value="";
   }
</script>

If you want this control as, read-only then,add read-only="true" in the share configuration.

<field id="myco:userDetails" set="userDetails" read-only="true" label="User Details" >
            <control template="/org/alfresco/components/form/controls/workflow/userdetails.ftl" />
       </field>

Please note: As of now, this is not production ready and we're also in developement mode. We want to improve this control, please share your idea / comments/ feedback.



回答2:

I want to add a couple of words on that subject.

As you can see from the Share architecture:

The presentation is actually put together with two different kinds of JavaScript frameworks, Yahoo UI library (YUI) and the new one called Aikau ...

You can use capabilities of the YAHOO! YUI library (in my humble experience this is an excellent library!)

Note on the container with the 'bd' identifier, you can often find it in WebScripts. This is how YUI works in Alfresco. Here will be created your table and other stuff...

<html>

<head>
    <title>Adding and deleting rows dynamically</title>
    <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.0r4/build/datatable/assets/skins/sam/datatable.css">
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/datasource/datasource-min.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/element/element-min.js"></script>
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/dragdrop/dragdrop-min.js"></script>    
    <script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/datatable/datatable-min.js"></script>
</head>

<body id="doc" class="yui-t1 yui-skin-sam">
    <div id="hd">
        <h1>Adding and deleting rows dynamically</h1>
    </div>
    <div id="bd"></div>
    <div id="ft">
        <button id="addRow">Add Row</button>
    </div>
    <script type="text/javascript">
        YAHOO.util.Event.onDOMReady(function() {
            var Event = YAHOO.util.Event,
                DT = YAHOO.widget.DataTable,
                DS = YAHOO.util.DataSource;

            var myDS = new DS([{
                    FirstName: 'John',
                    LastName: 'Paul',
                    EmailId: 'jpaul@example'
                },
                {
                    FirstName: 'michael',
                    LastName: 'raj',
                    EmailId: 'mraj@example'
                }
            ], {
                responseType: DS.TYPE_JSARRAY,
                responseSchema: {
                    fields: ['FirstName', 'LastName', 'EmailId']
                }
            });

            var myDt = new DT(
                'bd', [{
                        key: 'FirstName',
                        label: 'First Name',
                        sortable: true
                    },
                    {
                        key: 'LastName',
                        label: 'Last Name',
                        sortable: true
                    },
                    {
                        key: 'EmailId',
                        label: 'Email-Id',
                        formatter: 'email',
                        sortable: true
                    },
                    {
                        key: 'delete',
                        label: ' ',
                        formatter: function(elLiner,
                            oRecord, oColumn, oData) {
                            elLiner.innerHTML =
                                ' <button > Delete <\/button>';
                        }
                    }
                ],
                myDS,
                {
                   draggableColumns:true
                }
            );

            myDt.on('cellClickEvent', function(oArgs) {
                var target = oArgs.target,
                    oRecord = this.getRecord(target),
                    oColumn = this.getColumn(target);

                switch (oColumn.key) {
                    case 'delete':
                        this.deleteRow(oRecord);
                        break;
                }
            });

            var i = 0;
            Event.on('addRow', 'click', function() {
                myDt.addRow({
                    FirstName: 'first name' + i,
                    LastName: 'last name' + i,
                    EmailId: 'email' + i + '@example'
                });
                i++;
            });
        });
    </script>
</body>

</html>

One of many examples from Share is the workflow history. As you can see, there is a container with an identifier ${el}-workflowHistory-form-section:

...
<div id="${el}-workflowHistory-form-section" class="workflow-history">
    <h3>${msg("header.history")}</h3>
    <div class="form-element-background-color"></div>
</div>
...

This container is then used to build the widget.

...
var historyContainerEl = Dom.get(this.id + "-workflowHistory-form-section"),
    historyTasksEl = Selector.query("div", historyContainerEl, true);

var historyColumnDefinitions =
[
    { key: "name", label: this.msg("column.type"), formatter: this.bind(this.renderCellType) },
    { key: "owner", label: this.msg("column.completedBy"), formatter: this.bind(this.renderCellCompletedBy) },
    { key: "id", label: this.msg("column.dateCompleted"), formatter: this.bind(this.renderCellDateCompleted) },
    { key: "state", label: this.msg("column.outcome"), formatter: this.bind(this.renderCellOutcome) },
    { key: "properties", label: this.msg("column.comment"), formatter: this.bind(this.renderCellComment) }
];

var workflowHistoryDS = new YAHOO.util.DataSource(this.historyTasks,
{
    responseType: YAHOO.util.DataSource.TYPE_JSARRAY
});

this.widgets.historyTasksDataTable = new YAHOO.widget.DataTable(historyTasksEl, historyColumnDefinitions, workflowHistoryDS,
{
    MSG_EMPTY: this.msg("label.noTasks")
});
...

By using YUI you get all of the features of the DataTable widget, such as sorting, pagination, column reordering, resizing, inline editing, and more... In addition, your code becomes much cleaner due to the html reduction.

To understand how does YUI works, I can recommend you an excellent book by Daniel Barreiro and Dan Wellman - "YUI 2. 8 Learning the Library: Develop Your Next-Generation Web Applications with the YUI Javascript Development Library"