Arquitectura, buenas prácticas y desarrollo sobre la nueva herramienta de Microsoft SharePoint 2016

SharePoint: añadir Valoración a las noticias

EstrellasMuchas veces he escrito sobre la capacidad que existe en SharePoint de emplear utilidades ya implementadas por el propio servidor. Estos componentes nos facilitan mucho el desarrollo y, por regla general, son bastante configurables.

En esta ocasión, vamos a destripar el componente de «Rating» /Valoración que se le puede agregar a las bibliotecas de SharePoint de documentos y noticias de forma simple. Un requerimiento muy habitual en las Intranet es poder otorgar la funcionalidad de valorar la noticia por parte del usuario que la está leyendo. Y a través este componente lo podemos hacer sin problemas.

¿Empezamos?

Para empezar a utilizar este componente, lo podemos activar a través de la interfaz gráfica. Vamos a la configuración de la biblioteca de documentos/ páginas y activar el rating.
configuracion

El rating puede ser de dos formas: LikeEstrellas.

Configuracion2

Activarlo mediante la interfaz gráfica puede ser una solución que utilicen los usuarios avanzados/usuarios finales de SharePoint, pero en nuestros desarrollos debemos de dotar de la calidad de realizarlo sin hacer click (o minimizar el número de clicks a realizar). Para ello, vamos a activar esta funcionalidad con el siguiente script de PowerShell:

