Creación de aplicaciones HTML5

Arrastrar y colocar con HTML5 en las listas de SharePoint

Andrey Markeev

Descargar el ejemplo de código

Como Microsoft SharePoint es una plataforma empresarial con una larga historia y una amplia variedad de características, no puede reaccionar siempre con la rapidez necesaria para seguir todas las tendencias de las tecnologías web emergentes. Pese a la amplia adopción empresarial de SharePoint y el gran esfuerzo por proporcionar una cantidad importante de características, SharePoint sigue retrasado en comparación con los productos para la administración de contenidos (CMS) modernos en términos de interfaces de usuario envolventes, como por ejemplo HTML5 y CSS3.

Personalmente, creo que HTML5 es más que solo una tecnología nueva de moda; tiene muchas ventajas prácticas: es sencillo, práctico y completo. Y además es reconocido, hasta cierto grado, por todos los exploradores modernos (inclusivo los exploradores de los dispositivos móviles). Además, HTML5 y JavaScript se están convirtiendo en un conjunto de tecnologías importantes para la programación de los escritorio en Windows.

Por lo tanto, HTML5 definitivamente merece su lugar en SharePoint para que los portales sean más amigables. Y las interfaces mejoradas en SharePoint permiten que los usuarios empresariales trabajen en forma mejor y más rápido.

Desafortunadamente, SharePoint no tiene integrada ninguna de las bondades de HTML5, pero es extremadamente flexible. En este artículo ejemplificaré cómo agregar la función de arrastrar y colocar de HTML5 a SharePoint fácilmente para mejorar la interfaz estándar al hacerla más fluida, tal como se observa en la Figura 1.

Drag and Drop in SharePointFigura 1 Arrastrar y colocar en SharePoint

Para la implementación usaré uno de los bloques de creación esenciales de SharePoint, que es también una de mis herramientas favoritas de SharePoint: la clase XsltListViewWebPart y sus transformaciones XSL. (Para obtener más información, consulte la página de MSDN Library en bit.ly/wZVSFx.)

¿Por qué no usar una elemento web personalizado?

Como siempre, en lo referente a la implementación, SharePoint ofrece una amplia variedad de posibilidades y es sumamente importante escoger la que resulte más útil.

Para el desafío que tenemos en mente, y considerando que arrastrar y colocar se usa principalmente para administrar datos, muchos desarrolladores de SharePoint probablemente preferirían crear un elemento web personalizado, que en este caso funciona igual que un control de ASP.NET corriente: los datos se almacenan en una lista estándar de SharePoint, se recuperan mediante el modelo de objeto o el control SPDataSource y se representan mediante el marcado de ASCX y los controles de ASP.NET.

Simple, claro, sin más complicaciones... ¿pero es esa la mejor opción?

Hace dos años, habría pensado que sí. Hoy prefiero personalizar XsltListViewWebPart mediante sus transformaciones XSL. ¿Por qué ese cambio de opinión?

Desde SharePoint 2010, casi todos los tipos de vistas de lista (con la excepción de los Calendarios) se muestran a través de este Elemento web. Imagínese: todos esos tipos de datos, todos esas vistas, estilos y tipos de listas distintos, toda esa gran variedad de datos se representa mediante XsltListViewWebPart y sus transformaciones XSL. Es una herramienta extremadamente flexible y poderosa.

Si optamos por crear nuestro propio Elemento web personalizado para representar el marcado HTML5 para mostrar los datos de las listas, perdemos todas las características integradas. Y la experiencia me ha enseñado que esto es una pérdida enorme. Por lo demás, no he visto ni un solo Elemento web personalizado que no termine integrando por lo menos la mitad de las características predeterminadas de XsltListViewWebPart.

Por lo tanto, mi plan es reutilizar las funciones existentes en vez de crear un Elemento web personalizado similar que probablemente sería mucho menos flexible y poderoso.

