none
SharePoint List - Previous Item / Next Item RRS feed

  • Question

  • Hello,

    we have a standard SharePoint list. In this list we have the following entries for example:

    Number ; BProcess ; Identifier ; PreviosNextItem

    1 ; P2 ; 123456

    2 ; P3 ; 123456

    3 ; P2 ; 098888

    4 ; P2 ; 098888

    5 ; P2 ; 123456

    In the column "PreviousNextItem" I want to put a link to the previos and the next item with the same Identifier. For example for item 2:

    Previous Item: 1 ; Next Item 5

    I have created the following code for a calculated column. Problem is that it doesn't filter the identifier. So it displays the previous item in the list and the next item.

    ="<img src=/_layouts/images/blank.gif onload=""{"&"var TR=this;while(TR.tagName!='TR'){TR=TR.parentNode}"&"var TABLE=TR;while(TABLE.tagName!='TABLE'){TABLE=TABLE.parentNode}"&"var n=TR.rowIndex;"&"var item=ctx.ListData.Row[n-1];"&"var prev=n>1?ctx.ListData.Row[n-2].ID:false;"&"var next=TABLE.rows.length-1>n?ctx.ListData.Row[n].ID:false;"&"var thisID=GetUrlKeyValue('ID');"&"if(thisID==TR.id.split(',')[1]){"&"var url='<div style=float:{2}><a href='+document.location.pathname+'?ID={0}>{1} (ID:{0})</a></div>';"&"var prevHTML=prev?String.format(url,prev,'Previous','left'):'<div style=float:left>This is the first Item</div>';"&"var nextHTML=next?String.format(url,next,'Next','right'):'<div style=float:right>This is the last Item</div>';"&"var HTML=String.format('<div style=;margin-top:0px>{0}  This ID:{2} {1}</div>',prevHTML,nextHTML,thisID);"&"this.parentNode.innerHTML=HTML;"&"}else{"&"this.parentNode.innerHTML=String.format('<span id='+'prev'+'>{0}</span> <span id='+'next'+'>{1}</span>',prev,next);"&"}"&"}"">"

    Any help?:)


    • Edited by Twychopath Monday, March 6, 2017 2:57 PM
    Monday, March 6, 2017 7:58 AM

Answers

  • Hi,

    You could use JSLink for your requirement, here is my test code for your reference.

     

    (function () {
        'use strict';
    
        var CustomCtx = {};
    
        /**
         * Initialization
         */
        function init() {
    
            CustomCtx.Templates = {};
    
            CustomCtx.Templates.Fields = {
                'PreviosNextItem': {
                    'View': customDisplay
                }
            };
    
            // Register the custom template
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(CustomCtx);
        }
    
        /**
         * Rendering template
         */
        function customDisplay(ctx) {
            //from the context get the current item and it's value 
            if (ctx != null && ctx.CurrentItem != null) {
                var currentVal = ctx.CurrentItem['Identifier'];
                var currentIndex = ctx.CurrentItem.ID;
                var previous = "";
                var next = "";
    
                for (var i = 0; i < ctx.ListData.Row.length; i++) {
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                        previous = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>previous</a>";
                    }
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] > currentIndex) {
                        next = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>next</a>";
                    }
                    // Render the HTML5 file input in place of the OOTB                
                }
                return previous +" "+ next;
            }
        }
    
        // Run our intiialization
        init();
    
    })();

    You need link your list form with JS file, here is one link for your reference.

    https://zimmergren.net/sp-2013-using-the-spfield-jslink-property-to-change-the-way-your-field-is-rendered-in-sharepoint-2013/

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Tuesday, March 7, 2017 5:25 AM
  • Hi,

    Try this:

     

    (function () {
        'use strict';
    
        var CustomCtx = {};
    
        /**
         * Initialization
         */
        function init() {
    
            CustomCtx.Templates = {};
    
            CustomCtx.Templates.Fields = {
                'PreviosNextItem': {
                    'View': customDisplay
                },
                'itemNumber': {
                    'View': customDisplay1
                }
            };
    
            // Register the custom template
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(CustomCtx);
        }
    
        /**
         * Rendering template
         */
        function customDisplay(ctx) {
            //from the context get the current item and it's value 
            if (ctx != null && ctx.CurrentItem != null) {
                var currentVal = ctx.CurrentItem['Identifier'];
                var currentIndex = ctx.CurrentItem.ID;
                var previous = "";
                var next = "";
    
                for (var i = 0; i < ctx.ListData.Row.length; i++) {
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                        previous = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>previous</a>";
                    }
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] > currentIndex) {
                        next = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>next</a>";
                    }
                    // Render the HTML5 file input in place of the OOTB                
                }
                return previous +" "+ next;
            }
        }
    
        function customDisplay1(ctx) {
            //implement your logic here
            var index=1;
            var total = 0;
            var currentVal = ctx.CurrentItem['Identifier'];
            var currentIndex = ctx.CurrentItem.ID;
            for (var i = 0; i < ctx.ListData.Row.length; i++) {
                if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                    total += 1;
                    index += 1;
                }
                if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] >= currentIndex) {
                    total += 1;
                }
                // Render the HTML5 file input in place of the OOTB                
            }
            return index + " of " + total;
        }
        // Run our intiialization
        init();
    
    })();

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    • Marked as answer by Twychopath Tuesday, March 7, 2017 10:19 AM
    Tuesday, March 7, 2017 10:00 AM

