Forum Discussion
Adding a List Item to a Project Detail Page in Gallery format
Hello John Passaro ,
There wont be a webpart for the classic PDPs to show the gallery view on a modern list - I think you'd need to build (code) that yourself.
Will this central list on the root site contain items for each project? Out of the box you wont be able to filter the list items for the current project on that PDP, the list view will show all items in the list view used. Where the list is a central list on the root site or a list on the project site, you will need a custom solution to display the filtered / specific content for that project on the PDP. These blog posts might help:
The code isn't available on the download link anymore but I can share it here if needed (it will need updating / testing / making suitable for production use as it is very old - it might not event work anymore!)
Paul
- John PassaroOct 15, 2021Copper ContributorAnything you can share would be greatly appreciated. I will also look at the links you provided. Thank you very much.
- Paul_MatherOct 15, 2021MVP
Hello John Passaro ,
Please see the code samples below (these will need testing / changing / making suitable for production etc.) These were written many many years ago and might no loner work:
Showing lists from the Project sites on PDPs in an iframe:
</style> <script type="text/javascript"> $(document).ready(function () { getProjectUID(); }); var projects; SP.SOD.executeOrDelayUntilScriptLoaded(GetProjects, "PS.js"); //get project UID from the URL function getProjectUID(){ var urlStr = unescape(window.location) if (urlStr.toLowerCase().indexOf('projuid')>=0) { projUid = urlStr.substr(urlStr.indexOf("=")+1,36) } else { $("#messages").html("Not available in this context. Not a Project Server Project Detail Page or project associated"); $("#buttons").hide(); } } function GetProjects() { var projContext = PS.ProjectContext.get_current(); projects = projContext.get_projects(); projContext.load(projects, 'Include(Name, Id, ProjectSiteUrl)'); projContext.executeQueryAsync(onQuerySucceeded, onQueryFailed); } function onQuerySucceeded(sender, args) { var projectEnumerator = projects.getEnumerator(); var proj; while (projectEnumerator.moveNext()) { var project = projectEnumerator.get_current(); if (project.get_id() == projUid) { proj = project; } } projSiteUrl = proj.get_projectSiteUrl(); showRisks(); } function onQueryFailed(sender, args) { $get("spanMessage").innerText = 'Request failed: ' + args.get_message(); } function showRisks() { $("#issueDiv").hide(); $("#riskDiv").show(); $("#riskTable").html('<object width="950" height="800" data= "'+projSiteUrl+'/Lists/Risks/AllItems.aspx?isdlg=1"/>'); $("#riskBtn").addClass("selectedBtn").removeClass("deselectedBtn"); $("#issueBtn").removeClass("selectedBtn"); } function showIssues() { $("#riskDiv").hide(); $("#issueDiv").show(); $("#issueTable").html('<object width="950" height="800" data= "'+projSiteUrl+'/Lists/Issues/AllItems.aspx?isdlg=1"/>'); $("#riskBtn").removeClass("selectedBtn"); $("#issueBtn").addClass("selectedBtn").removeClass("deselectedBtn"); } </script>
You will need to ensure jQuery etc. are loaded on the page too. You then just need the HTML and CSS to such as:
<div id="divMessage"> <br/> <span id="spanMessage" style="color: #FF0000;"></span> </div> <p id="messages"></p> <div id="buttons"> <button type='button' id="riskBtn" class='deselectedBtn' onclick="showRisks()" >Display Risks</button> <button type='button' id="issueBtn" class='deselectedBtn' onclick="showIssues()">Display Issues</button> </div> <div id="riskDiv" style="display:none"> <h1>Risk List</h1> <div id="riskTable"></div> </div> <div id="issueDiv" style="display:none"> <h1>Issue List</h1> <div id="issueTable"></div> </div> <style type="text/css"> .selectedBtn { background-color: grey; color: white; text-decoration: underline; } .deselectedBtn { background-color: white; color: black; text-decoration: none; } </style>
The other example calls the SharePoint API's (the list svc - I'd change that to use the newer _api/web/ API) and puts the data into a table on the page - this is very old so definitely needs some work / rewriting:
<script type=text/javascript> var urlStr = unescape(window.location) if (urlStr.toLowerCase().indexOf('projuid')>=0) { var projUid = urlStr.substr(urlStr.indexOf("=")+1,36) } else { document.write("Not available in this context. Not a Project Server Project Detail Page or project associated"); } var projects; SP.SOD.executeOrDelayUntilScriptLoaded(GetProjects, "PS.js"); function GetProjects() { var projContext = PS.ProjectContext.get_current(); projects = projContext.get_projects(); projContext.load(projects, 'Include(Name, Id, ProjectSiteUrl)'); projContext.executeQueryAsync(onQuerySucceeded, onQueryFailed); } function onQuerySucceeded(sender, args) { var projectEnumerator = projects.getEnumerator(); var proj; while (projectEnumerator.moveNext()) { var project = projectEnumerator.get_current(); if (project.get_id() == projUid) { proj = project; } } projSiteUrl = proj.get_projectSiteUrl(); ko.applyBindings(new KoSpModal1(), riskDiv); ko.applyBindings(new KoSpModal2(), issueDiv); } function onQueryFailed(sender, args) { $get("spanMessage").innerText = 'Request failed: ' + args.get_message(); } </script> <script type="text/html" id="risktable"> <tr> <td data-bind="text:Title"></td> <td data-bind="spDate:DueDate,defaultValue:' NA'"></td> <td data-bind="spChoice:Status"></td> <td data-bind="spNumber:Cost,dataFormat:'£0.00',defaultValue:'£0.00'"></td> <td data-bind="spNumber:Probability,dataFormat:'0.00 %',defaultValue:'0.00 %'"align="center"></td> <td data-bind="spNumber:Impact,dataFormat:'0.00'"align="center"></td> <td data-bind="spUser:AssignedTo"></td> </tr> </script> <script type="text/javascript"> function KoSpModal1() { var self = this; self.Items = ko.observableArray([]); $.getJSON(projSiteUrl + "/_vti_bin/listdata.svc/Risks?$expand=Status,AssignedTo&$select=Title,DueDate,Status,Cost,Probability,Impact,AssignedTo", function (data) { if (data.d.results) { self.Items(ko.toJS(data.d.results)); } } ) } </script> <script type="text/html" id="issuetable"> <tr> <td data-bind="text:Title"></td> <td data-bind="spDate:DueDate,defaultValue:' NA'"></td> <td data-bind="spChoice:Status"></td> <td data-bind="spChoice:Priority"></td> <td data-bind="spUser:AssignedTo"></td> <td data-bind="spUser:ModifiedBy"></td> </tr> </script> <script type="text/javascript"> function KoSpModal2() { var self = this; self.Items = ko.observableArray([]); $.getJSON(projSiteUrl + "/_vti_bin/listdata.svc/Issues?$expand=Status,Priority,AssignedTo,ModifiedBy&$select=Title,DueDate,Status,Priority,AssignedTo,ModifiedBy", function (data) { if (data.d.results) { self.Items(ko.toJS(data.d.results)); } } ) } </script>
Then the HTML / CSS:
<div id="divMessage"> <br/> <span id="spanMessage" style="color: #FF0000;"></span> </div> <style type="text/css"> .tableGrid th { width:2%; padding:4; border:1px solid; } .tableGrid td { padding:2; border:1px solid; } .tableGrid tr:nth-child(even) { background: #E5E4E2; } .tableGrid tr:nth-child(odd) { background: #FFFFFF; } </style> <h1>Risk Data</h1> <br /> <div id="riskDiv"> <table class="tableGrid"> <thead> <tr> <th>Risk Title</th> <th>Due Date</th> <th>Status</th> <th>Cost</th> <th>Probability</th> <th>Impact</th> <th>Assigned To</th> </tr> </thead> <tbody data-bind="template: { name: 'risktable', foreach: Items }" /> </table> </div> <br /> <h1>Issue Data</h1> <br /> <div id="issueDiv"> <table class="tableGrid"> <thead> <tr> <th>Issue Title</th> <th>Due Date</th> <th>Status</th> <th>Priority</th> <th>Assigned To</th> <th>Modified By</th> </tr> </thead> <tbody data-bind="template: { name: 'issuetable', foreach: Items }" /> </table> </div>
This example uses jQuery, knockout-3.1.0.js and ko.sp-1.0.min.Ex.js so these will need to be loaded - but I'd really recommend not using this example code - it is very old but I've added it here to give you some ideas.
Both of these are just samples (very old samples!) to give you some ideas - they are provided as is with no warranties etc.
Hope that helps
Paul