[ 
https://issues.apache.org/jira/browse/TRINIDAD-723?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12528728
 ] 

Gregg Leichtman commented on TRINIDAD-723:
------------------------------------------

Apparently two more private generated JavaScript functions 
TrShuttleProxy._orderList and TrShuttleProxy._orderTopBottomList are also 
affected by this bug in the selectOrderShuttle component. I have also patched 
and successfully overridden these functions as follows (all fixes demarcated by 
"// gsl fix"; again I only added new lines of code; existing code lines were 
not altered):

    /*
     * _orderList
     *
     * This function reorders the given list by shifting the selections in
     * the given direction.  If no formName is supplied, the form is found when
     * this is called. The 'list' parameter should be the
     * list name(i.e.  "<shuttleName>:leading" or "<shuttleName>:trailing")
     */
    TrShuttleProxy._orderList = function(
      down,
      list,
      formName
      )
    {
      //get the formName if needed
      if(formName == (void 0))
      {
        formName = TrShuttleProxy._findFormNameContaining(list);
      }
      //get the actual list
      var colList = document.forms[formName].elements[list];
      //get all the selected item indexes
      var selItems = TrShuttleProxy._getSelectedIndexes(formName, list);
      //if no items are selected, return with alert.
      if(selItems.length == 0)
      {
        if (_shuttle_no_items_selected.length > 0)
          alert(_shuttle_no_items_selected);
        return;
      }
      var descArray = TrShuttleProxy._getDescArray(list);
      // Start with the last selected index and move up, working by blocks
      var processed = selItems.length - 1;
      while (processed >= 0)
      {
        var lastInBlock = selItems[processed];
        var firstInBlock = lastInBlock;
        var tempIndex = processed;
        // find the first index in that block
        while ((tempIndex > 0) && ((selItems[tempIndex] -
                                    selItems[tempIndex - 1]) == 1))
        {
          tempIndex--;
          firstInBlock--;
        }
        if (down == 0)
        {
          // move this block up
          // if we are at the top, do nothing
          if(firstInBlock != 0)
          {
            //get the text and value of the one space above the block
            var oText = colList.options[firstInBlock-1].text;
            var oValue = colList.options[firstInBlock-1].value;
var oTitle = colList.options[firstInBlock-1].title; // gsl fix
            if ( descArray != (void 0) )
              var dValue = descArray[firstInBlock - 1];
            //move the block up one at a time
            for (var i = firstInBlock; i <= lastInBlock; i++)
            {
              colList.options[i-1].text = colList.options[i].text;
              colList.options[i-1].value = colList.options[i].value;
colList.options[i-1].title = colList.options[i].title; // gsl fix
              colList.options[i-1].selected = true;
              if ( descArray != (void 0) )
                descArray[i-1] = descArray[i];
            }
             //put the info of the slot above the selection below it
            colList.options[lastInBlock].text = oText;
            colList.options[lastInBlock].value = oValue;
colList.options[lastInBlock].title = oTitle; // gsl fix
            colList.options[lastInBlock].selected = false;
            if ( descArray != (void 0) )
              descArray[lastInBlock] = dValue;
          }
        }
        else
        {
          // move this block down
          // if we are at the bottom, do nothing
          if(lastInBlock != colList.length-2)
          {
            //get the text and value of the one space below the block
            var oText = colList.options[lastInBlock+1].text;
            var oValue = colList.options[lastInBlock+1].value;
var oTitle = colList.options[lastInBlock+1].title; // gsl fix
            if ( descArray != (void 0) )
              var dValue = descArray[lastInBlock+1];
             //move the block down one at a time
            for (var i = lastInBlock; i >= firstInBlock; i--)
            {
              colList.options[i+1].text = colList.options[i].text;
              colList.options[i+1].value = colList.options[i].value;
colList.options[i+1].title = colList.options[i].title; // gsl fix
              colList.options[i+1].selected = true;
              if ( descArray != (void 0) )
                descArray[i+1] = descArray[i];
            }
             //put the info of the slot below the selection above it
            colList.options[firstInBlock].text = oText;
            colList.options[firstInBlock].value = oValue;
colList.options[firstInBlock].title = oTitle; // gsl fix
            colList.options[firstInBlock].selected = false;
            if ( descArray != (void 0) )
              descArray[firstInBlock] = dValue;
          }
        }
        processed = tempIndex - 1;
      }
      TrShuttleProxy._displayDesc( list, formName );
      //make the list for submission
      TrShuttleProxy._makeList(formName, list);
    }
   
    /*
     * _orderTopBottomList
     *
     * This function reorders the given list by shifting the selections all the 
way
     * in the given direction.  If no formName is supplied, the form is found 
when
     * this is called. The 'list' parameter should be the
     * list name(i.e.  "<shuttleName>:leading" or "<shuttleName>:trailing")
     */
    TrShuttleProxy._orderTopBottomList = function(
      down,
      list,
      formName
      )
    {
      //get the formname if needed
      if(formName == (void 0))
      {
        formName = TrShuttleProxy._findFormNameContaining(list);
      }
      //get the actual list
      var colList = document.forms[formName].elements[list];
      //get all the indexes of the items selected in the list
      var selItems = TrShuttleProxy._getSelectedIndexes(formName, list);
      //if no items are selected, return with alert.
      if(selItems.length == 0)
      {
        if (_shuttle_no_items_selected.length > 0)
          alert(_shuttle_no_items_selected);
        return;
      }
      var descArray = TrShuttleProxy._getDescArray(list);
      var moveDescArray = new Array();
      var selDescArray = new Array();
      var moveItemsText = new Array();
      var moveItemsValue = new Array();
var moveItemsTitle = new Array(); // gsl fix
      var moveItemsIndex = 0;
      if(down == 0)
      {
        //get an array of all the items we will have to displace in order
        var selItemsIndex = 0;
        var moveItemsIndex = 0;
        for(var colListIndex=0;
            colListIndex < selItems[selItems.length - 1];
            colListIndex++)
        {
          if(colListIndex != selItems[selItemsIndex])
          {
            moveItemsText[moveItemsIndex] = colList.options[colListIndex].text;
            moveItemsValue[moveItemsIndex] = 
colList.options[colListIndex].value;
moveItemsTitle[moveItemsIndex] = colList.options[colListIndex].title; // gsl fix
            if (  descArray != (void 0) )
              moveDescArray[moveItemsIndex] = descArray[colListIndex];
            moveItemsIndex++
          }
          else
          {
            if ( descArray != (void 0) )
              selDescArray[selItemsIndex] = descArray[colListIndex];
            selItemsIndex++;
          }
        }
        if ( descArray != (void 0) )
          selDescArray[selItemsIndex] = descArray[colListIndex];
        //place items to move toward top of col
        for(var i = 0; i < selItems.length; i++)
        {
          colList.options[i].text = colList.options[selItems[i]].text;
          colList.options[i].value = colList.options[selItems[i]].value;
colList.options[i].title = colList.options[selItems[i]].title; // gsl fix
          colList.options[i].selected = true;
          if ( descArray != (void 0) )
            descArray[i] = selDescArray[i];
        }
        //place displaced items below
        for(var j = 0; j < moveItemsText.length; j++)
        {
          colList.options[i].text = moveItemsText[j];
          colList.options[i].value = moveItemsValue[j];
colList.options[i].title = moveItemsTitle[j]; // gsl fix
          colList.options[i].selected = false;
          if ( descArray != (void 0) )
            descArray[i] = moveDescArray[j];
          i++
        }
      }
      else
      {
        //get an array of all the items we will have to displace in order
        var selItemsIndex = 1;
        var moveItemsIndex = 0;
        if ( descArray != (void 0) )
          selDescArray[0] = descArray[selItems[0]];
        for(var colItemsIndex=selItems[0]+1;
            colItemsIndex <= colList.length-2;
            colItemsIndex++)
        {
          if((selItemsIndex == selItems.length) ||
             (colItemsIndex != selItems[selItemsIndex]))
          {
            moveItemsText[moveItemsIndex] = colList.options[colItemsIndex].text;
            moveItemsValue[moveItemsIndex] = 
colList.options[colItemsIndex].value;
moveItemsTitle[moveItemsIndex] = colList.options[colItemsIndex].title; // gsl 
fix
            if ( descArray != (void 0) )
              moveDescArray[moveItemsIndex] = descArray[colItemsIndex];
            moveItemsIndex++;
          }
          else
          {
            if ( descArray != (void 0) )
              selDescArray[selItemsIndex] = descArray[colItemsIndex];
            selItemsIndex++;
          }
        }
        //place items to move toward bottom of col
        var j = colList.length - 2;
        for(var i = selItems.length-1; i >= 0; i--)
        {
          colList.options[j].text = colList.options[selItems[i]].text;
          colList.options[j].value = colList.options[selItems[i]].value;
colList.options[j].title = colList.options[selItems[i]].title; // gsl fix
          colList.options[j].selected = true;
          if ( descArray != (void 0) )
            descArray[j] = selDescArray[i];
          j--;
        }
        //place displaced items above
        for(var i = moveItemsText.length-1; i >= 0; i--)
        {
          colList.options[j].text = moveItemsText[i];
          colList.options[j].value = moveItemsValue[i];
colList.options[j].title = moveItemsTitle[i]; // gsl fix
          colList.options[j].selected = false;
          if ( descArray != (void 0) )
            descArray[j] = moveDescArray[i];
          j--
        }
      }
      TrShuttleProxy._displayDesc( list, formName );
      //make the list for submission
      TrShuttleProxy._makeList(formName, list);
    }

                           -=> Gregg <=-