All replies

  • Hi,

    You could use JSLink for your requirement, here is my test code for your reference.

     

    (function () {
        'use strict';
    
        var CustomCtx = {};
    
        /**
         * Initialization
         */
        function init() {
    
            CustomCtx.Templates = {};
    
            CustomCtx.Templates.Fields = {
                'PreviosNextItem': {
                    'View': customDisplay
                }
            };
    
            // Register the custom template
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(CustomCtx);
        }
    
        /**
         * Rendering template
         */
        function customDisplay(ctx) {
            //from the context get the current item and it's value 
            if (ctx != null && ctx.CurrentItem != null) {
                var currentVal = ctx.CurrentItem['Identifier'];
                var currentIndex = ctx.CurrentItem.ID;
                var previous = "";
                var next = "";
    
                for (var i = 0; i < ctx.ListData.Row.length; i++) {
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                        previous = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>previous</a>";
                    }
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] > currentIndex) {
                        next = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>next</a>";
                    }
                    // Render the HTML5 file input in place of the OOTB                
                }
                return previous +" "+ next;
            }
        }
    
        // Run our intiialization
        init();
    
    })();

    You need link your list form with JS file, here is one link for your reference.

    https://zimmergren.net/sp-2013-using-the-spfield-jslink-property-to-change-the-way-your-field-is-rendered-in-sharepoint-2013/

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Tuesday, March 7, 2017 5:25 AM
  • THANK YOU SO MUCH!

    But I have one other question:

    In the same list I've added the column "ItemNumber". Is it possible to display the total number of items with the same Identifier and the position of the current item, so I have something like an Index?

    For example so: 

    Thanks in advance! :)


    • Edited by Twychopath Tuesday, March 7, 2017 8:51 AM
    Tuesday, March 7, 2017 8:50 AM
  • Hi,

    Yes, you just need add the logic for itemNumber field.

     Here is the structure for your reference.

     

    (function () {
        'use strict';
    
        var CustomCtx = {};
    
        /**
         * Initialization
         */
        function init() {
    
            CustomCtx.Templates = {};
    
            CustomCtx.Templates.Fields = {
                'PreviosNextItem': {
                    'View': customDisplay
                },
                'itemNumber': {
                    'View': customDisplay1
                }
            };
    
            // Register the custom template
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(CustomCtx);
        }
    
        /**
         * Rendering template
         */
        function customDisplay(ctx) {
            //from the context get the current item and it's value 
            if (ctx != null && ctx.CurrentItem != null) {
                var currentVal = ctx.CurrentItem['Identifier'];
                var currentIndex = ctx.CurrentItem.ID;
                var previous = "";
                var next = "";
    
                for (var i = 0; i < ctx.ListData.Row.length; i++) {
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                        previous = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>previous</a>";
                    }
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] > currentIndex) {
                        next = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>next</a>";
                    }
                    // Render the HTML5 file input in place of the OOTB                
                }
                return previous +" "+ next;
            }
        }
    
        function customDisplay1(ctx) {
            //implement your logic here
            return "Item Number";
        }
        // Run our intiialization
        init();
    
    })();

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Tuesday, March 7, 2017 9:21 AM
  • Do you have any hint or tip for me how I can archive this logic?

    I do not have so much experience withCSR and JavaScript. I think the best solution would be to write all items with the same identifier into an variable and count the elements. Then get the position of the current element.

    Thanks so much for your help.

    Tuesday, March 7, 2017 9:44 AM
  • Hi,

    Try this:

     

    (function () {
        'use strict';
    
        var CustomCtx = {};
    
        /**
         * Initialization
         */
        function init() {
    
            CustomCtx.Templates = {};
    
            CustomCtx.Templates.Fields = {
                'PreviosNextItem': {
                    'View': customDisplay
                },
                'itemNumber': {
                    'View': customDisplay1
                }
            };
    
            // Register the custom template
            SPClientTemplates.TemplateManager.RegisterTemplateOverrides(CustomCtx);
        }
    
        /**
         * Rendering template
         */
        function customDisplay(ctx) {
            //from the context get the current item and it's value 
            if (ctx != null && ctx.CurrentItem != null) {
                var currentVal = ctx.CurrentItem['Identifier'];
                var currentIndex = ctx.CurrentItem.ID;
                var previous = "";
                var next = "";
    
                for (var i = 0; i < ctx.ListData.Row.length; i++) {
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                        previous = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>previous</a>";
                    }
                    if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] > currentIndex) {
                        next = "<a class='ms-listlink ms-draggable' href='" + ctx.listUrlDir + "/DispForm.aspx?ID=" + ctx.ListData.Row[i]['ID'] + "&Source=" + _spPageContextInfo.webAbsoluteUrl + _spPageContextInfo.serverRequestPath + "'>next</a>";
                    }
                    // Render the HTML5 file input in place of the OOTB                
                }
                return previous +" "+ next;
            }
        }
    
        function customDisplay1(ctx) {
            //implement your logic here
            var index=1;
            var total = 0;
            var currentVal = ctx.CurrentItem['Identifier'];
            var currentIndex = ctx.CurrentItem.ID;
            for (var i = 0; i < ctx.ListData.Row.length; i++) {
                if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] < currentIndex) {
                    total += 1;
                    index += 1;
                }
                if (currentVal == ctx.ListData.Row[i]['Identifier'] && ctx.ListData.Row[i]['ID'] >= currentIndex) {
                    total += 1;
                }
                // Render the HTML5 file input in place of the OOTB                
            }
            return index + " of " + total;
        }
        // Run our intiialization
        init();
    
    })();

    Best Regards,

    Lee


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    • Marked as answer by Twychopath Tuesday, March 7, 2017 10:19 AM
    Tuesday, March 7, 2017 10:00 AM