Xpages是在视图中循环并进行更改的最佳方式

Xpages是在视图中循环并进行更改的最佳方式,xpages,Xpages,这个问题快把我逼疯了 我可以查看带有类别的文档。现在文档的顺序是任意的,但是我想为用户提供一种简单的方法来上下移动类别中的文档。因此,视图中有上/下箭头 我在箭头后面有SSJS代码,可以更改文档中的“订单”值,以便它们可以向上或向下移动(在我的pick中,任务字段显示订单) 我的问题是它间歇性地工作。我想原因是因为我在循环中时,文档的顺序正在改变。我尝试将视图上的自动更新设置设置为手动,但它似乎仍然不起作用 也许我是在走这条路去硬的。我真的只需要更改两个文档,一个是用户选择的文档,另一个是他们

这个问题快把我逼疯了

我可以查看带有类别的文档。现在文档的顺序是任意的,但是我想为用户提供一种简单的方法来上下移动类别中的文档。因此,视图中有上/下箭头

我在箭头后面有SSJS代码,可以更改文档中的“订单”值,以便它们可以向上或向下移动(在我的pick中,任务字段显示订单)

我的问题是它间歇性地工作。我想原因是因为我在循环中时,文档的顺序正在改变。我尝试将视图上的自动更新设置设置为手动,但它似乎仍然不起作用

也许我是在走这条路去硬的。我真的只需要更改两个文档,一个是用户选择的文档,另一个是他们将其移动到的文档。仅仅抓住这些可能会更简单吗

function mveItm(mveDir,mveCat,curOrd) {

    var curOrdStr:String = String(curOrd);
    var tarOrd:Integer;
    var tarOrdStr:String;
    var doc:NotesDocument;
    var lstOrd:Integer;
    var fstOrd:Integer;

    //Grab Collection In Order
    var tskView = database.getView("(dbAllPCTasksAutoUpdateFalse)");
    tskView.refresh();
    tskView.setAutoUpdate(false);

    var veCol:NotesViewEntryCollection = tskView.getAllEntriesByKey(mveCat);

    //Set First and Last Order Number
    var fstOrd = 10
    var lstOrd = veCol.getCount() * 10;

    //If the user has clicked move Higher on the last item 
    //or move down on the first, then ignore
    if (mveDir == "Lower" && fstOrd == curOrd) 
    {return}
    if (mveDir == "Higher" && lstOrd == curOrd) 
    {return}

    //Move Higher
    if (mveDir == "Higher") {

    //Set target order
    tarOrd = curOrd + 10;
    tarOrdStr = String(tarOrd);

    //Loop through viewEntryCollection and process
    var entry:NotesViewEntry = veCol.getFirstEntry();
    while (entry != null) {     

        doc = entry.getDocument()

        //Where are we in the loop
        var n:String = String(entry.getDocument().getItemValueInteger("order"));

        //If the number we are on matches the number that was selected to be changed
        //Change the current number to the target number 
        if (n == curOrdStr)
        {           
        print ("We are in order");
        print ("This is the one we are on..." + n);
        print ("This is the one we passed in..." + String(curOrdStr));
        print ("This is the target..." + String(tarOrd));
        doc.replaceItemValue("order",tarOrd);
        doc.save;   
        }

        //If the number we are on matches the number that was the target
        //Change the number we are on to the selected order number 
        if (n == tarOrdStr)
        { 
        doc.replaceItemValue("order",curOrd);
        doc.save;
        }

        var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
        entry.recycle();
        entry = tmpentry;
    }
    }

    //Move down
    if (mveDir == "Lower") {

        //Set target order
        tarOrd = curOrd - 10;
        tarOrdStr = String(tarOrd);

        //Loop through viewEntryCollection and add to DocumentCollection
        var entry:NotesViewEntry = veCol.getFirstEntry();
        while (entry != null) {

            doc = entry.getDocument()

            //Where are we in the loop
            var n:String = String(entry.getDocument().getItemValueInteger("order"));

            //If the number we are on matches the number that was selected to be changed
            //Change the current number to the target number 

            if (n == curOrdStr)
            {   
            //doc = entry.getDocument()
            doc.replaceItemValue("order",tarOrd);
            doc.save;   
            }

            //If the number we are on matches the number that was the target
            //Change the number we are on to the selected order number 
            if (n == tarOrdStr)
            //Change the current number to the target number and change everyone after that to -10
            //if (movDwn == true)
            { 
            doc.replaceItemValue("order",curOrd);
            doc.save;
            }

            var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
            entry.recycle();
            entry = tmpentry;

        }
    }   

    tskView.setAutoUpdate(true);
    tskView.refresh();

    //resetCategories(mveCat);
    return true;
}
我在这里发布我的完整解决方案。代码在最后,我将解释我做了什么来解决这个问题。感谢大卫和克努特·赫尔曼对我的帮助——请看克努特的帖子

