Usar Select2 para filtrar listas de SharePoi con API REST - Blog de David Alonso. Microsoft SharePoint, Office 365, Azure y otras tecnologías Microsoft

Blog de David Alonso. Microsoft SharePoint, Office 365, Azure y otras tecnologías Microsoft

Microsoft SharePoint, Azure, Office 365

miércoles, 8 de noviembre de 2017

Usar Select2 para filtrar listas de SharePoi con API REST


Hace poco me paso que tenia que mostrar un dropdown list con datos de una lista, que obtenia haciendo una llamada a la API REST de SharePoint.

Como sabeis, esa llamada por defecto me devuelve (creo que 100) items, pero añadiendole a la llamada un top=n  me devolverá mas. No obstante, me va a devolver tantos elementos como el umbral de la lista tenga marcado.

Se nos ocurrio mejorar esto utilizando el componente select2 https://select2.org.

El objetivo es disponer de un dropdownlist, además de un cuadro de texto que va autocompletando con los datos de la lista.

De esta forma segun escribimos en el cuadro de texto, irá filtrando elementos de la lista y mostrandolos. Además permite hacer paginacion de la misma.

Empiezo con un ejemplo:

1. Lo primero que hay que hacer es añadir el scriopt select2 y su css a la página:

2 . A continuación, añadimos en la página un elemento de tipo select con un class específico. 
   <select class="sharepoint-select2"></select>
 3. Despues usamos el siguiente trozo de código javascript:

 $('.sharepoint-select2').select2({     
    width: '200px', 
    ajax: {
url: function (params, data) { return _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle('LISTNAME')/items?$top=30&$select=COLUMNS&$filter=startswith(COLUMNAME,'" + params.term + "')"; //fijarse que hago un top30 para tener bloques de 30 elementos
}, 
    dataType: 'json',   
    data: function (params) {
        var query = {        
        page: params.page || 1
      }      
      return query;
     }, 
    processResults: function (data, params) {
  params.page = params.page || 1;         
  //ESTA PARTE ES IMPORTANTE EN SELECT2 4.0
           var select2Data = $.map(data.value, function (obj) {
                        obj.id = obj.COLUMNID;
                        obj.text = obj.COLUMNTEXT;
                        return obj;
                     });
                return {
 results: select2Data ,
  pagination: {
  more: true //paginará siempre            
 }                
};     
},    
        cache: true
 },  
    placeholder: 'Selecciona un elemento ... ',      
  escapeMarkup: function (markup) { return markup; }, 
  minimumInputLength: 1,
  templateResult: formatData ,
    templateSelection: formatDataSelection
  });
}

donde las funciones formatData y formatDataSelection:
function formatData (data) { 
      //Aqui puede devolverse html para pintar un bloque con varios datos ,       
      // /imagenes etc..     
          return  data.COLUMNTEXT;
        }

function formatDataSelection (data) {
      return data.COLUMNID;
   }


4. Por ultimo, para páginar yo lo que hice fue manejar 2 variables (ultimo ID de elemento de lista y ultimo texto añadido)
var lastID = -1;
var lastTerm = "";
 $('.js-data-example-ajax').select2({   


Cuando se va a sacar la url, se comprueba primero si ha cambiado el cuadro de texto (es nueva busqueda) y en caso de que haya cambiado, reseteo el id a -1.

if(lastTerm != params.term)  
       thisID = -1;

Despues hago una query u otra dependiendo del id. Si es -1 la query anterior y sino lo que hago es ordenar por D, y devolver aquellos con ID > el idGuardado (lastID)

if(thisID == -1)
  return  LLAMADA ANTERIOR;
 else
  return _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle('LISTNAME')/items?$top=30&$select=COLUMNS&$filter=(startswith(COLUMNNAME,'" + params.term + "') and (ID gt "+lastID +"))";

Hay que fijarse que el filtro lo hago con un startswith, es decir, que empiecen por el texto que introduzco. 

En rpocessResults, guardo el latID y el lastTerm:

processResults: function (data, params) {
params.page = params.page || 1;
if(data.value.length > 0)
{
thisID = data.value[data.value.length-1].ID;
lastTerm = params.term;
}

Lo unico raro, es que si continuas haciendo scroll, siempre te aparece el texto  de Loading more results. Para quitarlo habria que controlar que no haya mas elementos.

Espero que os sea util.

Un saludo






No hay comentarios:

Publicar un comentario