Поставили задачу оперативно организовать на локальном сайте SharePoint конкурс детских рисунков с голосованием. Чтобы не изобретать велосипед было решено использовать встроенный в SharePoint 2013 функционал “Библиотеки рисунков” с включённым механизмом оценок. Однако первые же тесты показали, что на имеющейся у нас в данный момент версии - SharePoint Server 2013 Standard SP1 (15.0.4571.1502), некорректно работает отображение результатов оценки/голосования при отображении в виде звёзд. В случае, если общая сумма оценок получалась такой, что должно было отображаться половина звезды – все звёзды отображались вообще пустыми. Изучение проблемы привело к выводу, о том, что в коде, хранящемся в БД есть ошибка при использовании неверного знака разделителя дробной и целой части. Эту гипотезу подтверждало также то, что на английской версии шаблона сайта проблема не воспроизводилась. В конечном итоге от проблемы удалось избавиться установив последнее кумулятивное обновление KB2889944 - November 11, 2014 Cumulative Update for SharePoint Server 2013 package.
Теперь кратко пробежимся по шагам которые необходимо выполнить для решения нашей задачи.
Шаг #1. Добавляем список на сайт на основе шаблона списка “Библиотека рисунков”. Для оперативности сделаем PowerShell-скриптом:
Add-PSSnapin Microsoft.SharePoint.PowerShell $url = "http://kom-ad01-web01.holding.com" $listName = "ChildPict2014" $listDisplayName = "Конкурс детских рисунков" $web = Get-SPWeb -Identity $url $listTemplate = $web.ListTemplates["Picture Library"] $web.Lists.Add($listName, "", $listTemplate) $list = $web.Lists[$listName] $list.Title = $listDisplayName $list.TitleResource.SetValueForUICulture($web.UICulture, $listDisplayName); $list.Update() $web.Dispose()
Шаг #2. Переходим в “Параметры списка” > “Параметры оценок”. Включаем функционал оценок (Если “Параметры оценок” недоступны, то надо активировать возможность на уровне семейства сайтов “Инфраструктура публикации Sharepoint Server”)
Шаг #3. Создадим вычисляемый столбец (“Параметры списка” > “Создать столбец”) с именем “Сумма баллов”
В качестве формулы введём значение:
ОКРУГЛ([Оценка (0-5)]*[Число оценок];0)
Тип данных определим как “Число”
Шаг #4. Настроим основное представление. В параметрах списка в перечне имеющихся представлений выберем представление “Все рисунки”.
Включим для представления признак “Сделать представлением по умолчанию”:
Настроим отображаемые столбцы примерно следующим образом:
Настроим сортировку по полю “Сумма баллов” по убыванию:
Шаг #5. Добавим веб-часть для обновления контента страницы без её полной перезагрузки в случае изменения суммы баллов. Перейдём на страницу отображения представления “Все рисунки” и добавим на страницу дополнительную веб-часть “Редактор сценариев”.
Найти веб-часть “Редактор сценариев” можно в категории “Среда и контент”.
В добавленную веб-часть “Редактор сценариев” введём java-скрипт использующий объектную модель Java Script Object Model for Sharepoint (JSOM):
<script type="text/javascript"> EnsureScriptFunc('mQuery.js', 'm$', function () { m$.ready(function () { function onSuccess() { var evtAjax = { currentCtx: ctx, csrAjaxRefresh: true }; ctx.skipNextAnimation = true; AJAXRefreshView(evtAjax, SP.UI.DialogResult.OK); setTimeout(AddEvents, 3000); } function AddEvents() { var table = ctx.ListData.Row; for (var row = 0; row < table.length; row++) { for (var j = 1; j <= 5; j++) { var id = "averageRatingElement-" + table[row].ID + "-img-" + j; m$('#' + id).click(function () { setTimeout(onSuccess, 2000); }); } } } AddEvents(); }); }); </script>
Содержимое этой веб-части будет скрыто от глаз пользователей и оно будет отвечать за то, чтобы при нажатии на звездочки без перезагрузки страницы обновлялось поле “Сумма баллов” и динамически перестраивалась позиция рисунков в соответствии с правилом сортировки.
***
Добавляем в библиотеку рисунков отсканированные изображения детских рисунков и размещаем ссылку на страницу в элементах навигации сайта. Результат будет иметь примерно следующий вид:
После того, как период голосования подошёл к концу и нужно подводить итоги, в параметрах списка отключаем функционал оценок.
PS: Выражаю благодарность за предоставленную последовательность действий и java-скрипт Владимиру Землякову.
Отличное решение! Только у меня вопрос-замечание: это получается голосование не за одну понравившуюся фотографию, а хоть за сколько проголосовать можно, что-то типа "лайков", а понравиться могут все. А нужно за одну проголосовать...
В этом случае придется писать Farm Solution или Sandbox Solution, на cписок вещать event receiver, в котором будет отслеживаться голосовал ли уже пользователь. Я б наверное делал так.
В нашем случае перед нами такой задачи не стояло и мы воспользовались стандартным функционалом оценок.
А у меня код виден на странице =)
Владимир, спасибо большое за статью. А расскажите более подробно про голосование только за одну фотографию, может у вас уже есть наработки какие-то?
К сожалению таких наработок нет.