Param
(
    [Parameter(Mandatory=$true)]
    [string]$UrlWeb = $(Read-Host -Prompt "Web Url")
)
Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
$web=Get-SPWeb $UrlWeb;
$list=$web.Lists["Páginas"];
if($list -ne $null)
{
 Write-Host $list.Title "not null";
 $assembly=[System.Reflection.Assembly]::Load("Microsoft.SharePoint.Portal, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
 $reputationHelper =$assembly.GetType("Microsoft.SharePoint.Portal.ReputationHelper");
 $bindings = @("EnableReputation", "NonPublic", "Static");
 [System.Reflection.BindingFlags]$flags = [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic;
  $methodInfo = $reputationHelper.GetMethod("EnableReputation", $flags);
 #For enabling Ratings
 $values = @($list, "Ratings", $false);
 #OR for enabling Likes
 #$values = @($list, "Likes", $false);
 $methodInfo.Invoke($null, @($values));
  #For disable Rating or Likes
 <#$methodInfo = $reputationHelper.GetMethod("DisableReputation", $flags);
 $disableValues = @($list);
 $methodInfo.Invoke($null, @($disableValues));#>
}

Una vez lo tenemos activado, tenemos que ver cómo poder utilizar este componente tanto en los DisplayTemplate como en nuestro código C# bien en PageLayout o nuestros WebParts.

Utilizarlo en DisplayTemplate

En primer lugar, nos hemos creado un Módulo con todas las funcionalidades que tenemos para obtener las estrellitas y para generar el HTML que renderizará el valor de las mismas. El código seria el siguiente:

var Encamina = Encamina || {};
Encamina.Ratings = function () {
    var ratings = {
        termStoreName: '',
        termSetId: '',
        currentTerm: '',
        root: this,
        MenuItem: function (title, url) {

        },
        currentMenuItems: new Array(),
        init: function (termName, termId, current) {
            this.termStoreName = termName;
            this.termSetId = termId;
            this.currentTerm = current;
        },
        GenerateRatingStars: function (rating, ratingCount) {
            var decRating = rating.value - Math.floor(rating.value);
            var totalStars = 5;
            var html = "";
            if (ratingCount == "") {
                ratingCount = 0;
            }
            var filledImage = "/_layouts/15/images/RatingsSmallStarFilled.png";
            var emptyImage = "/_layouts/15/images/RatingsSmallStarEmpty.png";
            var halfImage = "/_layouts/15/images/RatingsSmallStarLeftHalfFilled.png";
            html += "<div class='ms-comm-noWrap'><span id='averageRatingElement-" + rating + "'>";
            for (var i = 0; i < totalStars; i++) {
                var count = i + 1;
                var img = emptyImage;
                if (count <= rating) {
                    img = filledImage;
                } else if (decRating > 0) {
                    img = halfImage;
                    decRating = 0;
                }

                html += "<span class='ratingsImageContainer star-' data-starnumber='" + count + "'>";
                html += "<img id='averageRatingElement-" + rating + "-img-" + count + "' src='" + img + "'/>";
                html += "</span>";
            }
            html += "</span><span class='ms-comm-ratingSeparator'/>";
            html += "<span class='ms-comm-ratingCountContainer' id='averageRatingElement-" + ratingCount + "-count'>";
            html += "&nbsp;" + ratingCount + "</span></span></div>";
            return html;
        },
        UpdateRating: function (siteUrl, listId, listItemId, context) {
            return function (element, arguments) {
                var rating = element.currentTarget.dataset.starnumber;

                function RatingSuccess(sender, args) {
                    SP.UI.Notify.addNotification('Valoración actualizada', false);
                    var queryState = new Srch.QueryState();
                    var queryStateArgs = new Srch.QueryEventArgs(queryState);
                    debugger;
                    context.ClientControl.raiseQueryReadyEvent(queryStateArgs);
                }

                function RatingFailure(sender, args) {
                    SP.UI.Notify.addNotification('Error actualizando valoración:' + args.get_message(), false);
                }

                if (rating != null && rating != "" && !isNaN(rating)) {
                    var spCtx = new SP.ClientContext(siteUrl + "/AlDia/Circulares");
                    Microsoft.Office.Server.ReputationModel.Reputation.setRating(spCtx, listId, listItemId, parseInt(rating));
                    spCtx.executeQueryAsync(Function.createDelegate(this, RatingSuccess), Function.createDelegate(this, RatingFailure));
                }

            };
        }
    };
    return ratings;
}();

Una vez tenemos estos valores, dentro de la plantilla del DisplayTemplate, deberemos de indicar la siguiente llamada:

<!--#_
            function SearchRating(avgRating, ratingCount, selector, siteUrl, listId, listItemId, context) {
                var stars = $("#" +selector+ " .ratingsImageContainer");
                stars.on("click", Encamina.Ratings.UpdateRating(siteUrl, listId, listItemId, context));
            }

     var AverageRating = $getItemValue(ctx, "AverageRating");
	 var RatingCount = $getItemValue(ctx, "RatingCount");
            var RatingDisplay = Encamina.Ratings.GenerateRatingStars(AverageRating, RatingCount);
            AddPostRenderCallback(ctx, function() {
                SearchRating(AverageRating, RatingCount, ratingsId, siteUrl, listId, listItemId, ctx);
            });

        _#-->

Utilizarla en los PageLayout

Para utilizarlo dentro de los PageLayouts, primero debemos registrar el componente en la cabecera del ASPX:

<%@ Register TagPrefix="SharePointPortalControls" Namespace="Microsoft.SharePoint.Portal.WebControls"  Assembly="Microsoft.SharePoint.Portal, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

A continuación, con añadir la siguiente línea ya tendremos disponible las estrellitas en nuestro desarrollo:

   <SharePointPortalControls:AverageRatingFieldControl ID="PageRatingControl" FieldName="AverageRating" runat="server"/>

Aunque… ¡¡esto no podía ser tan sencillo como parece!! Existe un bug reconocido: la primera vez que se carga la página con las estrellitas no se muestran las imágenes en Internet Explorer. Esto es debido al orden de carga de los ficheros de JavaScript propios de SharePoint. ¡SOLUCIÓN! Tenemos que añadir una función JavaScript, que hará que una vez que esté cargada la página, muestre las estrellas. Para ello podemos utilizar el siguiente código:

<script type="text/javascript">
    function fixIE10StarRatingIssue() {
        if (SP.UI.Reputation != null) {
            SP.UI.Reputation.RatingsHelpers.$c(false);
            jQuery('.votacion > script').each(function () {
                eval($(this).text());
            });
        }
    }
    _spBodyOnLoadFunctionNames.push('fixIE10StarRatingIssue');
</script>

Referencias

http://almondlabs.com/blog/adding-interactive-ratings-to-sharepoint-2013-search-results-part-2/
http://weblogs.asp.net/bsimser/adding-ratings-and-comments-to-sharepoint-publishing-pages
http://community.rightpoint.com/blogs/viewpoint/archive/2014/10/19/add-comments-and-ratings-to-a-sharepoint-2013-page-layout-using-design-manager.aspx

mm

Sobre Adrián Díaz

Adrián Díaz es Ingeniero Informático por la Universidad Politécnica de Valencia. Es MVP de Microsoft en la categoría Office Development desde 2014, MCPD de SharePoint 2010, Microsoft Active Profesional y Microsoft Comunity Contribuitor 2012. Cofundador del grupo de usuarios de SharePoint de Levante LevaPoint. Lleva desarrollando con tecnologías Microsoft más de 10 años y desde hace 3 años está centrado en el desarrollo sobre SharePoint. Actualmente es Software & Cloud Architect Lead en ENCAMINA.
Esta entrada ha sido publicada en out of the box y etiquetada como , , . Enlace permanente .
Suscríbete a Desarrollando sobre SharePoint

Suscríbete a Desarrollando sobre SharePoint

Recibe todas las actualizaciones semanalmente de nuestro blog

You have Successfully Subscribed!

ENCAMINA, piensa en colores