De hecho, XsltListViewWebPart incluye un puñado de características útiles. Está integrado con SharePoint Designer, es compatible con todas las conexiones de los Elementos web disponibles y representa correctamente todos los tipos de datos de SharePoint. Cuenta con funciones de agrupación, subtotales, paginación, menús contextuales de elementos, edición dentro de la línea, selecciones de elementos, indicadores de presencia, entre otros. Tiene una interfaz contextual en la Cinta, proporciona una interfaz de usuario para ordenar y filtrar los datos, ofrece algunos estilos básicos de vista y, nuevamente, otras cosas más. En síntesis, XsltListViewWebPart tiene una cantidad enorme de características útiles que sería difícil implementar manualmente en una solución con el Elemento web.

XsltListViewWebPart

XsltListViewWebPart ofrece muchos puntos de integración a los desarrolladores: una interfaz de programación, una interfaz para CAML y, por supuesto, transformaciones XSL junto con enlaces de parámetros. Y no olvidemos que todos estos objetos y propiedades también tienen sus representaciones en el Modelo de objetos del cliente, de manera que podemos obtener acceso a XsltListViewWebPart incluso desde JavaScript o Silverlight.

Por lo tanto, XsltListViewWebPart es una herramienta realmente poderosa. Es verdad que a primera vista todo este código XML (o XSLT) especializado para SharePoint resulta un poco intimidante, pero le mostraré algunas “soluciones salvadoras” para que pueda entender todo esto.

Escenario

Antes de profundizar en los detalles de la implementación, permítanme describir la situación general.

Lo que haré es que insertaré la función de arrastrar y colocar con HTML5 en las vistas de lista de SharePoint para permitir que los usuarios arrastren las celdas de una lista a otra. En este ejemplo usaré una lista llamada Tasks y una lista llamada Executors, para que el Administrador del proyecto pueda asignar y reasignar las tareas fácilmente, nada más con arrastrar los ejecutores a las celdas de la lista Tasks correspondiente.

Como sabrá, HTML5 cuenta con varios atributos nuevos para las funciones de arrastrar y colocar, de los cuales el más importante es el atributo “draggable”. Existen varios eventos para controlar las diferentes etapas del proceso de arrastrar y colocar. Las funciones controladoras de esos eventos se pueden adjuntar mediante los atributos correspondientes como “ondragstart,” “ondragend”, etc. (Para obtener más información, consulte el borrador de la especificación de HTML5 del World Wide Consortium [W3C], capítulo 7.6, en bit.ly/INL0FO).

En el caso del ejemplo, esto significa que solo tengo que usar XSLT para agregar algunos atributos básicos a ciertas celdas de la vista de lista, más probablemente algunos atributos personalizados adicionales para adjuntar los valores de los datos (que se transmitirán al arrastrar). Tarde o temprano tendré que proporcionar el código JavaScript correspondiente para las funciones del controlador.

Primeros pasos

Necesito dos listas. Puedo crear la lista Tasks a partir de la plantilla estándar Tareas o puedo simplemente crear una lista personalizada y agregar algunas columnas, entre ellas una columna de sitio “Assigned to”. Creo una segunda lista, Executors, como una lista personalizada, donde agrego “Executor” como una columna del tipo “Persona o grupo” y la establezco como obligatoria, indizada y única.

Como la lista Executors solo debe mostrar los nombres de usuario, no necesitamos la columna estándar “Título”. Para ocultar esta columna, voy a la configuración de la lista, habilito la administración de los tipos de contenido, voy al tipo de contenido “Elemento”, hago clic en la columna “Título” y oculto la columna, tal como aparece en la Figura 2.

Making the Title Column Hidden in SharePoint List SettingsFigura 2 Ocultar la columna Título en la configuración de la lista de SharePoint

Llené estas listas con datos de muestra y luego creé una página de Elemento web para mi panel, donde agregué estas listas lado a lado (con Tasks en el lado izquierdo y Executors en el derecho), tal como se indica en la Figura 3.

Adding the Lists to the SharePoint DashboardFigura 3 Agregar las listas al panel de SharePoint

Bien, ahora tengo las listas y los datos. Llegó el momento de implementar de la funcionalidad arrastrar y colocar propiamente tal.

SharePoint Designer

