SharePoint SOAP GetListItems VS jQuery - How to use Ajax to loop through Custom List items and also Ajax to update the contents of the list?

I am using jQuery to access the SOAP interface of a Sharepoint 2007 using the GetListItems method to read in a custom ad list in such a way as to update that list once a minute (if the list owners add new content so that the new content becomes visible if the end user will not refresh its sharepoint screen). What I would like to do is not only update this list, I would like to have each item in the list loop one at a time (perhaps each item remains visible for 10 seconds, then the next item will be loaded into that space.

Here is the code I have so far:

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/SiteCollectionDocuments/jquery.timers-1.0.0.js" ></script>  
<script type="text/javascript">

$(document).ready(function() {

// Create the SOAP request        
// NOTE: we need to be able to display list attachments to users, hence the addition of the
// <queryOptions> element, which necessitated the addition of the <query> element

var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
<soapenv:Body> \
   <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
     <listName>testlist</listName> \
     <viewFields> \
       <ViewFields> \
         <FieldRef Name='Title' /> \
         <FieldRef Name='Body' /> \
         <FieldRef Name='ID' /> \
         <FieldRef Name='Attachments' /> \
       </ViewFields> \
     </viewFields> \
     <query> \
       <Query /> \
     </query> \
     <queryOptions> \
       <QueryOptions> \
         <IncludeAttachmentUrls>TRUE</IncludeAttachmentUrls> \
       </QueryOptions> \
     </queryOptions> \
    </GetListItems> \
  </soapenv:Body> \
  </soapenv:Envelope>";

// call this SOAP request every 20 seconds
$("#tasksUL").everyTime(20000,function(i){
    // our basic SOAP code to hammer the Lists web service
    $.ajax({
    url: "http://ourdomain.net/_vti_bin/lists.asmx",
    type: "POST",
    dataType: "xml",
    data: soapEnv,
    error: printError,
    complete: processResult,
    contentType: "text/xml; charset=\"utf-8\""
    });
  });
});

// basic error display that will pop out SOAP errors, very useful!
function printError(XMLHttpRequest, textStatus, errorThrown)
{
 alert("There was an error: " + errorThrown + " " + textStatus);
  alert(XMLHttpRequest.responseText);
}


// main method that will cycle through the SoAP response nodes
function processResult(xData, status) 
{

  $(xData.responseXML).find("z\\:row").each(function() 
  {
    // resets display element
   $("#tasksUL").empty();

   // gets attachments array - if there is more than one attachment,
   // they get seperated by semi-colons in the response
   // they look like this natively (just an example):
   // ows_Attachments = ";#http://server/Lists/Announcements/Attachments/2/test.txt;
   // #http://server/Lists/Announcements/Attachments/2/UIP_Setup.log;#"

       var mySplitResult = $(this).attr("ows_Attachments").split(";");
  // set up storage for later display of images
  var notice_images = "";

  // processes attachments - please forgive the kludge!  
  for(i = 0; i < mySplitResult.length; i++)
  {
   // check to see the proper link URL gets chosen
   if (i % 2 != 0 && i != 0)
   {
    // strips out pound sign
    mySplitResult[i] = mySplitResult[i].replace("#", "");

    // (possibly redundant) check to make sure element isn't simply a pound sign  
    if (mySplitResult[i] != "#")
    {
     // adds an img tag to an output container
     notice_images = notice_images + "<img src='" + mySplitResult[i] + "' border='0' align='right' style='float:right;' /><br />"; 
    }
   }
  }

  // create final output for printing
  var liHtml = "<h3>" + $(this).attr("ows_Title") + "</h3><p>" + notice_images + $(this).attr("ows_Body") + "</p>";

  // assign output to DIV tags
    $("#tasksUL").html(liHtml);

   });

}
</script>

<div id="tasksUL"/>&nbsp;</div>

      

Pretty simple stuff so far (although finding decent documentation as to what you can do with a SOAP GetListItem request has been tricky). Inside the block where I iterate over the returned lines (PprocessResult function), I return the HTML assigned to the DIV block so that only one line is displayed as output. A way of customizing the code, this means that only the very last line in my custom list will be visible since I have no code to stop the iterations.

My thought was to wrap a timer around this block of code:

$(xData.responseXML).find("z\\:row").each(MYTIMER(10000, function(){...

      

But I have met with zero or mixed results.

My question to all of you is, what would be the best way to set up my current code to update the original list data like it is now? And loop through the query results from this list one at a time (preferably with a little pause on each item so people can read it)?

+2


source to share


2 answers


I would keep your visual loop and data refresh loop as separate entities.

Set up your timeout function to update the container from the div with your data being displayed inside. You can add and remove from this list as you wish.

You can start with something like:

<div id="container">
  <div id="1" class="task">task foo</div>
  <div id="2" class="task">task bar</div>
  <div id="3" class="task">task baz</div>
</div>

      



And then after updating the data, it can add another item:

<div id="container">
  <div id="1" class="task">task foo</div>
  <div id="2" class="task">task bar</div>
  <div id="3" class="task">task baz</div>
  <div id="4" class="task">task lol</div>
</div>

      

Then use a loop plugin to simply loop through an ordered set of divs within a given container element. It will always just show the next div in the collection and not rely on your update plugin to restart the loop.

The most popular jQuery looping plugin is jquery.cycle.js at http://malsup.com/jquery/cycle2/ . You may also be interested in the 'lite' version available online.

+1


source


Actually, no one knew that this happened because someone installed the jQuery package for the site collection, which was old and didn't work very well with jCycle. Once I deactivated this feature on the collection, restarted IIS and refreshed the page, everything worked fine. As an extra step, I downloaded the latest full version of jQuery into the document library and linked to it instead of the google hosted version of the script. So all the js I use is life within a site collection.

I was able to sort out the conflicting versions of jQuery, but using the Firebug Console and the Script debugger. I had to defer the debugger to stop all errors, but the very first error that came up was about the site collection jQuery package, not my included Google code. It is for this reason that I am answering my own question. There are other poor bastards out there who do SharePoint, and it might not happen to them that they use FireFox to test their SP installations, given how much IE favors it and all.



Thanks to everyone who read and answered / commented!

0


source







All Articles