> Shuttle Component Fails to Transfer Short Description on Item Move
> ------------------------------------------------------------------
>
>                 Key: TRINIDAD-723
>                 URL: https://issues.apache.org/jira/browse/TRINIDAD-723
>             Project: MyFaces Trinidad
>          Issue Type: Bug
>          Components: Components
>    Affects Versions: 1.2.1-core
>         Environment: [EMAIL PROTECTED]:~> uname -a
> Linux aragorn 2.6.11.4-21.13-default #1 Mon Jul 17 09:21:59 UTC 2006 i686 
> i686 i386 GNU/Linux
> Eclipse Europa 3.3 with MyEclipse 3.3 M1.
> Using JSF RI 1.2:
> INFO: Initializing Sun's JavaServer Faces implementation (1.2_04-b16-p02) for 
> context '/trinidaddemo' 
>            Reporter: Gregg Leichtman
>
> I have found and fixed what appears to be a bug in the shuttle component 
> JavaScript code. This bug might affect other components as well. Any 
> component that uses the TrShuttleProxy._moveItems and the 
> TrShuttleProxy._moveAllItems functions would be affected.
> The problem is that the title attribute for the HTML option tag is not 
> propagated from the leading to the trailing portion of the shuttle or 
> vice-versa when the user selects move or move all. Therefore, the short 
> description attribute in the shuttle tags are converted to title attributes 
> on the HTML options and show a tooltip on initial page load but are lost as 
> soon as the user moves one or more selections between the leading and 
> trailing portions of the shuttle. This seems to occur because the JavaScript 
> that handles item moving simply has no code to propagate the HTML title 
> attribute between the leading and trailing portions of the shuttle.
> I have patched and overridden the generated JavaScript code as shown below to 
> fix this problem (patched code demarcated by // gsl fix):
>     /*
>      * Overridden method to fix bug in generated code. gsl
>      * Remove this code when fix is incorporated into Trinidad.
>      * Should be incorporated by version 1.2.3.
>      *
>      * _moveItems
>      *
>      * This function moves the selected items in the 'from' list to the
>      * 'to' list.  If no formName is supplied, the form is found when
>      * this is called.  The items are inserted in the 'to' list
>      * at the bottom. The 'from' and 'to' parameters should be the
>      * list names(i.e.  "<shuttleName>:leading" or "<shuttleName>:trailing")
>      */
>     TrShuttleProxy._moveItems = function(
>       from,
>       to,
>       formName
>       )
>     {
>           //get the formName if needed
>           if(formName == (void 0))
>           {
>             formName = TrShuttleProxy._findFormNameContaining(from);
>           }
>           if(formName.length == 0)
>           {
>             alert(shuttle_no_form_available);
>             return;
>           }
>           //store the from and to lists
>           var fromList = document.forms[formName].elements[from];
>           var toList = document.forms[formName].elements[to];
>           if ( fromList == (void 0 ) || toList == (void 0 ))
>             return;
>           //get all the indexes of the selected items
>           var selItems = TrShuttleProxy._getSelectedIndexes(formName, from);
>           //if no items are selected, return with alert.
>           if(selItems.length == 0)
>           {
>             if (_shuttle_no_items_selected.length > 0)
>               alert(_shuttle_no_items_selected);
>             return;
>           }
>           var fromDescArray = TrShuttleProxy._getDescArray(from);
>           var toDescArray = TrShuttleProxy._getDescArray(to);
>           //set no selection on toList so it will only have new items 
> selected.
>           toList.selectedIndex = -1;
>           //get the index in the toList to start inserting at.  Length-1 
> because of
>           //bars.
>           var insertAt = toList.length-1;
>           //save bar text so you know how long it should be
>           var barText = toList.options[insertAt].text;
>           //insert the items at the end of the toList
>           for(var i=0; i<selItems.length; i++)
>           {
>             var oText = fromList.options[selItems[i]].text;
>             var oValue = fromList.options[selItems[i]].value;
>     var oTitle = fromList.options[selItems[i]].title // gsl fix
>             if(i == 0)
>             { //replace the bars
>               toList.options[insertAt].text = oText;
>               toList.options[insertAt].value = oValue;
>             }
>             else
>             {  //have to make new item
>               toList.options[insertAt] = new Option(oText, oValue, false, 
> false);
>             }
>     toList.options[insertAt].title = oTitle; // gsl fix
>             if ( toDescArray != (void 0) && fromDescArray != (void 0) )
>               toDescArray[insertAt] = fromDescArray[selItems[i]];
>             toList.options[insertAt].selected = true;
>             insertAt++;
>           }
>           //insert a new bar at bottom of toList
>           toList.options[insertAt] = new Option(barText, "", false, false);
>           toList.options[insertAt].selected = false;
>           //remove items from fromList.  do this backward to maintain indices
>           for( var i=selItems.length-1; i >= 0; i--)
>           {
>             if ( fromDescArray != (void 0) )
>               TrShuttleProxy._remove( fromDescArray, selItems[i], 1 );
>             fromList.options[selItems[i]] = null;
>           }
>           //make no selected on fromList
>           fromList.selectedIndex = -1;
>           TrShuttleProxy._clearDescAreas( formName, from);
>           TrShuttleProxy._displayDesc( to, formName );
>           //make the new lists for submitting.
>           TrShuttleProxy._makeList(formName, from);
>           TrShuttleProxy._makeList(formName, to);
>         }
>        
>     /*
>      * Overridden method to fix bug in generated code. gsl
>      * Remove this code when fix is incorporated into Trinidad.
>      * Should be incorporated by version 1.2.3.
>      *
>      * _moveAllItems
>      *
>      * This function moves all the items in the 'from' list to the
>      * 'to' list.  If no formName is supplied, the form is found when
>      * this is called.  The items are inserted in the 'to' list
>      * at the bottom. The 'from' and 'to' parameters should be the
>      * list names(i.e.  "<shuttleName>:leading" or "<shuttleName>:trailing")
>      */
>     TrShuttleProxy._moveAllItems = function(
>       from,
>       to,
>       formName
>       )
>     {
>       //get the formName is needed
>       if(formName == (void 0))
>       {
>         formName = TrShuttleProxy._findFormNameContaining(from);
>       }
>       //get the lists
>       var fromList = document.forms[formName].elements[from];
>       var toList = document.forms[formName].elements[to];
>       //save the bar text for later use.
>       var barText =
>         toList.options[document.forms[formName].elements[to].length-1].text
>       //get the index to start inserting at in the toList.  length-1 because 
> of
>       //bars
>       var insertAt = toList.length-1;
>       var fromDescArray = TrShuttleProxy._getDescArray(from);
>       var toDescArray = TrShuttleProxy._getDescArray(to);
>       //move the items
>       if (fromList.length > 1)
>       {
>         //move all but the last (bars).
>         var initialLength = fromList.length
>         for(var i=0; i<initialLength-1; i++)
>         {
>           var oText = fromList.options[0].text;
>           var oValue = fromList.options[0].value;
>     var oTitle = fromList.options[0].title // gsl fix
>           fromList.options[0] = null;
>           if(i == 0)
>           { //replace the bars
>             toList.options[insertAt].text = oText;
>             toList.options[insertAt].value = oValue;
>           }
>           else
>           { //make new option
>             toList.options[insertAt] = new Option (oText,oValue,false,false);
>           }
>     toList.options[insertAt].title = oTitle; // gsl fix
>           if ( toDescArray != (void 0) && fromDescArray != (void 0) )
>             toDescArray[insertAt] = fromDescArray[i];
>               insertAt++;
>         }
>         //insert a new bar:
>         toList.options[insertAt] = new Option(barText, "", false, false);
>         toList.options[insertAt].selected = false;
>         if ( fromDescArray != (void 0) )
>         {
>           var len = fromDescArray.length;
>           TrShuttleProxy._remove(fromDescArray, 0, len);
>         }
>         //set no selection on both lists
>         fromList.selectedIndex = -1;
>         toList.selectedIndex = -1;
>         TrShuttleProxy._clearDescAreas( formName, from, to );
>         //make the lists for submission
>         TrShuttleProxy._makeList(formName, from);
>         TrShuttleProxy._makeList(formName, to);
>       }
>       else if (_shuttle_no_items.length > 0)
>       {
>         alert(_shuttle_no_items);
>       }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to