Microsoft SharePoint Designer es una herramienta completamente gratuita para el desarrollo rápido de aplicaciones SharePoint. SharePoint 2010 ha visto unas mejoras significativas respecto a SharePoint 2007 y hoy es una herramienta extremadamente útil, incluso para los desarrolladores. La idea es que puede usar la interfaz gráfica de usuario de SharePoint Designer para generar código XSLT realmente complejo y luego puede copiar y pegar el código generado en su proyecto de Visual Studio, en vez de tener que escribir a mano el código en XML/XLST; un proceso sujeto a errores y que no siempre cuenta con toda la documentación necesaria. Frecuentemente uso este truco en proyectos reales, y le aseguro que me permite ahorrar mucho tiempo.

Abro SharePoint Designer y voy a la página del panel que creé anteriormente. Selecciono una celda de la columna Assigned to (haga clic con el botón secundario y elija Seleccionar | Celda). Ahora viene la magia: en la barra de estado puedo ver la ruta de acceso a la plantilla XSL (y a la etiqueta HTML correspondiente dentro de la plantilla) que es responsable de mostrar esa celda específica (consulte la Figura 4).

The Path to the Current XSL Template in SharePoint DesignerFigura 4 Ruta de acceso a la plantilla XSL actual en SharePoint Designer

Esta información puede ser sumamente útil para determinar cuál es la plantilla XSL que hay que reemplazar para cambiar el marcado de las celdas. Podrá encontrar el código original de estas plantillas en la carpeta 14/TEMPLATE/LAYOUTS/XSL y usarlo en sus archivos XSLT propios o en la etiqueta <Xsl> de XsltListViewWebPart.

Pero no hace falta que me enfrente con estos archivos XSLT enormes y complicados para cumplir con mi meta. En lugar de eso, puedo usar la característica de formato condicional de SharePoint Designer que fue diseñada para destacar ciertas filas o celdas con un formato especial, de acuerdo con ciertas condiciones determinadas. No necesitamos ningún conocimiento especial para usar esta función, la interfaz de usuario gráfico facilita todo el trabajo. Tras bambalinas, todo se implementa con XSLT. Por lo tanto, SharePoint Designer incluye una especie de generador de XSLT gráfico listo para usar, y esto es lo que voy a usar ahora para mis propias necesidades.

Selecciono una celda, hago clic en el botón Formato condicional en la Cinta y selecciono Formato de columna, tal como se muestra en la Figura 5.

Setting Conditional Formatting in SharePoint DesignerFigura 5 Configuración del formato condicional en SharePoint Designer

A continuación creo una condición poco probable, donde el identificador es igual a cero, tal como aparece en la Figura 6

The Conditional Formatting Dialog in SharePoint DesignerFigura 6 Cuadro de diálogo de Formato condicional en SharePoint Designer

Después hago clic en el botón Establecer estilo y selecciono un estilo cualquiera (por ejemplo “text-decoration: underline”). Hago clic en Aceptar y paso a la pestaña Vista de código, donde localizo el código generado. Naturalmente se encuentra dentro de la etiqueta <Xsl> del control XsltListViewWebPart.

Transformaciones XSL

Ahora estoy listo para modificar el marcado de las celdas “Assigned to”. La columna “Assigned to” es el elemento que aceptará los datos donde arrastro a los ejecutores, y por lo tanto tengo que proporcionar los atributos “ondragover”, “ondragenter”, “ondragleave” y “ondrop”, que apuntarán a las funciones del controlador de eventos de JavaScript correspondientes.

El código generado por SharePoint Designer en el último párrafo contiene la plantilla XSL con la siguiente firma:

<xsl:template name="FieldRef_printTableCell_EcbAllowed.AssignedTo"
  match="FieldRef[@Name='AssignedTo']" mode="printTableCellEcbAllowed"
  ddwrt:dvt_mode="body" ddwrt:ghost="" xmlns:ddwrt2="urn:frontpage:internal">

Como probablemente sepa, las plantillas XSL pueden llamarse entre sí, ya sea por nombre o por condición. El primer tipo de llamada se realiza con el elemento “xsl:call-template” y es muy similar a una llamada de función, por ejemplo como la que se usaría en C#.