我的问题如下:用户可以输入带有类别的文档(我的示例是“OS”和“软件”)。我希望用户可以通过重复控件中的箭头轻松地对其进行排序。他们还必须能够选择要删除的多个文档,并添加文档,并且顺序始终正确。为了更难,我为该类别设置了一个过滤器,以便用户可以看到所有类别或一个类别(该解决方案也适用于多个类别)

订单的实际更改并不太困难。我意识到我不必检查一个类别中的所有文档,只需获取用户选择的文档,以及下一个更高或下一个更低的文档(取决于他们想做什么),并交换位置。这一部分并不太难(参见库中的方法mveTsk)

困难的部分是确定是否显示向上或向下移动箭头。如果项目是第一个项目,则无法显示向下箭头;如果项目是最后一个项目,则无法显示向上箭头。此外,如果用户删除了一个项目或两个或三个项目,则必须对项目重新排序

我认为这是一个很好的解决方案,应该适用于许多不同的情况

============================

完整代码:

[无法输入所有代码]这是我认为最重要的

<?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"
    style="font-size:8pt">
    <xp:this.data>
        <xp:dominoView
            var="view1"
            viewName="(xpAllPCBuilds)" />
    </xp:this.data>
    <xp:this.resources>
        <xp:styleSheet
            href="/custom.css" />
    </xp:this.resources>
    <xp:this.beforePageLoad><![CDATA[#{javascript:viewScope.put("rows","5")}]]></xp:this.beforePageLoad>

    <xe:widgetContainer id="widgetContainerView" style="width:99.00%">

        <xp:panel>
            <xp:repeat
                id="repeat1"
                var="rowData"
                indexVar="repeatIndex"
                value="#{view1}"
            >
                <xp:this.facets>
                    <xp:text
                        disableTheme="true"
                        xp:key="header"
                        escape="false">
                        <xp:this.value><![CDATA[<table class='lotusTable repeatRowColors' border='0' cellspacing='0' cellpadding='0'>
<tr class ='lotusFirst lotusSort scope='col'>
<th></th>
<th class ='lotusBold'>Employee Name</th>
<th class ='lotusBold'>Computer</th>
<th class ='lotusBold'>Create Date</th>
<th class ='lotusBold'>Create User</th>
<th class ='lotusBold'>ID</th>
</tr>
</thead>]]>
                        </xp:this.value>
                        <xp:panel id="pagerPnlTop">
                            <xp:table
                                styleClass="lotusPaging lotusPagingTop"
                                style="width:100%">
                                <xp:tr>
                                    <xp:td styleClass="lotusLeft">
                                        <xp:panel
                                            themeId="Panel.left"
                                            styleClass="xspRowCount">


                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                            &#160;

                                        </xp:panel>
                                    </xp:td>
                                    <xp:td styleClass="lotusRight">


                                    </xp:td>
                                </xp:tr>
                            </xp:table>
                        </xp:panel>
                    </xp:text>
                    <xp:text
                        disableTheme="true"
                        xp:key="footer"
                        escape="false"
                    >
                        <xp:this.value>
                            <![CDATA[</table>]]></xp:this.value>
                        <xp:panel id="pagerPnlBottom">
                            <xp:table
                                styleClass="lotusPaging lotusPagingTop"
                                style="width:100%"
                            >
                                <xp:tr>
                                    <xp:td styleClass="lotusLeft">
                                        <xp:panel
                                            themeId="Panel.left"
                                            styleClass="xspRowCount"
                                        >
                                            <xp:label
                                                value="Show: "
                                                id="label1"
                                            />
                                            <xp:link
                                                text="5"
                                                id="link2"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 5)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 5;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label2"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="10"
                                                id="link3"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 10)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 10;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label3"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="25"
                                                id="link4"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 25)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 25;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label4"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="50"
                                                id="link6"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 50)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 50;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value="|"
                                                id="label5"
                                                themeId="Text.smallSeparator"
                                            />
                                            &#160;
                                            <xp:link
                                                text="100"
                                                id="link7"
                                            >
                                                <xp:this.style>
                                                    <![CDATA[#{javascript:if (viewScope.get("rows") == 100)
{return "color:#808080;font-weight:normal;"}
else
{return "font-weight:bold"}}]]>
                                                </xp:this.style>
                                                <xp:eventHandler
                                                    event="onclick"
                                                    submit="true"
                                                    refreshMode="complete"
                                                >
                                                    <xp:this.action>
                                                        <![CDATA[#{javascript:var numEntries = 100;
viewScope.rows = numEntries;
var dt = getComponent("repeat1"); 
if(dt != null && dt.getRowCount() > 0) { 
        dt.setFirst(0); 
}}]]>
                                                    </xp:this.action>
                                                </xp:eventHandler>
                                            </xp:link>
                                            &#160;
                                            <xp:label
                                                value=" entries"
                                                id="label6"
                                            />
                                        </xp:panel>
                                    </xp:td>
                                    <xp:td styleClass="lotusRight">
                                        <xp:pager
                                            xp:key="headerPager"
                                            layout="Previous Group Next"
                                            for="repeat1"
                                            id="pager5"
                                            style="font-weight:inherit"
                                            styleClass="pagerTopRight"
                                        />
                                    </xp:td>
                                </xp:tr>
                            </xp:table>
                        </xp:panel>
                    </xp:text>
                </xp:this.facets>
                <xp:this.rows><![CDATA[#{javascript:var rows:Integere = viewScope.get("rows");
if (rows == null)
{return 5}
else
{return rows}}]]></xp:this.rows>
                <xp:tr id="rowDataContainer">
                    <xp:td
                        style="width:20px;min-width:20px;max-width: 20px;"
                    >
                        <xc:ccRowSelectCheckBox
                            docID="#{javascript:rowData.getNoteID()}"
                            selectedClass="selectedRow"
                            containerID="rowDataContainer"
                        />

                    </xp:td>
                    <xp:td
                        style="width:200px;min-width:200px;max-width: 200px;"
                    >
                        <xp:link
                            escape="true"
                            id="link1"
                            value=""
                        >
                            <xp:this.text><![CDATA[#{javascript:rowData.getColumnValue("employeeName")}]]></xp:this.text>
                            <xp:eventHandler
                                event="onclick"
                                submit="true"
                                refreshMode="complete"
                            >
                                <xp:this.action>
                                    <xp:openPage
                                        name="xpFormPCBuild.xsp"
                                        target="openDocument"
                                    >
                                        <xp:this.documentId><![CDATA[#{javascript:rowData.getDocument().getUniversalID()}]]></xp:this.documentId>
                                    </xp:openPage>
                                </xp:this.action>
                            </xp:eventHandler>
                        </xp:link>
                    </xp:td>
                    <xp:td
                        style="width:75px;min-width:75px;max-width:75px;">
                        <xp:text
                            escape="true"
                            id="computedField2">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("computerName");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td
                        style="width:100px;min-width:100px;max-width:100px;">
                        <xp:text
                            escape="true"
                            id="computedField3">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("CrtDte");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td
                        style="width:150px;min-width:150px;max-width: 150px;">
                        <xp:text
                            escape="true"
                            id="computedField4">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("crtUsr");}]]>
                            </xp:this.value>
                        </xp:text>
                    </xp:td>
                    <xp:td>
                        <xp:text
                            escape="true"
                            id="computedField5">
                            <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("ID")}]]></xp:this.value>
                        </xp:text>
                    </xp:td>
                </xp:tr>
            </xp:repeat>
        </xp:panel>
    </xe:widgetContainer>

    </xp:view>

