private void _renderMultiItemNavigator()

in trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/ui/laf/base/xhtml/NavigationBarRenderer.java [692:1144]


  private void _renderMultiItemNavigator(
    UIXRenderingContext context,
    UINode navBar,
    int    blockSize,
    String eventKey,
    String sourceKey,
    String valueKey,
    String sizeKey,
    String partialTargetsKey,
    String partialTargets
    )
    throws IOException
  {
    // get current value
    Number result = (Number)navBar.getAttributeValue(context,
                                                     VALUE_ATTR);
    long currentValue = (result != null)
                          ? result.longValue()
                          : 1;

    // get min value
    result = (Number)navBar.getAttributeValue(context, MIN_VALUE_ATTR);
    long minValue = (result != null)
                       ? result.longValue()
                       : 1;

    // get max value
    result = (Number)navBar.getAttributeValue(context, MAX_VALUE_ATTR);
    long maxValue = (result != null)
                       ? result.longValue()
                       : MAX_VALUE_UNKNOWN;

    // get destination
    String destinationString = _getDestinationString(context, navBar);

    // get name
    String nameString = _getNameString(context, navBar);


    // get form name (#1308799)
    String formName = XhtmlLafUtils.getParentFormName(context);

    int  nextRecords = 0;
    int  backRecords = 0;
    long backValue = 0;
    long nextValue = 0;

    if (blockSize > 0)
    {
      // determine how many records user can go forward
      long lNextRecords = blockSize;

      if (maxValue != MAX_VALUE_UNKNOWN)
      {
        // if we know the total records, align the current value to the
        // start of its block. This makes the choice-rendering style
        // not show extra back navigation records on the min block,
        // which it would if not aligned.

        /** no don't do this. see bug: 3052637
        currentValue -= minValue;
        currentValue /= blockSize;
        currentValue *= blockSize;
        currentValue += minValue;
        */

        lNextRecords = maxValue - (currentValue + blockSize - 1);
      }

      // determine how many records user can go back
      long lBackRecords = currentValue - minValue;

      // trim
      nextRecords = (lNextRecords > blockSize)
        ? blockSize
        : (int) lNextRecords;

      backRecords = (lBackRecords > blockSize)
        ? blockSize
        : (int) lBackRecords;

      backValue = currentValue - backRecords;
      nextValue = currentValue + blockSize;
    }

    // calculate destinations
    String prevDestination = null;
    String nextDestination = null;
    String prevOnClick     = null;
    String nextOnClick     = null;

    UINode leftArrow  = null;
    UINode rightArrow = null;
    UINode leftLink   = null;
    UINode rightLink  = null;

    boolean validate = false;
    boolean createSubmitButton = false;

    boolean showDisabledNavigation = disabledNavigationShown(context);
    boolean hasBackRecords = (backRecords > 0);
    boolean hasNextRecords = (nextRecords > 0);

    boolean showBackButton = hasBackRecords || showDisabledNavigation;
    boolean showNextButton = hasNextRecords || showDisabledNavigation;
    if (!supportsNavigation(context))
    {
      showBackButton = false;
      showNextButton = false;
    }

    Object showAll = navBar.getAttributeValue(context, SHOW_ALL_ATTR);
    boolean atShowAll = SHOW_ALL_ACTIVE.equals(showAll);
    if (atShowAll)
    {
      backRecords = 0;
      nextRecords = 0;
    }

    if (formName == null)
    {
      // use parameterized URLs
      if (hasBackRecords && !atShowAll)
      {
        prevDestination = _getMultiDestinationURL(destinationString,
                                                  eventKey,
                                                  sourceKey,
                                                  nameString,
                                                  valueKey,
                                                  backValue,
                                                  sizeKey,
                                                  partialTargetsKey,
                                                  backRecords,
                                                  partialTargets);

        if (partialTargets != null)
        {
          // If we're doing partial page rendering, we need to
          // generate the _firePartialChange() onclick handler
          prevOnClick = XhtmlLafUtils.getFirePartialChangeHandler(
                                        prevDestination);
          prevDestination = "#";
        }
      }

      if (hasNextRecords && !atShowAll)
      {
        nextDestination = _getMultiDestinationURL(destinationString,
                                                  eventKey,
                                                  sourceKey,
                                                  nameString,
                                                  valueKey,
                                                  nextValue,
                                                  sizeKey,
                                                  partialTargetsKey,
                                                  nextRecords,
                                                  partialTargets);

        if (partialTargets != null)
        {
          // If we're doing partial page rendering, we need to
          // generate the _firePartialChange() onclick handler
          nextOnClick = XhtmlLafUtils.getFirePartialChangeHandler(
                                        nextDestination);
          nextDestination = "#";
        }
      }
    }
    else
    {
      // determine whether we need to validate on submit
      validate = _doValidate(context, navBar);

      // use form submit
      if (supportsScripting(context))
      {
        if (hasBackRecords && !atShowAll)
        {
          prevDestination = "#";
          prevOnClick = _getMultiDestinationSubmit(context,
                                                   formName,
                                                   eventKey,
                                                   sourceKey,
                                                   nameString,
                                                   valueKey,
                                                   backValue,
                                                   sizeKey,
                                                   backRecords,
                                                   validate,
                                                   partialTargetsKey,
                                                   partialTargets);
        }

        if (hasNextRecords && !atShowAll)
        {
          nextDestination = "#";
          nextOnClick =  _getMultiDestinationSubmit(context,
                                                    formName,
                                                    eventKey,
                                                    sourceKey,
                                                    nameString,
                                                    valueKey,
                                                    nextValue,
                                                    sizeKey,
                                                    nextRecords,
                                                    validate,
                                                    partialTargetsKey,
                                                    partialTargets);
        }

        // render hidden fields to hold the form data
        if (hasBackRecords || hasNextRecords)
          renderHiddenFields( context,
                              formName,
                              true,
                              eventKey,
                              sourceKey,
                              valueKey,
                              sizeKey,
                              partialTargetsKey,
                              partialTargets);
      }
      else
      {
        // create submit buttons to handle submission
        createSubmitButton = true;
      }
    }

    //
    // create the anonymous link nodes
    //
    if (createSubmitButton)
    {
      if (showBackButton)
      {
        // create back submit button bean
        leftArrow = createSubmitButton(context,
                                        _getMultiSubmitButtonText(context,
                                                                  true,
                                                                  backRecords),
                                        null,
                                        null,
                                        formName,
                                        validate,
                                        eventKey,
                                        sourceKey,
                                        nameString,
                                        valueKey,
                                        backValue,
                                        sizeKey,
                                        backRecords);
      }

      // create next submit button bean
      if (showNextButton)
      {
        rightArrow = createSubmitButton(context,
                                         _getMultiSubmitButtonText(context,
                                                                  false,
                                                                  nextRecords),
                                         null,
                                         null,
                                         formName,
                                         validate,
                                         eventKey,
                                         sourceKey,
                                         nameString,
                                         valueKey,
                                         nextValue,
                                         sizeKey,
                                         nextRecords);
      }
    }
    else
    {
      if (showBackButton)
      {
        leftArrow  = _createArrowImage(context,
                                       true,
                                       prevDestination,
                                       prevOnClick);

        leftLink   = _createTextLink(context,
                                     navBar,
                                     true,
                                     prevDestination,
                                     prevOnClick,
                                     backRecords);
      }

      if (showNextButton)
      {
        rightArrow = _createArrowImage(context,
                                       false,
                                       nextDestination,
                                       nextOnClick);

        rightLink  = _createTextLink(context,
                                     navBar,
                                     false,
                                     nextDestination,
                                     nextOnClick,
                                     nextRecords);

      }
    }

    UINode rangeNode  = _createRangeNode(context,
                                         navBar,
                                         destinationString,
                                         nameString,
                                         formName,
                                         minValue,
                                         currentValue,
                                         blockSize,
                                         maxValue,
                                         eventKey,
                                         sourceKey,
                                         sizeKey,
                                         partialTargetsKey,
                                         partialTargets);

    // ready to render
    ResponseWriter writer = context.getResponseWriter();
    boolean renderAsTable = _renderAsTable(context, navBar);



    // The following strange code is part of the work around for
    // bug 2275703.  IE has problems re-laying out a TableBean
    // after a partial page replacement.  In particular, pieces
    // of the table's top navigation bar, such as the previous link
    // or icon, or sometimes the entire navigation bar,  may shift to
    // the left.  In some cases, pieces of the navigation bar (the previous
    // icon) may disappear during re-layout!  There doesn't seem to be
    // any clean way to avoid this apparent IE bug.  However, we explicitly
    // pareform a partial replacement of the navigation bar's previous icon
    // *after* the entire table has been replaced, everything seems to lay
    // out just fine.
    //
    // So, if we are rendering a TableBean's navigation bar with
    // PPR enabled on IE, then we generate an ID for the nav bar's
    // previous icon, and we add this to the list of rendered partial
    // targets during the partial page render.  This forces the icon
    // to be replaced as part of the partial page update, and fixes
    // our layout problems.
    String iconID = null;
    Object id = (supportsID(context) ? getID(context, navBar) : null);
    TrinidadAgent agent = context.getAgent();

    if ((id != null) &&
        (partialTargets != null) &&
        (agent.getAgentApplication() == TrinidadAgent.Application.IEXPLORER))
    {
      iconID = id.toString() + "-i";
    }

    // if we need to render standalone, create a table and table row...
    if (renderAsTable)
    {
      writer.startElement("table", null);
      renderLayoutTableAttributes(context, "0", null);

      // We should always render the ID, but we particularly need
      // to make sure that the ID is rendered if the NavBar is being
      // used to navigate a TableBean, since we explicitly target
      // TableBean NavBars when using PPR to re-render TableBeans...
      renderID(context, navBar);
      writer.startElement("tr", null);
    }

    // we only want to render the baseID, if needed, once. Then we
    // render the subIDs. So we need to keep track of this.
    boolean isBaseID = true;
    if (leftArrow != null)
    {
      // We assign an id to the left arrow so that we can target it as
      // a partial target to work around bug 2275703 - see note above.
      if (iconID != null)
      {
        writer.startElement("td", null);
        renderAttribute(context, "id", iconID);

        // If the navigation bar that we are currently rendering
        // is included in a partial page response, add the icon
        // id to the list of partial targets.
        PartialPageContext pprContext = context.getPartialPageContext();
        if ((pprContext != null) &&
            pprContext.isInsidePartialTarget())
        {
          pprContext.addRenderedPartialTarget(iconID);
        }
      }
      else
      {
        // not in PPR mode, so just render the td (and id if not in a table
        // for the Visual Editor)
        _renderStartTableCell(context, navBar, writer, renderAsTable, isBaseID);
        isBaseID = false;
      }

      writer.writeAttribute(VALIGN_ATTRIBUTE, "middle", null);
      leftArrow.render(context);
      writer.endElement("td");
      _renderSpacerCell(context);
    }

    if (leftLink != null)
    {
      _renderStartTableCell(context, navBar, writer, renderAsTable, isBaseID);
      isBaseID = false;
      writer.writeAttribute(VALIGN_ATTRIBUTE, "middle", null);
      writer.writeAttribute(NOWRAP_ATTRIBUTE, Boolean.TRUE, null);
      leftLink.render(context);
      writer.endElement("td");
      _renderSpacerCell(context);
    }

    _renderStartTableCell(context, navBar, writer, renderAsTable, isBaseID);
    isBaseID = false;
    writer.writeAttribute(VALIGN_ATTRIBUTE, "middle", null);
    writer.writeAttribute(NOWRAP_ATTRIBUTE, Boolean.TRUE, null);
    rangeNode.render(context);
    writer.endElement("td");

    if (rightLink != null)
    {
      _renderSpacerCell(context);

      _renderStartTableCell(context, navBar, writer, renderAsTable, false);
      writer.writeAttribute(VALIGN_ATTRIBUTE, "middle", null);
      writer.writeAttribute(NOWRAP_ATTRIBUTE, Boolean.TRUE, null);
      rightLink.render(context);
      writer.endElement("td");
    }

    if (rightArrow != null)
    {
      _renderSpacerCell(context);

      _renderStartTableCell(context, navBar, writer, renderAsTable, false);
      writer.writeAttribute(VALIGN_ATTRIBUTE, "middle", null);
      rightArrow.render(context);
      writer.endElement("td");
    }

    if (renderAsTable)
    {
      writer.endElement("tr");
      writer.endElement("table");
    }
  }