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=1
do 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); }