GetListItems and GetAttachments

Oct 23, 2009 at 1:00 PM
Edited Oct 23, 2009 at 2:29 PM

Hi folks

Being playing around with these for getting all list items and exposing links directly to attachments. This is what i have so far:


function showAttribute(xmlObject, attrName, showlink) {
		var attrValue = xmlObject.attr(attrName);
		showlink ?
		$(divId).append("<li><b>" + attrName + "</b>: <a href='" + attrValue + "'>" + attrValue + "</a></li>") :
		$(divId).append("<li><b>" + attrName + "</b>: " + attrValue + "</li>");

    function getListItems() {
			listName: reqList,
			CAMLViewFields:'<ViewFields><FieldRef Name="Title"/><FieldRef Name="Modified"/></ViewFields>',
			completefunc: function (xData, Status) {
				$(divId).html("").append("<b>This is the output from the GetListItems operation:</b>");
				$(xData.responseXML).find("z\\:row").each(function() {
					showAttribute($(this), "ows_Title");
					showAttribute($(this), "ows_Modified");
						listName: reqList, ID: $(this).attr("ows_ID"),
						completefunc: function (xData, Status) {
							$(xData.responseXML).find("Attachment").each(function() {
								$(divId).append("<li><a href='" + $(this).text() + "'><img src='/_layouts/images/attach.gif' alt='Attachment'/></a></li>");

It pulls out the list items and the attachments links but it appends the attachment links after the list items. Its probably my crappy jQuery but ideally i would want the links alongside the items


Oct 23, 2009 at 2:17 PM

It's actually your HTML.  ;=)

You're outputting every element as a list item (<LI>), so they all become equal siblings in the list. If you wrap the attachment elements in an unordered list (<UL>), you'll at least get them indented.

    $(xData.responseXML).find("Attachment").each(function() {
    $(divId).append("<li><a href='" + $(this).text() + "'><img src='/_layouts/images/attach.gif' alt='Attachment'/></a></li>");

I expect that you'll want some totally different formatting in reality, but this is a good POC.


Oct 23, 2009 at 2:26 PM

:) ye i knew the html wasnt proper, and that there were no UL. Shoulda cleaned up before i posted.

However, i was under the impresseion the first 2 calls to showAttribute() would append the LIs (to a div :/) and then the call to GetAttachmentCollection would append a further LI next to the previous two. However its putting the GetAttachmentCollection listitems after the whole of GetListItems:

<li>Item 1 Title</li>
<li>Item 1 Modified</li>
<hr />
<li>Item 2 Title</li>
<li>Item 2 Modified</li>
<hr />
<li>Item 3 Title</li>
<li>Item 3 Modified</li>
<hr />
<li>Attachment 1</li>
<li>Attachment 2</li>
<li>Attachment 3</li>

The formatting and HTML is garbage i know - but lets not worry about that just now :)


Oct 23, 2009 at 2:32 PM

Oh, I get what you mean.  The Web Service calls are, by default, asynchronous.  So you can't predict when each will complete and decide to add its output to the DIV.  So you have two options, depending on your goals:

  1. Make the Web Service calls asychronous.  You can do this by adding the
    async: false
    option to the SPServices calls.  By doing this, though, you are requiring everything to wait while the calls complete.
  2. Build up your output in one string and then append the string to the DIV at the end of your code.


Oct 23, 2009 at 2:55 PM
Edited Oct 26, 2009 at 9:40 AM

I think it may have to be async rather than string append. Wouldnt the stringbuilder method suffer the same fate as my instant output before. I.e it will add to the string whenever it gets a complete request

The async:false method works, thanks