Ostatnio napisałem kilka słów o tym jak wyświetlić dodatkowe pole na webpartcie z thumbnails view. W tym samym projekcie trzeba było rozwiązać problem z wyświetlaniem szczegółów wątku – na webpartcie odpowiedzialnym za dyskusje, jak użytkownik kliknie na temat dyskusji to domyślnie przekierowywany jest na stronę szczegółów wątku. Ogólnie rozwiązanie dobre jak lubimy cały czas klikać back w przeglądarce ;)
Ja miałem za zadanie zrobić to tak by jednak z tej strony na której jest webpart użykownik nie był przekierowywany dalej, ale by wyświetlić informację o szczegółach wątku najlepiej na tej samej stronie.
Po wielu godzinach i próbach, okazało się to niemożliwe z domyślnymi webpartami, a próbowałem wszystkiego :) Doprowadziłem już nawet do sytuacji, że prawie działało tak jak miało działąć:
- Użytkownik klika na nazwę wątku
- Po prawej/lewej/na dole/górze (w zależności gdzie drugi webpart jest umiejscowiony) pokazywały się szczegóły wątku
Do tego to wyglądało tak jak powinno wyglądać – 1-1 tak jak byśmy oglądali szczegóły wątku i listy wątków. Problem polegał na tym, że wątki działają na zasadzie katalogów i opierają się baaaaardzo mocno o query string. Na tyle mocno się opierają, że bez query stringa zawierającego ścieżkę do folderu i widoku, webpart szczegółów dyskusji nie będzie działał po stronie klienckiej. Po stronie serwerowej możemy to wszystko sobie zmocować jak chcemy. Więc mimo, że wszystko wyglądało jak należało i dodawanie kolejnych odpowiedzi do szczegółów wątku też działało, to za nic w świecie nie działało odświeżanie tego webparta. Odświeżanie nie działało, gdyż refresh był robiony (i dalej jest) na bazie aktualnego URLa przeglądarki, który gdzieś w bebechach całego JS API od SharePoint był ukrywany na tyle, że nie miałem możliwości go podmienić (albo mi się po prostu nie udało)./
Rozwiązaniem okazały się dwie opcje:
- Ablo iframe z załądowaną stroną – dość proste rozwiązanie, dodajemy opcję
IsDlg=1do query string i mamy minimalny szablon i każdy link otwierany będzie otwierany w nowym oknie. Minusy rozwiązania to próba dostosowania widoku tak by pasował do całej strony (suwaki itp. itd.), drugi ribbon plus problem z przechwyceniem kiedy powinien webpart zostać ukryty, czy przy zmianie widoku na liście wątku? Czy przy filtrowaniu listy wątków itp.? nagle z prostego rozwiązania zrobiło się dość skomplikowane, nie działające coś :) - Albo modal window – to samo co iframe ale w oknie, odpowiadamy, zamykamy i kontynuujemy dalej
Z iframe po kilku godzinach zrezygnowałem, i znów za pomocą JSLink osiągnąłem otwieranie każdego wątku w osobnym oknie.
Poniżej kod, jakby kogoś to interesowało (sposób instalacji taki sam jak ostatnio):
RegisterModuleInit("/_catalogs/masterpage/Discussion.js", RegisterDiscussionOverride);
RegisterDiscussionOverride();
function RegisterDiscussionOverride() {
if (typeof SPClientTemplates === 'undefined' || SPClientTemplates === null)
return;
// Setup the template override
var overrideCtx = {};
overrideCtx.Templates = {};
overrideCtx.BaseViewID = 3;
overrideCtx.ListTemplateType = 108;
// Register endHTML render handler
overrideCtx.OnPostRender = PostRenderDiscussionHandler;
// Register for template override
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
}
function PostRenderDiscussionHandler(ctx) {
try {
$('.ms-comm-postMainContainer.ms-comm-postSubjectColumn > a').click(function (evt) {
evt.preventDefault();
var $this = $(this),
href = $this.attr('href');
var dialog = SP.UI.ModalDialog.showModalDialog({
title: 'Some Title Disussion Thread View',
url: href,
autoSize: true,
width: 1024,
height: 800
});
return false;
});
}
catch (err) {
console.error(err);
}
}
Trzeba jeszcze tylko zmodyfikować webpart widoku tematów dyskusji by zawierał w polu JSLink wartośći:
// linie pociete, nalezy polaczyc w jedna SP.UI.Discussion.js| Discussion.js
PS.: mały bonus, skąd wiem, że jak jest IsDlg to link otworzy się w nowym oknie? stąd, że webparty msowe generują onclick dla a z wartością:
GoToLinkOrDialogNewWindow(this);return false;
a o to kod metody GoToLinkOrDialogNewWindow:
function GoToLinkOrDialogNewWindow(elm) {
if (elm.href == null)
return;
if (Boolean((ajaxNavigate.get_search()).match(RegExp("[?&]IsDlg=1"))))
window.open(elm.href);
else
GoToLink(elm);
}