La segunda opción es preferible y mucho más flexible: el elemento “xsl:apply-templates” nos permite especificar el modo y el parámetro (que se selecciona con XPath y por lo tanto puede incluir varios elementos) sin especificar el nombre de ninguna plantilla. Para cada elemento de parámetro se hará coincidir la plantilla correspondiente mediante el atributo “match”. Puede imaginarse esta solución como algo similar a las sobrecargas en C#.

Como podrá apreciar en el código anterior, esta plantilla concordará con los elementos “FieldRef”, donde el atributo Name es igual a “AssignedTo”. Además, el atributo “mode” de la llamada xsl:apply-template correspondiente debe ser igual a “printTableCellEcbAllowed”. Por lo tanto, esta plantilla es esencialmente una sobrecarga para la función estándar que muestra los valores de los campos. Esta sobrecarga concordará solo con los valores del campo “Assigned to”.

Echemos ahora una mirada al interior de la plantilla que se muestra en la Figura 7 (para mayor claridad se eliminó parte del código).

Figura 7 Dentro de la plantilla XSL

<xsl:template match="FieldRef[@Name='AssignedTo']" mode="printTableCellEcbAllowed" ...>
  <xsl:param name="thisNode" select="."/>
  <xsl:param name="class" />
  <td>
    <xsl:attribute name="style">
      <!-- ... -->
    </xsl:attribute>
    <xsl:if test="@ClassInfo='Menu' or @ListItemMenu='TRUE'">
      <xsl:attribute name="height">100%</xsl:attribute>
      <xsl:attribute name="onmouseover">OnChildItem(this)</xsl:attribute>
    </xsl:if>
    <xsl:attribute name="class">
      <!-- ... -->
    </xsl:attribute>
    <xsl:apply-templates select="." mode="PrintFieldWithECB">
      <xsl:with-param name="thisNode" select="$thisNode"/>
    </xsl:apply-templates>
  </td>
</xsl:template>

Como podrá apreciar, la plantilla contiene dos elementos xsl:param, un elemento <td>, varios elementos xsl:attribute y un elemento xsl:apply-templates que se usa para aplicar algunas plantillas de bajo nivel.

Para lograr la funcionalidad de arrastrar y colocar agrego los atributos drag-and-drop al elemento <td>, del siguiente modo:

    <td ondragover="return UserDragOver(event, this)" ondragenter=
      "return UserDragOver(event, this)" ondragleave=
      "UserDragLeave(event, this)" ondrop="UserDrop(event, this)">

Es muy sencillo, ¿no?

Una alternativa que podría evaluar si tiene implementado jQuery en su entorno de SharePoint es adjuntar controladores de evento de JavaScript mediante el método .on de jQuery.

El marcado de la columna Assigned to ya está listo (escribiré los controladores un poco más adelante). Llegó la hora de personalizar la lista Executors.

Vuelvo a la pestaña Vista de diseño, selecciono una celda de la columna Executors y repito el truco del formato condicional para generar el código XSLT. Después agrego el atributo onstartdrag para asegurarme de que arrastrar y colocar se inicie correctamente (no necesito el atributo draggable aquí, puesto que los valores del campo “Persona o grupo” se representan como vínculos y, según las especificaciones, estos tienen el atributo draggable establecido en el valor “true” de manera predeterminada):

    <td ondragstart="UserDragStart(event, this)">

Genial. ¿Pero cómo voy a identificar los datos? ¿Cómo puedo determinar qué ejecutor se está arrastrando? Evidentemente, necesito su nombre de inicio de sesión o, mejor aún, su identificador. Analizar el identificador desde el interior del elemento TD es, en mi opinión, suficientemente complicado como para que carezca de sentido.

A lo que voy es que en XSLT para cualquier campo del tipo Persona o grupo el identificador de usuario está disponible y se puede recuperar mediante XPath con una sencilla consulta.

En esta consulta tengo que apuntar hacia los valores del elemento actual. En todas las plantillas corrientes de XsltListViewWebPart generalmente se usa el parámetro $thisNode para hacer referencia al elemento actual. Para recuperar el identificador del usuario, debo apuntar al un atributo del parámetro $thisNode que tenga el mismo nombre de la columna Persona o grupo, y al que se añade “.id” al final.

