カスタムJSLinkレンダリングテンプレート - どのようにAjaxページングを作業しますか?

sharepoint.stackexchange https://sharepoint.stackexchange.com//questions/77262

  •  10-12-2019
  •  | 
  •  

質問

この投稿カスタムJSlinkレンダリングテンプレートでページングを実装して手に入れたそれは素晴らしいうちに動作します。そのための唯一の欠点は、ページングアクションがフルページの後退であるのに対し、Stock SP List Web-PartではAjaxを使用します。 MSコードを掘り下げた後、私はPaging呼び出しがRefreshPageToへの呼び出しで折り返されていたことがわかった。これを採用した後はまだAjaxページングが得られません。

MSスクリプトINPLVIEW.jsでは、マークアップがどのように装飾されているか、およびそれらがclvpと呼ばれるプロパティが、外部レンダリングブロックHTML要素のいずれかに追加されたプロパティのようです。どういうわけか私のテンプレートマークアップブロックをajaxifyに呼び出すことができるJSメソッドでなければならないようです。

私の質問は、カスタムJSLinkレンダリングテンプレートでAjaxページングをどのように実装することができますか? 以下のこのシンプルなテンプレートはAjaxページングで動作するはずですが、そうではありません。

window.MyNewsList = window.MyNewsList || {};
window.MyNewsList.NewsLink = {
    header: function (ctx) {
        var hdrHtml = "";
        if( window.MyNewsList.NewsLink.canAddNews() ) {
            hdrHtml += "<div>";
                hdrHtml += "<span class=\"link-item\"><a href=\"/news/Lists/Pages/Forms/NewForm.aspx\">Add New</a></span>";
            hdrHtml += "</div>";
        }
        return hdrHtml;
    },

    body: function (ctx) {
        bodyHtml = "";
        bodyHtml += "<div>";
        bodyHtml += ctx.CurrentItem.Title;
        bodyHtml += "</div>";
        return bodyHtml;
    },
    footer: function (ctx) {
        var footerHtml = "";
        var firstRow = ctx.ListData.FirstRow;
        var lastRow = ctx.ListData.LastRow;
        var prev = ctx.ListData.PrevHref;
        var next = ctx.ListData.NextHref;

           footerHtml += "<table class=\"ms-bottompaging\"><tr><td>";
            if (prev)
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='" + prev + "'><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23' /></span></a>";
            else
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-disabled' href='javascript:void(0);'><span class='ms-promlink-button-image'><img class='ms-promlink-button-left-disabled' src='/_layouts/15/images/spcommon.png?rev=23' /></span></a>";

            footerHtml += "<span class=\"ms-promlink-button-inner\"></span>";

            if (next)
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
            else
                footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-disabled' href='javascript:void(0);'><span class='ms-promlink-button-image'><img class='ms-promlink-button-right-disabled' src='/_layouts/15/images/spcommon.png?rev=23' /></span></a>";

            footerHtml += "</td></tr></table>";

        return footerHtml;
    }
};

// anonymous self-executing function to setup JSLink templates on page load..
(function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};

    //Tempate overrides
    overrideCtx.Templates.Header = window.MyNewsList.NewsLink.header;
    overrideCtx.Templates.Item = window.MyNewsList.NewsLink.body;
    overrideCtx.Templates.Footer = window.MyNewsList.NewsLink.footer;

    //List Settings
    //Pages List has Type 850 publishing page library
    //BaseViewID = 1 means default View
    //overrideCtx.BaseViewID = 1;
    overrideCtx.ListTemplateType = 850;

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();
.


編集:

残念ながら、受け入れられた解決策は結局のところうまくいきませんでした。それは最初のページに問題がありますが、以前のページに戻ったらテンプレートはマークアップをレンダリングしません。そこからそれは本当にグリッチアップされます。私はこれを掘り下げる時間がある時間があるまで、私はただめちゃくちゃになってポストバックのページングでそれを残しました。

役に立ちましたか?

解決

SharePoint is a huge historical monster. Core of the current paging implementation was introduced long ago, probably in SP2010 or even earlier. That's why your approach doesn't work: SharePoint isn't finding some html elements that are supposed to be there, and falls back to a simpler approach with link.

Investigation

Here is why it happens (you may skip to solution if not interested).

Core of RefreshPageTo implementation is found in inplview.RefreshPageToEx function of inplview.js file:

function RefreshPageToEx(evt, url, bForceSubmit) {
    var clvp = CLVPFromEvent(evt);

    if (clvp != null && clvp.ctx.IsClientRendering) {
        clvp.RefreshPaging(url);
        clvp.ctx.queryString = url;
        if ((typeof clvp.ctx.operationType == "undefined" || clvp.ctx.operationType == SPListOperationType.Default) && Boolean(clvp.ctx.ListData)) {
            var fromPage = clvp.ctx.ListData.FirstRow - 1;
            var toPage = Number(GetUrlKeyValue("PageFirstRow", false, url));

            if (!isNaN(fromPage) && !isNaN(toPage) && fromPage != toPage)
                fromPage < toPage ? (clvp.ctx.operationType = SPListOperationType.PagingRight) : (clvp.ctx.operationType = SPListOperationType.PagingLeft);
        }
    }
    else {
        SubmitFormPost(url, bForceSubmit);
    }
}

