Problem with no data being returned during pagination

Dec 10, 2014 at 10:55 PM
Edited Dec 10, 2014 at 10:56 PM
For some reason when the SPServices code hits a certain area of my pagination, it just skips over the SPServices call, or goes in and out with out returning anything. I can probably give you what the data is for the area, and I'll give you the CAMLQuery, CAMLQueryOptions, CAMLRowLimit, and items in the completefunc now:

CAMLQuery:
<Query><OrderBy><FieldRef Name='Title' /></OrderBy></Query>

CAMLQueryOptions:
<QueryOptions><Paging ListItemCollectionPositionNext='Paged=TRUE&p_Title=Good to Great: Why Some Companies Make the Leap...And Others Don't&p_ID=244

CAMLRowLimit: 25

and now the completefunc:
    completefunc: function (xData, Status) {
        $("#searchResults > tbody").html(""); 
        var datarows = "<tbody>";
        var rowcount = countStart;

        $(xData.responseXML).SPFilterNode("z:row").each(function() {

            var titleString = $(this).attr("ows_Title");
            if(titleString != null) {
                var titleHtml = "<td>" + titleString + "</td>";
            } else {
                var titleHtml = "<td>&nbsp;</td>";
            }

            var authorString = $(this).attr("ows_Column2");
            if(authorString != null) {
                var authorHtml = "<td>" + authorString + "</td>";
            } else {
                var authorHtml = "<td>&nbsp;</td>";
            }

            var competenciesString = $(this).attr("ows_Competencies");

            if(competenciesString != null) {
                competenciesArray = competenciesString.split(";#");
                competenciesString = "";
                chopEndArrayLength = competenciesArray.length - 2; //chop back entry that is blank
                for (i = 1; i <= chopEndArrayLength; i++) {
  "chopEndArrayLength: " + chopEndArrayLength);
                    if((competenciesArray[i] != null) && i < chopEndArrayLength) {
                        competenciesString += competenciesArray[i] + ", ";
                    } else { // add end of array data
                        competenciesString += competenciesArray[i];
                    }
                }
            } else {
                competenciesString = "&nbsp;";
            }

            competenciesHtml = "<td>" + competenciesString + "</td>";
            if( rowcount % 2 == 1 ){
                var bgcolor = "#eeeeee";
            } else {
                var bgcolor = "#ffffff";
            }

            datarows += "<tr bgcolor='" + bgcolor + "'>"+ "<td>" + rowcount + "</td>" + titleHtml + authorHtml + competenciesHtml +"</tr>";
            rowcount++;
        });

        datarows += "</tbody>";
        $("#searchResults").append(datarows);
    }

any debug help would be great.

Thank You
Dec 11, 2014 at 2:56 AM
You need to Xml escape the next page token.



--
Paul T.

-- Sent from Mobile

Marked as answer by trout0525 on 12/15/2014 at 6:16 AM
Dec 15, 2014 at 1:11 PM
Hello Paul,

Thank you for the response. Please pardon my ignorance, but I am uncertain about XML escaping. Do you have an example?

Thank You,

Matt
Dec 15, 2014 at 1:37 PM
Look here: https://github.com/purtuga/SPWidgets/blob/master/src/jquery.SPWidgets.js#L643

Line 643 has a function called escapeXML that you should be able to reuse.




--
Paul T.

-- Sent from Mobile

Dec 15, 2014 at 1:37 PM
Hello Paul,

Oh, I'm sorry. You mean to escape the special characters that the page encodes, right? I'm looking where and how to do it. I'm thinking I'm going to have to write a .replace().replace().replace... or a function to do the proper escaping I need. Any advice on what to escape?

Thank You,

Matt
Dec 15, 2014 at 2:00 PM
Hello Paul,

Here is what I'm using to build my page navigation:
function buildNav(rowLimit) {
    // Unbind old objects
    $("libraryPrev a").unbind('click');
    $("libraryNext a").unbind('click');
    $(".pager a").unbind('click');
    // Clear current nav
    $("#libraryPages").html("");

    var recordCount = 0;
    var firstPos = "";

    // execute once to get all items
    // not using rowLimit to return all items
    $().SPServices({
        operation: "GetListItems",
        async: false,
        listName: list,
        CAMLViewFields: camlFields,
        CAMLQuery: camlQuery,
        completefunc: function (xData, Status) {
            recordCount = parseFloat($(xData.responseXML).SPFilterNode("rs:data").attr("ItemCount"));

        }
    });

    // execute again to retrieve first position
    // this uses rowLimit
    $().SPServices({
        operation: "GetListItems",
        async: false,
        listName: list,
        CAMLViewFields: camlFields,
        CAMLQuery: camlQuery,
        CAMLRowLimit: rowLimit,
        completefunc: function (xData, Status) {
            firstPos = $(xData.responseXML).SPFilterNode("rs:data").attr("ListItemCollectionPositionNext");
        }
    });

    if(eval(recordCount > rowLimit)) {
        $("#libraryPages").append('<div id=\'library-prev\'><a href="#">Prev</a></div>');

        var pages = Math.ceil(recordCount / rowLimit);
        var nextPos = "";

        for (i=1; i <= pages; i++) {
            if (i == 1) {
                $("#libraryPages").append("<div id='row-" + i + "' class='pager'><a class='selected' href='javascript:getItems(\"\",\"" + rowLimit + "\")'> " + i + "</a></div>");
            } else {
                nextPos = getNextPos(nextPos, rowLimit, camlQuery);
                $("#libraryPages").append("<div id='row-" + i + "' class='pager'><a class='selected' href='javascript:getItems(\"" + escapeXML(nextPos) + "\",\"" + rowLimit + "\")'>" + i + "</a></div>");
            }
        }

        $("#libraryPages").append('<div id=\'library-next\'><a href="#">Next</a></div>');
    }
}
Where escapeXML is this function:
function escapeXML(xmlString) { 

    if ( typeof xmlString !== "string" ) { 
        return ""; 
    } 

    return xmlString
    .replace(/&/g,'&amp;')
    .replace(/</g,'&lt;')
    .replace(/>/g,'&gt;')
    .replace(/'/g,"&apos;")
    .replace(/"/g,"&quot;"); 

}
when I use the function I started this discussion with, all it returns me for the one page that isn't showing any data, is the "<tbody>" and nothing else. Anymore thoughts? It's almost like the '$(xData.responseXML).SPFilterNode("z:row").each(function() {' isn't even executing.

Thank You,

Matt
Dec 15, 2014 at 2:16 PM
Hello Paul,

I think I found my error, that you helped point out to me. I was using this to escape:
    pos = pos.replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
and I didn't get a chance to escape the single quote. I started just using the function escapeXML, and I think that took care of it in my getItems function above.

Thank You.
Marked as answer by trout0525 on 12/15/2014 at 6:16 AM
Dec 15, 2014 at 2:25 PM
Right. That was the character that triggered me to say you needed to escape the value.



--
Paul T.

-- Sent from Mobile