0

I was given an old webpart using SP services and XML. I was requested to use Ajax. This is the first time I do this kind of conversion and I am not sure if I am doing it correctly. This is the old code

$(document).ready(function() {
  $().SPServices({
    operation: "GetListItems",
    async: false,
/**--List Name Below(case sensative)--**/
    listName: "Title of List Here",
/**--Site List Resides on (leave blank if same site)--**/
    webURL: "",
/**--No Change below this line--**/
    CAMLViewFields: "<ViewFields><FieldRef Name='RequiredField' /><FieldRef Name='Title' /></ViewFields>",
    completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {
        var pictureLink = $(this).attr("ows_RequiredField");
        var linkTitle = $(this).attr("ows_Title");
        $('#lightBoxContainer')
            .append($('<figure class="col-6 col-md-3 view overlay hm-red-strong">')
                .append ($('<a>').attr('href', "" + "/" + pictureLink + "").attr("title", linkTitle).attr('data-size', "1600x1067")
                .append($('<img>').attr('src', "" +  "/" + pictureLink + "").attr("title", linkTitle).addClass("img-fluid")))
            .append($('<figcaption class="text-center" itemprop="caption description">').html(linkTitle)));
      });
    }
  });
});

This is what I have done so far

$.ajax({
    url: "/_api/web/lists/GetByTitle('LightBoxGallery')/items",
    method: 'GET',
    headers: {
        'Accept': 'application/json; odata=verbose'
    },
    success: function(data) {

        var items = data.d.results;

        for (var i = 0; i < items.length; i++) {
            var pictureLink = items[i].RequiredField;
            var linkTitle = items[i].Title;
        }


        $('#lightBoxContainer')
                .append($('<figure class="col-6 col-md-3 view overlay hm-red-strong">')
                .append ($('<a>').attr('href', "" + "/" + pictureLink + "").attr("title", linkTitle).attr('data-size', "1600x1067")
                .append($('<img>').attr('src', "" +  "/" + pictureLink + "").attr("title", linkTitle).addClass("img-fluid")))
                .append($('<figcaption class="text-center" itemprop="caption description">').html(linkTitle)));
      });
        }
    },
    error: function(data) {
        console.log('Error: ' + data);
    }
}); 
0

You're almost there... a couple things to note:

  • If you see the CAMLViewFields part of the SPServices code, you'll see that you only really need to retrieve two fields, Title and RequiredField. That can translate into a $select in your REST query.
  • You probably need to specify the URL of the site you are trying to query against, so you could add _spPageContextInfo.webAbsoluteUrl to the beginning of your URL string.
  • You need to do the appending from inside the for loop you set up to loop through your results. The way you have it set up right now, it will loop through all the items, each time assigning the pictureLink and linkTitle variables to new values, but then not doing anything with them, just going on to the next loop iteration. Then on the last iteration, it will set the variables to the values of Title and RequiredField of the last item only, then exit the loop, then go on to the append code and only append a link with the data from the last item.
  • You had a few extra close brackets & parens in there, so your code blocks were a little off.

Here's a cleaned up version that might work for you:

$.ajax({
    url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('LightBoxGallery')/items?$select=Title,RequiredField",
    method: 'GET',
    headers: {
        'Accept': 'application/json; odata=verbose'
    },
    success: function (data) {

        var items = data.d.results;

        for (var i = 0; i < items.length; i++) {
            var pictureLink = items[i].RequiredField;
            var linkTitle = items[i].Title;

            $('#lightBoxContainer')
                .append($('<figure class="col-6 col-md-3 view overlay hm-red-strong">')
                .append($('<a>').attr('href', "" + "/" + pictureLink + "").attr("title", linkTitle).attr('data-size', "1600x1067")
                .append($('<img>').attr('src', "" + "/" + pictureLink + "").attr("title", linkTitle).addClass("img-fluid")))
                .append($('<figcaption class="text-center" itemprop="caption description">').html(linkTitle)));

        } // this ends your for loop

    }, // this ends your success function

    error: function(data) {
        console.log('Error: ' + data);
    }
});

If this same webpart is going to be used on different sites and reading from different lists, there are a few things to consider:

  • Using _spPageContextInfo.webAbsoluteUrl as part of the REST query URL will make it automatically look to the site where the webpart is hosted, so in terms of portability, you're good there.
  • The part of the query where you name the list you want to get items from is pretty self explanatory: .../lists/GetByTitle('Name of List here')/items. In your example you have LightBoxGallery. If the web part on a different site is supposed to look for a list with a different name, you are going to have to replace that part of the query with the correct list name. This makes portability difficult because now you have to have a separate script file for each list that's being queried, because the list name is hard coded into the query URL. This may not be such a big deal if you are hosting your scripts on each site in its Site Assets library or something, but if you were hoping to only have one script file in a centralized location, that's not really going to work well.
  • The third thing to keep in mind is that the script, as is, is assuming the list it is querying has the fields Title and a field with the internal name RequiredField. Title is fairly easy to assume because that's the most default of default SharePoint fields. But you're going to have to make sure that if you are querying different lists, they all have a field with the internal name RequiredField, or else you will have to modify the script to reflect querying for a differently named field.
  • Thank you @Dylan Cristy, one question I have is since this is a webpart that will be used in different sites and will be pulling data from different lists; I understand that this part from the previous code will allow you to just write the name of the list after listName and that will do it. Will that be necessary for this new code? ``` /**--List Name Below(case sensative)--/ listName: "Title of List Here", /--Site List Resides on (leave blank if same site)--**/ webURL: "", ``` – Juan Angelogianopulos Aug 15 at 16:50
  • @JuanAngelogianopulos updated my answer to address your comment. – Dylan Cristy Aug 15 at 18:06
  • very helpful. Thank you – Juan Angelogianopulos Aug 15 at 18:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.