Esta es mi consulta:

    <td ondragstart="UserDragStart(event, {$thisNode/Executor.id}, this)">

Las llaves sirven para incluir la expresión XPath dentro del valor del atributo.

El marcado está listo, y de hecho ya se puede usar, pero probablemente sea una buena idea pulirlo un poco poder reutilizarlo mejor.

Cómo hacer que las plantillas sean reutilizables

Es posible que le haya llamado la atención que las plantillas están enlazadas estrechamente con los nombres de las columna específicas, y que están escritas de tal forma que solo se pueden usar con un par de listas determinadas. Sin embargo, resulta bastante sencillo modificarlas para poder usarlas con otras listas con columnas diferentes.

Para comenzar, si analizamos la firma de la plantilla que mostré previamente, encontramos el siguiente atributo:

match="FieldRef[@Name='AssignedTo']"

Evidentemente, esto vincula la plantilla con la columna Assigned to. Para ampliar un poco el alcance de esta plantilla, podemos reemplazar el enlace de nombres con un enlace de tipos para que concuerde cualquier columna Persona o grupo. ¡Que así sea! Este es el código:

match="FieldRef[@Type='User']"

Habrá que aplicar la misma modificación también en la segunda plantilla, donde el elemento FieldRef concuerda con el nombre interno del campo “Executor”.

Como ahora se puede tratar de cualquier columna del tipo Persona o grupo y cualquier lista, tengo que pasar información adicional a los controladores JavaScript. Cuando se realiza una operación de arrastrar y colocar, tengo que actualizar el valor de la columna Assigned to de la lista Tasks, de modo que debo conocer el nombre de la columna y el GUID de la lista.

Como mencioné anteriormente, SharePoint XSLT tiene algunos parámetros estándar disponibles en forma global. Uno de estos es $List, que almacena el GUID de la lista actual. Y el nombre interno del campo se puede recuperar fácilmente del elemento FieldRef concordante.

Por lo tanto, paso el GUID de la lista y el nombre interno de la columna al controlador UserDrop como se indica a continuación (omitiré los atributos “ondragenter”, “ondragover” y “ondragleave” para que el ejemplo quede más claro):

    <td ... ondrop="UserDrop(event, this, '{$List}', '{./@Name}'">

El “.” apunta al elemento actual FieldRef (que la plantilla hizo concordar previamente).

A continuación tengo que deshacerme de la cadena “Executor” en el parámetro id del XSLT de la lista Executors con el siguiente código:

    <td ondragstart="UserDragStart(event, {$thisNode/@*[name()=
      concat(current()/@Name, '.id')]}, this)">

Ahora las plantillas están listas y se pueden reutilizar, así que escribiré el código JavaScript correspondiente para implementar los controladores.

Escritura de los controladores en JavaScript

Aunque hay que escribir cuatro controladores distintos, en su mayoría son primitivos y bastante evidentes.

Generalmente recomiendo colocar este código en un archivo JavaScript separado. Además conviene usar Visual Studio para crearlo, para aprovechar los beneficios de IntelliSense. Pero en algunas circunstancias conviene colocar el código dentro de XSLT, lo que reemplaza la plantilla raíz (concordancia=“/”) para esta finalidad. Esto nos permite usar algunas variables y parámetros de XSLT en el código de JavaScript, y además no tendremos que preocuparnos por implementar archivos JavaScript.

Veamos entonces el código de los controladores: DragStart, DragEnter, DragOver, DragLeave y Drop.

En el controlador UserDragStart, tenemos que inicializar la transferencia de datos. Esto significa que deberá almacenar los datos arrastrados en un objeto DataTransfer especial de HTML5 parecido a este:

function UserDragStart(e, id, element) {
  e.dataTransfer.effectAllowed = 'copy';
  e.dataTransfer.setData('Text', id + '|' + element.innerHTML);
}

Observe que el identificador del usuario no es la única parte de los datos que se transfiere. También agregué el HTML interno del elemento <td> para no tener que actualizar la página después de colocar los datos (para obtener más información, consulte el código del controlador de UserDrop en la Figura 8).

