【问题标题】:compute styleClass for button in repeat control计算重复控件中按钮的 styleClass
【发布时间】:2015-09-03 14:09:34
【问题描述】:

我在 xp:repeat 控件中有一个 xp:button 控件。我想计算按钮的 styleClass 属性,所以我通过将“活动”添加到 styleClass 来确定我点击了哪个。

不幸的是,当我在 viewScope 变量中设置活动 ID(所选按钮的 ID)并将其与它们区分的 styleClass 中计算的 ID 进行比较时。

不同之处在于 viewScope 中 ID 的值似乎包含一个额外的迭代器值,例如

查看:_id1:_id81:repeat2:0:button2 或 查看:_id1:_id81:repeat2:1:button2

样式类中的计算值不是例如

查看:_id1:_id81:repeat2:button2

最后一个 ID 值对于所有其他按钮都是相同的。

用于计算我使用的 ID 值:

getComponent("button2").getClientId(facesContext)

正如 Tim Tripcony Getting the clientId of an XPages button programmatically 所说的

我做错了什么或者如何在 SSJS 中正确计算 styleClass 属性?

【问题讨论】:

  • 请添加计算 ID 和计算 styleClass 的完整源代码,特别是在何时何地触发。更改与时间有关,并且组件树仅包含一组用于重复的控件,这些控件在运行时迭代。
  • var myID:String = getComponent("button2").getClientId(facesContext); var activeID:String = sessionScope.get("btnSubRActive"); if (activeID == myID){ return "btn btn-responsive btn-marginb active"; } else{ return "btn btn-responsive btn-marginb not-active"; }
  • 为什么不使用服务器生成的ID(“button2”)?每次部分刷新或任何刷新(Xpages 上的每次更改)都可以为所有控件生成新的客户端 ID。

标签: xpages xpages-ssjs


【解决方案1】:

不要使用客户端 ID。使用重复索引来记住点击了哪个按钮。

<xp:repeat
    id="repeat1"
    rows="30"
    value="..."
    indexVar="index">
    <xp:button
        value="Label"
        id="button1"
        styleClass="#{javascript:
            'yourClass' + (viewScope.buttonPressed == index ? 'Active' : '')}">
        <xp:eventHandler
            event="onclick" submit="true"
            refreshMode="partial" refreshId="repeat1">
            <xp:this.action><![CDATA[#{javascript:
                viewScope.buttonPressed = index}]]></xp:this.action>
        </xp:eventHandler>
    </xp:button>
</xp:repeat>

【讨论】:

  • 对,这就是我的想法 :) 虽然我会使用 requestScope,因为 viewScope 可能会使“活动”存活太久。另一方面,也许不是……
  • 刚刚测试过:requestScope 也可以正常工作。您在问题中提到了 viewScope,所以我使用了这个:-)
  • 这不是 我的 问题,我刚刚发布了另一个答案(从你的 :D 中看到一个)。但你是对的:最初的问题提到了 viewScope。,之前没有注意到
  • Ups,@Lothar,你是对的。这不是你的问题... :D
  • 嗨克努特,你测试过这个吗?我无法在驻留在中继器中的按钮的 styleClass 属性中访问重复控件的 indexVar 属性。 ([ReferenceError] 'index' not found )。但是,我可以在该按钮的其他属性中使用 indexVar 属性。你对此有什么解释吗?
【解决方案2】:

写完第一个答案后,我就回家了。在我的路上,我仔细考虑了这一点,并认为我找到了一个相当简单的解决方案;因为我认为其他答案中的一些想法可以帮助理解我的解决方案建议,所以我将其保持不变并创建这个新的。您可以尝试以下方法:

为中继器的 indexVar 属性添加一个值,例如rIndex(您可以在所有属性下找到它)

假设要激活的按钮必须由用户单击,您可以像这样将一些 SSJS 代码添加到其 onclick 事件中,以便将当前 indexVar 值存储在 requestScope 变量中:

requestScope.put("activeIndex", rIndex)

确保 onclick 对包含重复控件的容器执行部分刷新

创建代码来计算重复按钮的样式类;如果重复的迭代索引是存储在 requestScope 中的索引,则分配一个样式类,否则分配另一个:

if(rIndex==requestScope.get("activeIndex")){
  "btnStyleActive";
}else{
  "btnStyleInactive";
}

因为 onclick 部分刷新了转发器及其内容,所以应用了正确的样式类。

我家里没有 Domino Designer,所以我无法尝试,但我觉得这一定行得通。

更新: 刚刚构建了我自己的解决方案,与 Knut 的 sn-p 非常相似,并且运行良好;没有运行时错误。为了完整起见,我向转发器添加了一个入口变量 (var="rEntry"),但您可能不需要它。

