1

Hi there and thanks in advance :)

So, my use-case is:

I have a visual webpart on top of the DispForm.aspx of a custom list for events.

I have another List called "Attendee List" where attendees are stored along with the event. For simplicity, lets say this list has only 2 columns, "Attendee" and "Event title".

So, I have a button in my webpart: "Show Attendee List".

What I want to achieve: If the user clicks the "Show Attendee List" - Button, a new browser Window will open and show the attendee List for the actual event, at its best in a printable format.

So, my Problem is: I don't know how to open a new browserwindow on button-click and how to show the data in a printable format. I think SPGridView should be fine for this?

Apart from that, I know how to "normally" get the data (I have a SPListItem "currentEventItem" and a SPList "attendeeList" and know how to get the data with linq/caml), but I think there might be problems getting the data in the newly opened window?! Recommendations for other workflows are appreciated ;)

Best regards, Dominik

2 Answers 2

2

Dominik,

  1. Make a new Web Part page in SitePages library [with a single Web Part Zone], and with the help of SharePoint Designer... Add a List View of Attendee List in this page!
    [I am assuming page name as "AttendeesList.aspx"]
  2. Add a parameter to this list view [Ribbon -> List View Tools -> Options -> Parameter], choose Query String as source and name it "EventId" [we are going to use it later]
  3. Add a filter to this list view [Ribbon -> List View Tools -> Options -> Filter], choose your Lookup column for Event and select Query String Parameter we made in step 2 as Value!

Your page is now setup and complete, now we will open this page in dialog on a click of a link:

  • In your display form as you said, take a Content Editor Web Part and insert following into the HTML source of Content Editor:

    function openAttendeesDialog(eventId)
    {
         //Using a generic object.
         var options = {
               title: "Attendees List",
               width: 400, //set according to your needs
               height: 600, //set according to your needs
               url: "/SitePages/AttendeesList.aspx?EventId=" + eventId  //Page with Query String 
            };
    
         SP.UI.ModalDialog.showModalDialog(options);
    
     }
    
  • Call this function from your Visual Web Part on click of an anchor or add the anchor in your Content Editor [as you wish]

    <a href="#" onclick="javascript:openAttendeesDialog(eventId)">View Attendee List</a>
    

NOTE:

  • You can access the Event Id from Request.QueryString["ID"] in your Visual Web Part
  • If applying filter on Lookup column doesn't work, take the ID column as well with your Lookup column and apply filter on Extended Column... EventList:ID
  • You can place the JavaScript on your Visual Web Part as well, I prefer to keep it in Content Editor so that I can adjust the width and height of the Dialog without touching the code in Visual Web Part
  • If you choose to use Content Editor Web Part, in Web Part properties make Chrome Type = None so that it doesn't display the header for the Content Editor Web Part..
2
  • Awesome answer! We do this for printer views too.
    – Kit Menke
    Dec 12, 2012 at 15:33
  • Thank you for your answer! :) I tried something like it's done here: armedia.com/blog/2012/06/… and it works, too, but I think i'll redo it your way for it's much cleaner :)
    – Dominik
    Dec 12, 2012 at 19:16
1

As mentioned above, I like Arsalans approach very much, but for some reasons (i'm doing this project for my bachelor thesis at the moment and as mentioned before it's my first time doing sharepoint dev. so I am fairly new to all of this and have no clue if the following is goodor bad ;) ) the head-of-development (who is my auditor for the thesis, too) liked my approach better because it's more "autarkical", as he said, so I wanted to share my solution with you, too. This is just the disclaimer: I personally would do it arsalans way ;)

But nonetheless, here's the code (behind) of my visual webpart:

Page_Load

Here I'm adding an onclick-javascript handler to my asp.net Button (Names are changed for better understanding) which opens a new browser page / tab.

protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                ... 
                    SPList attendeeList = web.Lists["Attendees"];
                    SPListItem currentEventItem = (SPListItem)SPContext.Current.Item;
                    SPFieldLookupValue eventLookup = new SPFieldLookupValue(currentEventItem.ID, currentEventItem .Title);
                    ShowAttendeeListButton.Attributes.Add("onclick", "javascript: var win=window.open(); self.focus();win.document.open();win.document.write('');win.document.write('" + GetAttendeeList() + "');win.document.write('');win.document.close();");
            }
            catch (Exception ex)
            {
                ...   
            } 
        }

GetAttendeeList

Here I'm formatting the newly opened Page(removed try/catch for better readability). The css is stored into a document library called "scripts" in my site Collection. (will get to style library later on)

private string GetAttendeeList() {

        string DocType = "<!doctype html>";
        string Metadata = "<html><head><title>Attendee List for Event " + currentEventItem["Title"].ToString() + "</title><link rel=\"stylesheet\" type=\"text/css\" href=\"../../scripts/tablestyle.css\"/></head><body>";
        string Tableheader = "<table id=\"hor-minimalist-b\" summary=\"Attendee List\"><thead><tr><th scope=\"col\">Title</th> <th scope=\"col\">Name</th> <th scope=\"col\">E-Mail</th> <th scope=\"col\">Department</th><th scope=\"col\">Phone</th></tr> </thead>";
        string Tablebody = "<tbody>" + GetUsersForAttendeeList() + "</tbody></table>";
        string PrintButton = "<input type=\"button\" value=\"Print List\" onClick=\"window.print()\">";
        string EndHtml = "</body></html>";
        string ListResult = DocType + Metadata + Tableheader + Tablebody + PrintButton + EndHtml;
        return ListResult;
    }

GetUsersForAttendeeList (& CheckIfSPFieldIsNull)

Here I'm getting the Users for the actual event formatted for my tablecells. The Event-Column is a lookup-column in my attendees-list, that's why there's a "eventLookup" in page_load. The method CheckIfSPFieldIsNull is needed for there could be empty fields in the attendee List.

private string GetUsersForAttendeeList()
    {
            string res = null;

            var foundAttendees = from SPListItem item in attendeeList.Items
                                 where item["Event"].ToString() == eventLookup.ToString()
                                 select item;

            foreach (var attendee in foundAttendees)
            {
                res += "<tr>";
                //Done this for it's a User/Group Field, having ID;#LoginName stored (yeh, I know, LoginName sucks, but that_'s how it's done in productive env. here ;) )
                string attendeeName = CheckIfSPFieldIsNull(attendee["Name"]).Split('#').Last();
                res += CheckIfSPFieldIsNull(attendee["Title"]) + "<td>" + attendeeName;
                res += CheckIfSPFieldIsNull(attendee["E-Mail"]) + CheckIfSPFieldIsNull(attendee["Department"]) + CheckIfSPFieldIsNull(attendee["Phone"]);
                res += "</tr>";
            }
            return res;
        }
    }


    private String CheckIfSPFieldIsNull(object field) {
        if (field == null)
        {
            return "<td>N/A</td>";
        }
        else 
        {
            return "<td>" + field.ToString() + "</td>";
        }
    }

So yeah, that's it. I hope you can understand what I've done. Feel free to ask me if something's unclear, but please use the answer above instead (and please don't kill me for this is a very cheesy approach in my opinion. Just wanted to show it for completeness, and in fact, it IS an answer. Not the best, though ;) )

Goodie: tablestyle.css-content (works in actual versions of IE/FF/Chrome/Opera): http://pastebin.com/1wGDbt2H

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.