Figura 8 Controlador del evento Drop

function UserDrop(e, toElement, listGuid, columnName) {
  // Terminate the event processing
  if (e.stopPropagation)
      e.stopPropagation();
  // Prevent default browser action
  if (e.preventDefault)
      e.preventDefault();
  // Remove styles from the placeholder
  toElement.style.backgroundColor = '';
  //toElement.className = '';
  // iid attribute is attached to tr element by SharePoint
  // and contains ID of the current element
  var elementId = toElement.parentNode.getAttribute('iid').split(',')[1];
  // Transferred data
  var data = e.dataTransfer.getData('Text');
  var userId = data.split('|')[0];
  var userLinkHtml = data.split('|')[1];
  // Setting value of the field using SharePoint
  // EcmaScript Client Object Model
  var ctx = new SP.ClientContext.get_current();
  var list = ctx.get_web().get_lists().getById(listGuid);
  var item = list.getItemById(elementId);
  item.set_item(columnName, userId);
  item.update();
  // Asynchronous call
  ctx.executeQueryAsync(
    function () { toElement.innerHTML = userLinkHtml; },
    function (sender, args) { alert('Drag-and-drop failed.
      Message: ' + args.get_message()) }
    );
  return false;
}

En este caso los controladores de los eventos DragEnter y DragOver son idénticos, de modo que creo una sola función. Debemos indicar en estos eventos que el usuario puede colocar sus datos aquí. Según la especificación, debemos llamar el método event.preventDefault para esta finalidad (de estar disponible) y devolver false.

El controlador DragEnter/DragOver es el lugar perfecto para aplicar estilos personalizados para el marcador de posición de arrastrar y colocar para notificar al usuario que efectivamente puede colocar los datos que está arrastrando. Para simplificar el ejemplo, usaré estilos CSS en línea, pero en un proyecto real recomiendo usar clases CSS (consulte las líneas comentadas que se muestran en la Figura 9).

Figura 9 Controladores de los eventos DragOver y DragLeave

function UserDragOver(e, toElement) {
  // Highlight the placeholder
  toElement.style.backgroundColor = '#efe';
  // toElement.className = 'userDragOver';
  // Denote the ability to drop
  if (e.preventDefault)
      e.preventDefault();
  e.dataTransfer.dropEffect = 'copy';
  return false;
}
function UserDragLeave(e, toElement) {
  // Remove styles
  toElement.style.backgroundColor = '';
  // toElement.className = '';

Evidentemente, en DragLeave tengo que eliminar los estilos aplicados anteriormente, tal como se muestra en la Figura 9.

Durante el evento Drop, en la Figura 8, tenemos que realizar dos acciones importantes:

  1. Aplicar los cambios. Mediante el modelo de objeto del cliente de EcmaScript de SharePoint, establecemos el valor del campo en el identificador del usuario transferido.
  2. Reemplazamos el código HTML interno de la celda actual (TD) con el código de la celda transferida para que los cambios aparezcan sin tener que actualizar la página.

Ahora están implementados todos los controladores y podrá implementar Java­Script. Es más, puede hacer esto en varias formas distintas: puede personalizar la página maestra, usar un control delegado, crear una acción personalizada con Ubicación establecida en “ScriptLink” o, como mencioné antes, incluir JavaScript directamente dentro de XSLT.

En este caso la forma más sencilla es personalizar el archivo de la página maestra con SharePoint Designer, puesto que no requiere de ningún conocimiento especial. Pero dado que usted es un desarrollador, es probable que quiera reunir todas estas personalizaciones de JavaScript y XSLT y crear una solución implementable. Pues bien, ¡pongamos manos a la obra!

Creación de una solución implementable

Para crear una solución lista para usar que pueda enviar a sus clientes, tenemos que realizar algunos pasos sencillos:

  1. Abra Visual Studio y cree un proyecto de SharePoint vacío. Seleccione “implementar como solución de granja” en el cuadro de diálogo de configuración del proyecto.
  2. Agregue la Carpeta asignada “Diseños” de SharePoint a su proyecto y agregue tres archivos nuevos: UserDragHandlers.js, UserDragProvider.xsl y UserDragConsumer.xsl.
  3. Pegue el código de JavaScript creado anteriormente y el código XSLT (generado con SharePoint Designer) en los archivos correspondientes.
  4. Agregue un proyecto del tipo Elemento vacío, abra Elements.xml y pegue el siguiente código:
            <CustomAction ScriptSrc="/_layouts/SPDragAndDrop/UserDragHandlers.js" Location="ScriptLink" Sequence="10" />
    Esto implementará el vínculo al archivo de JavaScript en todas las páginas del sitio.
  5. Para terminar, agregue un Receptor de eventos a Feature1 (que se creó automáticamente al agregar el elemento de proyecto Elemento vacío), quite la marca de comentario del método FeatureActivated y pegue el siguiente código dentro de este:
var web = properties.Feature.Parent as SPWeb;
        SPList list;
        SPView view;
        list = web.Lists["Tasks"];
        view = list.DefaultView;
        view.XslLink = "../SPDragAndDrop/UserDragConsumer.xsl";
        view.Update();
        list = web.Lists["Executors"];
        view = list.DefaultView;
        view.XslLink = "../SPDragAndDrop/UserDragProvider.xsl";
        view.Update();

Eso es todo. ¡Listo! Es muy sencillo, ¿no? Ahora, si crea e implementa la solución con las listas Tasks y Executors que creó anteriormente y después crea un panel que contiene vistas predeterminadas de cada uno de ellos, su panel contará con la característica útil de arrastrar y colocar.

Compatibilidad con los exploradores

Hoy en día, casi todos los exploradores importantes, salvo Opera, son compatibles con la función de arrastrar y colocar de HTML5. Probé Internet Explorer 9.0.8112.16421, Chrome 16.0.912.75 y Firefox 3.6.12; todos son completamente compatibles con esta solución. Me imagino que algunas versiones anteriores de esos exploradores también pueden funcionar. De hecho, también debería funcionar en Safari pero, en el momento de la redacción de este artículo, este explorador tiene algunos errores extraños en la implementación de arrastrar y colocar de HTML5 que impiden que la solución funcione como cabe esperar.

Próximos pasos

En mi solución, ni las plantillas XSLT ni el código en JavaScript contienen nada que se refiera específicamente a las listas: no hay GUID, nombres, títulos ni nada similar codificado de forma rígida. Por lo tanto, estas transformaciones se podrían aplicar en principio a cualquier lista o biblioteca de documentos y usted podría agregar compatibilidad con la funcionalidad de arrastrar y colocar a cualquier columna del tipo Persona o grupo. ¿No es esto genial?

Evidentemente, otros tipos de columnas también se pueden tratar de la misma manera, lo le permitiría, de hecho, crear una solución en la que todas las celdas en todas las listas de SharePoint sean arrastrables, para que los usuarios puedan arrastrar las celdas entre listas en las páginas del panel, lo cual también resulta práctico.

Otro desafío interesante sería implementar una función de arrastrar y colocar para las filas. La idea es esencialmente la misma, pero para poder obtener la plantilla apropiada, tendría que usar el formato condicional para las filas. Esto serviría para vincular los elementos de las listas o para cambiar su orden. Podría crear, por ejemplo, un vínculo “Papelera de reciclaje” en el menú de inicio rápido que funcione como un elemento que acepta arrastrar y colocar, y que funcione como una forma interesante de eliminar elementos de las listas.

Hay tantas cosas que se pueden hacer. Solo piense un poco, experimente e inténtelo. Su portal de SharePoint se volverá entonces un lugar mucho más agradable.

Andrey Markeev es un MVP de SharePoint Server que trabaja como desarrollador de SharePoint en Softline Group, en Rusia. Markeev es uno de los 10 expertos más importantes en SharePoint StackExchange (bit.ly/w9e4NP), el creador de varios proyectos de código abierto en CodePlex y es un orador y bloguero activo. Puede seguirlo por Twitter en twitter.com/amarkeev.

Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo: Michael Nemtsev y Brandon Satrom