我将发布我页面的 xml 代码,以便您可以复制粘贴并尝试:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:this.resources>
        <xp:styleSheet href="/test.css"></xp:styleSheet>
    </xp:this.resources>
    <xp:panel id="pnMainContainer">
        <xp:repeat
            id="repeat1"
            rows="30"
            indexVar="rIndex"
            var="rEntry">
            <xp:this.value><![CDATA[#{javascript:[1, 2, 3, 4, 5]}]]></xp:this.value>
            <xp:panel id="pnRptInner">
                <xp:label id="label1">
                    <xp:this.value><![CDATA[#{javascript:"Entry content for this iteration = "+ rEntry.toString() + " "}]]></xp:this.value>
                </xp:label>
                <xp:button id="button1">
                    <xp:this.value><![CDATA[#{javascript:"Repeated Button @ index #" + rIndex.toString()}]]></xp:this.value>
                    <xp:this.styleClass><![CDATA[#{javascript:if(requestScope.get("activeIndex")==rIndex){
    "btnStyleActive";
}else{
    "btnStyleInactive";
}}]]></xp:this.styleClass>
                    <xp:eventHandler
                        event="onclick"
                        submit="true"
                        refreshMode="partial" refreshId="pnMainContainer">
                        <xp:this.action><![CDATA[#{javascript:requestScope.put("activeIndex", rIndex)}]]></xp:this.action>
                    </xp:eventHandler></xp:button>
            </xp:panel>
        </xp:repeat>
    </xp:panel>
</xp:view>

为了使它完整,这里是一个非常简单的 css:

.btnStyleInactive{color:blue;}
.btnStyleActive{color:red;};

确保:

  • 按钮的 onclick 对中继器本身执行部分更新 或周围的容器
  • onclick 代码是 SSJS

【讨论】:

  • 正如其他回复中提到的:我无法使用位于重复控件中的按钮的 styleClass 属性访问重复控件的 indexVar 属性:-/
  • 我试试看; Knut 的代码 sn-p 正是我想到的,但我没有测试它。今天晚些时候可以这样做。同时,请发布有关您的环境(服务器和设计器版本等)的一些详细信息。我不希望在服务器版本之间找到任何差异,但你永远不知道......
  • 刚刚试过,效果很好。我在上面的答案中添加了详细信息
【解决方案3】:

您不能依赖静态资源(如 styleSheet)中的控件 ID,因为这些 ID 总是被计算出来的。向您的 xpage 添加更多组件,所有控件都可能收到新的 id。出于这个原因,我严格避免在我的 styleSheets 中使用 id。

我不能 100% 确定我是否理解您在此处尝试执行的操作,因此以下解决方案可能与您无关;反正我会试试的:

  1. 尝试在你的 CSS 中使用伪标识符,例如

    div.myRepeaterClass button:active{whatever: 然而;}

  2. 使用包含转发器的 indexVar 的计算样式类;为此,您需要为重复控件的 indexVar 属性命名,例如 rIndex。然后您的按钮的 styleClass 可以呈现为

    styleClass="#{javascript:"myBtnClass_" + rIndex.toString()}"

这样你的按钮至少有独特的 styleClasses

  1. 这可能是最复杂的一个,以防其他都不起作用:您可能知道css也可以使用各种控件属性作为参考;假设你有一个标准的 html 元素,并且你的 css 可以是 title 属性

    [title=myElementTitle]{无论如何:然而;}

对于 Xpage 控件,您可以使用通用属性属性:您会在“所有属性>>基础知识”下找到一个元素“attrs" 适用于大多数控件。在这里,您可以添加您自己的自定义属性 - 值对,然后您可以从您的 styleSheet 中引用它们。如有必要,您可以编写一些操作该自定义属性的 onClick 代码。示例:

创建一个自定义属性myRepeatBtn,其值为btnInactive。然后编写 JS 代码将该值更改为 btnActive。你的 CSS 可以使用这个选择器:

[myRepeatBtn=btnActive]{whatever: however;}

部分刷新将导致 css 对该更改做出反应

希望这个面具有意义;) 祝你好运。

【讨论】:

  • 嗨洛萨。我注意到我的重复控件的 indexVar 可用于按钮标签,但不适用于 styleClass 属性( [ReferenceError] 'idx' not found )。我通过添加自定义属性对其进行了测试,然后相同的 indexVar 属性再次可用。怎么样?
【解决方案4】:

或者,从按钮将条目的 NoteID 写入 viewScope 变量并根据该变量计算类。我假设有一些后续处理需要完成,在这种情况下 NoteID 将非常有用。

这是我在很多场合都使用过的技术,例如启用/禁用“in view edit”的可编辑字段。

【讨论】:

    【解决方案5】:

    在中继器中,“var”可以在很多地方使用,但无论出于何种原因,都不能用于计算 styleClass。

    以下解决方法有效: 使用标准 div, span, ... 而不是 xp:div, xp: span ... 然后您可以计算类。 (请注意编写有效的 javascript,因为没有编辑器支持)

    代码如下所示:

    <xp:repeat
        id="repeat1"
        value="objList"
        var="obj">
        <span class="#{javascript:return (obj.Condition) ? 'class1' : 'class2';}">
            <xp:button
                value="obj.Name"
                id="button1"
                styleClass="btn">
                <xp:eventHandler
                    event="onclick" submit="true"
                    refreshMode="partial" refreshId="repeat1">
                    <xp:this.action>
                    ...
                    </xp:this.action>
                </xp:eventHandler>
            </xp:button>
        </span>
    </xp:repeat>
    

    css 取决于父元素类:

        ....
    .class1 .btn{
        text-align: left;
    }
    
    .class2 .btn{
        text-align: right;
    }
    
        ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      相关资源
      最近更新 更多