javascript - Xpages:包含多个相同自定义控件的页面不唯一

标签 javascript xpages custom-controls

我为美国货币的输入文本框创建了一个很好的自定义控件。我希望能够多次将此 CC 放在页面上,因此我将字段名称设为属性。如果页面上有一个控件,则一切似乎都可以正常工作,但如果有多个控件,则 CC 中的代码将无法按预期工作。我正在尝试在 CC 内的 CSJS 中进行一些验证和编辑,并尝试在这样做时获取唯一的计算 ID。但它不起作用 - 第一个值覆盖第二个值,并且会发生其他奇怪的事情。

我的代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <xp:view
        xmlns:xp="http://www.ibm.com/xsp/core"
        xmlns:xc="http://www.ibm.com/xsp/custom"
        xmlns:xe="http://www.ibm.com/xsp/coreex"
        createForm="false">
        <style> .errorRed{ border: 2px solid red; }</style>
        <xp:inputText
            id="curText1"
            value="#{viewScope.a}"
            styleClass="pull-right"
            style="width:200px;text-align:right"
            defaultValue="0.00">
            <xp:this.converter>
                <xp:convertNumber
                    type="currency"></xp:convertNumber>
            </xp:this.converter>
            <xe:this.dojoAttributes>
                <xp:dojoAttribute
                    name="input"
                    value="text-align: right">
                </xp:dojoAttribute>
            </xe:this.dojoAttributes>
            <xp:eventHandler
                event="onchange"
                submit="false">
                <xp:this.script><![CDATA[//Set some things

    var thisID  = '#{javascript:getClientId("curText1")}';
    var thisCmp = XSP.getElementById(thisID);
    var thisVal = XSP.getElementById(thisID).value;

    //Error if this is not a number
    if (isNaN(thisVal)) 
    {thisCmp.className = thisCmp.className + " errorRed";
    return}
    else
    {thisCmp.className = thisCmp.className.replace(" errorRed","")}

    //Must remove $ and any commas
    y = thisVal.replace(',','');
    z = y.replace('$','');

    //Must fix to 2 decimal places
    if ((typeof z) === 'string'){
        z = parseFloat(z).toFixed(2)}
    else {
        z = z.toFixed(2)
    }   

    //Now put it back in the field
    thisID.value = parseFloat(z);
    XSP.partialRefreshPost(thisID);]]></xp:this.script>
            </xp:eventHandler>
        </xp:inputText>
    </xp:view>


I am adding my modified code:

Custom Control:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    createForm="false">
    <style>.errorRed{ border: 2px solid red; }</style>  
    <xp:scriptBlock
        id="scriptBlock1"
        type="text/javascript">
        <xp:this.value><![CDATA[formatNumber = function(thisID) {
var thisCmp = XSP.getElementById(thisID);
var thisVal = XSP.getElementById(thisID).value;

//Must remove currency symbol and any commas
y = thisVal.replace(',','');
z = y.replace('$','');

//Error if this is not a number
if (isNaN(z)) 
{thisCmp.className = thisCmp.className + " errorRed";
return}
else
{thisCmp.className = thisCmp.className.replace(" errorRed","")}

//Must fix to 2 decimal places
if ((typeof z) === 'string')
{z = parseFloat(z).toFixed(2)}
else    
{z = z.toFixed(2)}  

//Now put it back in the field
thisID.value = parseFloat(z);
XSP.partialRefreshPost(thisID,{execId:thisID, immediate: true});

}]]></xp:this.value>
    </xp:scriptBlock>
    <xp:inputText
        id="curText1"
        styleClass="pull-right"
        style="width:200px;text-align:right"
        defaultValue="0.00"
        value="#{compositeData.price}">
        <xp:this.converter>
            <xp:convertNumber
                type="currency"
                currencySymbol="$">
            </xp:convertNumber>
        </xp:this.converter>
        <xp:this.dojoAttributes>
            <xp:dojoAttribute
                name="input"
                value="text-align: right">
            </xp:dojoAttribute>
        </xp:this.dojoAttributes>
        <xp:eventHandler
            event="onblur"
            submit="false">
            <xp:this.script><![CDATA[var thisID = '#{javascript:getClientId("curText1")}';
formatNumber(thisID);]]></xp:this.script>
        </xp:eventHandler>
    </xp:inputText>

    <xp:inputText>
        <xp:this.value><![CDATA[#{javascript:{"${"+compositeData.bla+"}"}}]]></xp:this.value>
    </xp:inputText>
</xp:view>

这是 Xpage 的代码,带有 2 个自定义控件:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex"
    xmlns:xc="http://www.ibm.com/xsp/custom">

    <xp:panel>
        <xp:this.data>
            <xe:objectData
                var="doc">
                <xe:this.createObject><![CDATA[#{javascript:var doc = new com.scoular.model.Project();

var unid = sessionScope.get("key");

if (unid != null) {
    doc.loadByUnid(unid);
} else {
    doc.create();
}

sessionScope.put("key",null);

return doc;}]]></xe:this.createObject>
            </xe:objectData>
        </xp:this.data>
        </xp:panel>

    <xp:panel id="numbers">
        <xc:cc_CommonInputCurrency2
            field="total1"
            bla="#{doc.prjAmtColumn11}">
        </xc:cc_CommonInputCurrency2>
    </xp:panel>

        <xp:panel id="panel1">
        <xc:cc_CommonInputCurrency2
            field="total2"
            bla="#{doc.prjAmtColumn12}">
        </xc:cc_CommonInputCurrency2>
    </xp:panel>

</xp:view>

最佳答案

您的 value 属性绑定(bind)为 viewscope.a 。在渲染阶段,该范围只有一个和一个值,因此所有字段都绑定(bind)回相同的值。 更好的方法是在自定义控件中使用参数来提供值。所以你会得到类似 <cc:moneyControl bla="document1.price"> 的内容 然后使用一个隐藏 CSS 属性的字段并将其绑定(bind)到 #{"${"+compositeData.bla+"}"}并让您的道场更新该字段。节省您的服务器行程并在 CC 之外拥有额外的字段。 它是如何工作的: $ 首先被评估一次,并形成任何有效的数据源,而不仅仅是文档。

希望有帮助

关于javascript - Xpages:包含多个相同自定义控件的页面不唯一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38960341/

相关文章:

javascript - 在 useEffect 中使用 reducer 状态

javascript - 有 JavaScript strcmp() 吗?

javascript - 基于 ids 数组有效循环对象

Xpages 搜索显示文档和响应

javascript - XPage 和加载 JavaScript 文件

ios - 自定义 slider 响应缓慢

javascript - 如何用javascript自动执行搜索功能?

html - 如何阻止富文本字段中的 CSS 覆盖文档

iphone - 将自定义 UI 对象 (UISwitch) 添加到 iOS 项目

visual-studio - 如何在Visual Studio表单设计器中呈现.NET Compact Framework自定义控件的位图属性?