嗯,我认为有几种方法可以做到这一点。我没有确切的答案,但如果时间允许,我有兴趣进一步探索。 你不会说有多少文档或者排序顺序是什么。但是如果文档包含排序顺序的字段,那么你就可以很容易地进行操作,只需进行视图刷新。不过我假设这不是一个选项。 我相信java.util.ArrayList会控制插入对象的顺序。如果不是,那么可能是LinkedList。无论如何,如果你创建了一个列表,然后在视图中循环添加文档unid到列表中。那么理论上你就有了一个按视图顺序排列的unid列表。NotesViewNavigator和NotesViewEntry应该可以很快做到这一点。现在你可以我将其转换为一个repeat控件,从UNID获取文档,然后再获取您想要的任何其他值。 那么你会如何影响顺序呢?如果单元的列表在范围内,或者你只需要一个Java方法来“上移”或“下移”。我看到这个问题,它看起来像是一个Collections.swap方法。即使这不是答案,也一定有一些很酷的Java解决方案。 无论如何,这不是一个明确的答案,但也许有一些想法让你去追求


(请确保在获得最终解决方案后发布。)

您必须拥有SSJS解决方案还是基于Java的解决方案?我没有说我有什么,但我只是想知道。此外,我不明白为什么您要调用tskView.refresh()就在您获得视图之后。我看不出性能受到影响有任何意义…Java就可以了。至于刷新,只是为了确保在我的测试中刷新它。我会在生产中关闭它。我现在想知道如果根本不做循环是否会简单得多。用户正在移动当前文档(他们点击箭头的那个)向上或向下。抓取当前文档,然后抓取上一个文档或下一个文档,这取决于他们选择的是向下箭头还是向上箭头。只需交换两个文档的顺序并保存。也许这就是解决方法?Dave我仍在研究我的解决方案,完成后会发布,或者如果无法解决问题,会与您联系,但我想我也是这样戴夫,我找到了一个我认为非常好的解决方案,并把它贴在上面。
var validateForm = function()
{
var valid = true;
var control;
var control2;
var val;
var val2;

REMOVED business code

function mveTsk(mveDir,pckCat,pckOrd) {

    //OK I am assuming we are only moving something that we can move

    //Set variables
    var pckDoc:NotesDocument;
    var trgDoc:NotesDocument;
    var trgOrd:Integer;
    var tskView = database.getView("(dbAllPCTasksLookup)");
    var key:String = createKey(pckCat,pckOrd);

    //Get the chosen doc
    var query = key;    
    var pckDoc = tskView.getDocumentByKey(query);

    //Get the current order
    var curOrd:Integer = pckDoc.getItemValueInteger("order");

    //Get doc depending on whether we are moving higher or lower
    if (mveDir == "Lower")
        {query = createKey(pckCat,pckOrd-1); 
        var trgDoc = tskView.getDocumentByKey(query);
        pckDoc.replaceItemValue("order",curOrd-1)
        pckDoc.replaceItemValue("key",createKey(pckCat,curOrd-1))
        trgOrd = trgDoc.getItemValueInteger("order");
        trgOrd += 1;
        trgDoc.replaceItemValue("order",trgOrd)
        trgDoc.replaceItemValue("key",createKey(pckCat,trgOrd))}
    else
        {query = createKey(pckCat,pckOrd+1); 
        print (query);
        var trgDoc = tskView.getDocumentByKey(query);   
        pckDoc.replaceItemValue("order",curOrd+1)
        pckDoc.replaceItemValue("key",createKey(pckCat,curOrd+1))
        trgOrd = trgDoc.getItemValueInteger("order");
        trgOrd -= 1;
        trgDoc.replaceItemValue("order",trgOrd)
        trgDoc.replaceItemValue("key",createKey(pckCat,trgOrd))}

    pckDoc.save();
    trgDoc.save();
    resetCategories(pckCat);

    return 
}

function resetCategories (rstCat)
{
    var tskView = database.getView("(dbAllPCTasks)");
    var veCol:NotesViewEntryCollection = tskView.getAllEntriesByKey(rstCat);
    var veCnt = veCol.getCount();
    var curCnt:Integer;
    var tmpDoc:NotesDocument;
    var curOrd:Integer;
    var chgOrd:Integer = 0;
    var doc:NotesDocument

    print (String(veCnt));

    //We have no records so get out
    if (veCnt == 0) {
        return;
    }

    //We have one record, so set this record and get out
    if (veCnt == 1) {
        var entry:NotesViewEntry = veCol.getFirstEntry();
        doc = entry.getDocument()
        doc.replaceItemValue("order",1);
        doc.replaceItemValue("key",createKey(rstCat,1));
        doc.save();
        return;
    }

    //We have one first and one last record, so set these two records and get out
    if (veCnt == 2) {

        //First Entry
        var entry:NotesViewEntry = veCol.getFirstEntry();
        doc = entry.getDocument()
        doc.replaceItemValue("order",1);
        doc.replaceItemValue("key",createKey(rstCat,1));
        doc.save();

        //Second Entry
        var entry:NotesViewEntry = veCol.getNextEntry(entry);
        doc = entry.getDocument()
        doc.replaceItemValue("order",2);
        doc.replaceItemValue("key",createKey(rstCat,2));
        doc.save();
        return;
    }

    //Else we have 3 or more so go through the loop

    print  ("we have more");

    curCnt = 1
    var entry:NotesViewEntry = veCol.getFirstEntry();   
    while (entry != null) {

        doc = entry.getDocument()

        print (String(curCnt));

        //We are the first record
        if (curCnt == 1) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        //We are the last record
        if (curCnt == veCnt) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        //We are neither first nor last; inbetween record
        if ( (curCnt != 1) && (curCnt != veCnt)) {
            doc.replaceItemValue("order",curCnt);
            doc.replaceItemValue("key",createKey(rstCat,curCnt));
            doc.save();
        }

        var tmpentry:NotesViewEntry = veCol.getNextEntry(entry);
        entry.recycle();
        entry = tmpentry;

        curCnt = curCnt + 1
    }

    return
}


    function orderToString (tmpOrd)
    {

        keyString:String        
        tmpOrdStr:String = tmpOrd

        if (len(tmpOrdStr == 1))
        {keyString = "00" + tmpOrdStr;}

        if (len(tmpOrdStr == 2))
        {keyString = "0" + tmpOrdStr;}

        if (len(tmpOrdStr == 3))
        {keyString = tmpOrdStr;}

        return keyString
    }