As you can see, this implementation depends on clvp object, which basically represents the list view context, containing all the necessary information for paging and other list view tasks. CLVPFromEvent function call fetches the clvp object from the current event, by ascending from the event element (which is the <span> that is clicked) and trying to find TABLE with class 'ms-listviewtable'. That table contains attribute clvp that stores the desired clvp object.

If TABLE with class 'ms-bottompaging' is found, then the CLVPFromEvent function processes to the previous sibling of the parent of this table, and then finds 'ms-listviewtable' amongst it's children.

So the usual structure of a SharePoint list view is as follows:

<table>
  ...
  <table class="ms-listviewtable">...</table>
</table>
<div id="scriptPagingWPQ2">
  <table class="ms-bottompaging">
    ...
  </table>
</div>

But in case of custom rendering, you'll get the following structure:

<table>
  ...
  <table class="ms-listviewtable">...</table>
</table>
<div id="scriptPagingWPQ2">
  <!-- your custom footer code goes here -->
</div>

Since Ajax paging implementation is tightly depends on clvp object and can't find it, Ajax paging doesn't work.

Solution

Simplest approach would be of course to create this missing table. Like that:

SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
    Templates: {
      Footer: function (ctx) {
        var footerHtml = '<table class="ms-bottompaging"><tr><td>';
        var next = ctx.ListData.NextHref;
        footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
        footerHtml += "</td></tr></table>";
        return footerHtml;
      }
    }
});

I tested it and it works.

Still, if you find any problems I might have missed, then it likely that some other "supposed" elements are missed there. In this case I would advise you to explore the original implementation in the OOTB function RenderPaging that can be found in the clienttemplates.js file in 15/template/layouts folder.

Although this approach works, but there might be cases when you want to avoid placing a table there due to some problems with CSS or maybe you're a purist and want to make things more perfect ;) In this case you might want to create your own implementation of the RefreshPageToEx function, so that it finds the necessary clvp object and calls clvp.RefreshPaging(url) directly. But this is more risky approach.

Update

It turns out that the 'ms-listviewtable' TABLE is generated by OOTB header template. If you override the header template, it is not generated and thus paging goes non-Ajax yet again. To fix that, you can call RenderTableHeader OOTB function and then just close the table tag.

So in case you're overriding the header template along with footer template, you should use the following fix:

SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
    Templates: {
      Header: function(ctx) {
        var headerHtml =  RenderTableHeader(renderCtx);
        headerHtml += "</table>";
        // add some other stuff to headerHtml
        return headerHtml;
      },
      Footer: function (ctx) {
        var footerHtml = '<table class="ms-bottompaging"><tr><td>';
        var next = ctx.ListData.NextHref;
        footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next + "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
        footerHtml += "</td></tr></table>";
        return footerHtml;
      }
    }
});

So in your case you should change the header function as follows:

header: function (ctx) {
    var hdrHtml = RenderTableHeader(renderCtx) + "</table>";
    if( window.MyNewsList.NewsLink.canAddNews() ) {
        hdrHtml += "<div>";
            hdrHtml += "<span class=\"link-item\"><a href=\"/news/Lists/Pages/Forms/NewForm.aspx\">Add New</a></span>";
        hdrHtml += "</div>";
    }
    return hdrHtml;
},

他のヒント

RefreshPageToEx is more powerful function and if table class is "ms-bottompaging" then no full refresh happens. if the class is reptetive or not being used then full postback happens. if try it and let me know if you still face the problem.

its bit late post but will update complete plugin sooner

Using the function "ctx.clvp.RefreshPagingEx(ctx.ListData.NextHref, true,null)" for the paging button onclick works great and avoids the need for extra markup and the entire JSLink chain is called.

Complete code:

var ClientsideContext = {};
ClientsideContext.Templates.Footer = loadFooter;

function loadFooter(ctx) {
    var footerHtml = '<table class="ms-bottompaging"><tr><td>';
    var firstRow = ctx.ListData.FirstRow;
    var lastRow = ctx.ListData.LastRow;
    var prev = ctx.ListData.PrevHref;
    var next = ctx.ListData.NextHref;
    if (prev) {
        footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + prev +
            "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-left' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
    }
    if (prev || next) {
        footerHtml += "<span class='ms-paging'><span class='First'>" + firstRow + "</span> - <span class='Last'>" + lastRow + "</span></span>";
}
    if (next) {
        footerHtml += "<a class='ms-commandLink ms-promlink-button ms-promlink-button-enabled' href='javascript:void(0);' onclick=\"RefreshPageTo(event, &quot;" + next +
            "&quot;);return false;\"><span class='ms-promlink-button-image'><img class='ms-promlink-button-right' src='/_layouts/15/images/spcommon.png?rev=23'/></span></a>";
}
    footerHtml += "</td></tr></table>";
    return footerHtml;
}
ライセンス: CC-BY-SA帰属
所属していません sharepoint.stackexchange
scroll top