简体   繁体   中英

Scrape Table Data and convert to an Unordered List with jQuery

I have a Sharepoint webpart that cannot be customized - it generates a massive nest of tables before getting to the actual data table.

I want to use jQuery to scrape the data from each cell and add it to a list item using spans with classes in order to style it as its not really tabular data but thats how sharepoint provides values to variables I need in my page; I need this to repeat for each row to create several list items.

I have observed that the data begins 4 tables in - crazy I know but thats how MS go about laying out components, so I have been targeting similar to:

$('table table table table tr td').html();

I would like to generate a list of structure:

<ul>
 <li>
  <span class="name">Name</span>
  <span class="points">Points</span>
 </li>
 <li>...
</ul>

The rendered Sharepoint Table is (ignoring the outer tables) of the format as below and I wrap a DIV with uniqueID around the webpart in order to assist with targeting

<div id="uniqueID">
 <table>
    <tr>
        <td>John Doe</td>
        <td>50</td>
    </tr>
 </table>
</div>

Hope someone can assist with how to convert this to a formatted list

Thanks

If I understood you correctly than $('table table table table tr td').html() returns you the <div id="uniqueID">...</div> part.

If that's correct than you can use the map() function of jquery to cycle through the original Nodes and return an array of new nodes. I don't know exactly from which container you get the original list, so I added a placeholder PARENTNODE to the original query, you need to modify that.

var ul = $('<ul/>');
var originalItems = $('table table table table tr td', PARENTNODE);
var items = $.map( originalItems, function(i,node){
  var dataCells = $(node).find('table tr td'),
      li = $('<li/>');

  li.append( '<span class="name">'+ dataCells.eq(0).text()+'</span>'  );
  li.append( '<span class="points">'+ dataCells.eq(1).text()+'</span>'  );

  return li;
});

ul.append( items );

and of course you can make it a little shorted by putting the map into the append:

...
ul.append( $.map( ... ) )
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
</head>
<body>
    <div id="uniqueID">
        <table>
            <tr>
                <td>John Doe</td>
                <td>50</td>
            </tr>
            <tr>
                <td>John Doe1</td>
                <td>500</td>
            </tr>
        </table>
    </div>
    <div id="list">
    </div>
</body>

<script type="text/javascript">
    $(document).ready(function () {
        var str = "<ul>";
        $('tr').each(function (index, responce) {
            str += "<li> <span class=\"name\">" + $($($(this).children())[0]).text() + "</span><span class=\"points\">" + $($($(this).children())[1]).text() + "</span></li>";
        });
        str += "</ul>";
        $('#list').html(str);
    });
</script>
</html>

You can use SharePoint 2010's JavaScript client object model to access SharePoint list/library data from JavaScript without having to parse rendered HTML.

In SharePoint 2010, to run some JavaScript on a page (without messing around with SharePoint Designer or Visual Studio), you can:

  1. Place a combination of HTML and JavaScript in a text file
  2. Save the text file to a document library on your site
  3. Add a Content Editor web part to a page where you want the HTML/JavaScript to display/execute
  4. Edit the properties of the web part
  5. In the Content Link property you can paste in the path to your text file

The embedded JavaScript will then run when that web part loads, and the HTML will display wherever you place it. (Note that SharePoint 2013 introduced the Script Editor web part, simplifying this process somewhat.)

As a reference for getting started with the JavaScript client object model, here's a barebones example:

<ul id="PointList"></ul>
<script>
    var pointList = document.getElementById("PointList");

    ExecuteOrDelayUntilScriptLoaded(loadListData,"SP.JS");

    function loadListData(){
        var clientContext = new SP.ClientContext();
        // Replace "Example List" with your list's title below:
        var list = clientContext.get_web().get_lists().getByTitle("Example List");
        var camlQuery = new SP.CamlQuery();
        // use a CAML query to retrieve a set of list items:
        camlQuery.set_viewXml(
            '<View><Query>'+
            '<Where>'+
            //    '<BeginsWith>'+
            //        '<FieldRef Name=\'Title\' /><Value Type=\'Text\'>A</Value>'+
            //    '</BeginsWith>'+
            '</Where>'+
            '<OrderBy>'+
            //    '<FieldRef Name=\'Modified\' />'+
            '</OrderBy>'+
            '</Query></View>');
        var items = list.getItems(camlQuery);
        clientContext.load(items);
        clientContext.executeQueryAsync(
            /* code to run on success: */
            Function.createDelegate(this,
                function(){
                    var item, itemEnumerator = items.getEnumerator();
                    while(itemEnumerator.moveNext()){
                        item = itemEnumerator.get_current();
                        // Replace "Title" and "Points" with the 
                        // internal names of your fields below:
                        addHTML(item.get_item("Title"), item.get_item("Points"));
                    }
                }
            ),
            /* code to run on error: */
            Function.createDelegate(this,
                function(sender,args){
                    alert(args.get_message());
                }
            )
        );
    }
    function addHTML(name, points){
        var li = document.createElement("li"),
         nameSpan = document.createElement("span"),
         pointSpan = document.createElement("span");
        pointList.appendChild(li);
        li.appendChild(nameSpan);
        li.appendChild(pointSpan);
        nameSpan.innerHTML = name;
        pointSpan.innerHTML = points;
    }
</script>

I commented out the inner elements of the Where and OrderBy clauses in the CAML query so that it'll just grab everything in the default order, but you can still see the general format. By changing that CAML query, you can grab a filtered subset of items and/or get them in a particular order. (For more details on CAML syntax, check out this answer .)

Here are a few good JavaScript references from Microsoft for further research:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM