Sunday, January 28, 2007

I love Sharepoing!

Half a year ago I posted a post about a possible bug in workflow schema, and as a side note I asked my readers (thats you) if it happens to you that you write sharepoing instead of sharepoint.

I had a comment from someone telling me it happens to him, reassuring me I am not the only one in the world making that mistake.

Since then I have been tracking the elusive "sharepoing" on the internet forums and blogs. Last week I found a blogger called Raghu Iyer who also made the mistake and I posted a comment for him, welcoming him to the sharepoing community. Sadly, Raghu fixed his mistake so you will not see it there.

Today I ran a google search and it turns out there are 971 instances of the sharepoing on the google index! I definitly liked Heather's (MVP) Avoid "SharePoing of the Living Dead" (I wonder if she noticed).
Another cool highlight is this russian blogger (post is in english) who apperantly types everything by hand, since all his namespaces are "Microsoft.Sharepoing.SPList".
Most of the other search results are from forums and discussion boards, but I am sure if we start a sharepoing movement, we can change it! I put a challange to the sharepoint community - If you have a blog, make a diliberate post with "sharepoing" at the header, and explain this (point to this posting) and lets watch this wonderful word gets the honor it deserves.
By the way, I would copyright the right to sharepoing, but I dont have the resources.

Wednesday, January 24, 2007

Teach the Content Query Web Part how to display a link list


A small problem with the content query web part is when you connect it to a link list is that it doesnt know what is the title of the link, and the link it is rendering point to the list item view page and not to the target of the link:



The web part renders (blank) as title

Connecting a CQWP to a link list

Connecting a CQWP to a link list

The web part renders (blank) as title, and the link points to the item



To fix this, we need to do two things:

  • Teach the web part to get the "URL" field from the list

  • Define the style for a link list that will render the link properly using the URL field



  • Lets start.


    Begin by connecting a query webpart to a link list like shown in the images above. Make sure there are some links in the list so you can track the change.
    After this, you should get the same look that you saw in the second image above.


    Export the web part - open the edit menu of the web part, and choose export to save it:




    After you save it to the hard disk, open it for editing in your text (or xml) editor of choice (notepad is ok):




    In the file, find the property "CommonViewFields". It should look like this:

    <property name="CommonViewFields" type="string" />


    Change it to include the URL field:

    <property name="CommonViewFields" type="string">URL,text</property>



    Save and import the file into the page (you can delete the web part you had on the page):

    Import web part menu

    Click the "Page" menu and select add webparts - import




    upload the web part file

    Browse to the file you just saved, and click Upload. drag and drop the web part to the page.




    So now the web part "knows" about the URL column. Now we have to "teach" it to show it properly.



    Open the site in SharePoint Designer. Under the root, find the "Style Library" folder, and then the "XSL Style Sheets" folder. right click the "ItemStyle.xsl" file and choose "checkout":





    After checking it out, open it. We are looking for the "NoImage" template. It should start with a line like this:

    <xsl:template name="NoImage" match="Row[@Style='NoImage']" mode="itemstyle">



    Copy the entire template (from the "<xsl:template" to "</xsl:template>") and paste it underneath. This is where we will create our own style - just for links.
    In the new section, change the code using the following rules (full code to follow):

    1. Rename "No Image" to "LinkList"
    2. Change the "href" attribute to point to the URL column, the text before the comma.
    3. Change the link text to point to the URL column, the text after the comma


    Here is the code:





    <xsl:template name="LinkList" match="Row[@Style='LinkList']" mode="itemstyle">
    <xsl:variable name="DisplayTitle">
    <xsl:call-template name="OuterTemplate.GetTitle">
    <xsl:with-param name="Title" select="@URL"/>
    <xsl:with-param name="UrlColumnName" select="'URL'"/>
    </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="LinkTarget">
    <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
    </xsl:variable>
    <div id="linkitem" class="item" >
    <div class="bullet link-item">
    <xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
    <a>
    <xsl:attribute name="href">
    <xsl:value-of select="substring-before($DisplayTitle,', ')">
    </xsl:value-of>
    </xsl:attribute>
    <xsl:attribute name="title">
    <xsl:value-of select="@Description">
    </xsl:value-of>
    </xsl:attribute>
    <xsl:value-of select="substring-after($DisplayTitle,', ')">
    </xsl:value-of>
    </a>
    </div>
    </div>
    </xsl:template>



    Save the file and publish it.
    Warning - if you paste it wrong or delete some character by mistake, all your content query web parts may stop working in the site collection. If that happens, either check out the file and use the undo function (if it's still in memory) or right click the file and use the version history to roll back. You may also want to download the file as a backup.



    Go back to the web part page with the uploaded webpart that has a referance to the URL field (the one we imported earlier), and open the web part properties. This may take a while, but under "Presentation" - "Styles" - "Item Style" you should have the "LinkList" style to select. Select it and click ok.





    The web part should now display the titles of the list items, and the link should point at the link target. Also, the description of the link should appear as a tool tip when you hover over the link:




    note - my site has a modified style sheet, so bullets look like ">". You'r links should appear like regular bullets.

    Tuesday, January 23, 2007

    Showing the description of a page in the Content Query Web Part as rich HTML


    The Content query web part is a wonderful way to aggregate data into a page. A common use of it is to show "news" pages in the home page of a publishing site. This is well enough, and it even has several styles to pick from :




    If you want to customize one of the styles or create your own you can do that by editing the xslt data

    Problem
    Some of the built-in styles include the description field and display it, but my problem was that the description was plain text. It even ignored line breaks that the users wrote. And that is a big problem if you want a summary of the article in your home page with a "read more..." link. For example, if the description the user wanted on the home page was:

    This is a very important description
    that has a line break.


    He would instead get:
    This is a very important description that has a line break.


    Solution?Since the pages sit in a document library, and since document libraries do not support rich text fields (damn it!), I had to think of a quick and ugly solution - paste html text into the description. So if the description was to be:

    This is a very important description
    that has a line break.

    the user had to paste the html equivalent:

    This is a very <strong><font color="red">important</font></strong> description<br>that has a line break.

    Almost!

    So I tried this, and found a flaw. The Content Query web part would display the text as-is and would not format it as rich html.

    XSL to the rescue


    To resolve this, there is a simple tweak you can do on the itemstyle.xsl file in the site. Open the site in SharePoint Designer, and navigate to the "Style Library" folder, and into the "XSL Style Sheets" folder. Check out and open the ItemStyle.xsl file, and in it find the style that you are using in the webpart, where you want to display the description as rich text.

    A quick way to do that would be to search the file for the text

    <xsl:value-of select="@Description" />



    Add
    disable-output-escaping="yes"
    inside the tag, so that the end result is:

    <xsl:value-of select="@Description" disable-output-escaping="yes" />

    With this quick change, the html code the user inputs in the description field will be displayed as rich text. The only danger in this is that the user will make a mistake, not close one of the fields and cause havoc on the page. So make sure your users are aware of the risk, and maybe write an event handler or workflow to validate the html. I would recommend just implementing an approval workflow that checks the validity of the html.

    Monday, January 22, 2007

    InfoPath form Services - implementing a Master-Detail on the web


    If you ever tried publishing a form to the web using infopath form services, you probably know that one compatibility issue you will have is with master-detail (also known as "cascading dropdowns") fields.


    Master-detail basically means when you have two fields (usualy dropdown boxes) and you want the options in the second field to change based on the choice the user made in the first field.


    For example, I have a dropdown called "States", and a dropdown calles "Cities". Now I want when the user chooses a state, to only show cities within the chosen state.
    This is easy to do in infopath - just connect the dropdowns with a little configuration. But when you try to publish the form to a web form, it will tell you that the master-detail will simply not work in the web form. It's not supported.

    To the rescue!

    Let me use the above example, showing you how to get it to work.

    First, you will need to set up two seperate data connections - one for the states, and one for the cities. I will use sharepoint lists in this example (and on the way tell you a small trick that my colluege Rai Umair showed me).

    Lets create the lists:


    The states list





    Set up a lookup into the states list from the cities list





    The cities list


    Now that we have our lists set up, lets build a simple infopath form that will show them:


    • Create a blank new form in infopath
    • Add the connection to the "States" list:
      Tools->Data Connections->Add->Receive Data->SharePoint library or list->link to the site->Select "States"->Select "Title"->click next until the wizard finishes.
    • Add the connection to the "Cities" list:
      ok, here is the trick from Rai. instead of adding the connection to the list as a sharepoint library connection, we will instead add it as a XML connection, and point it to a url that will allow us to filter the list. This is a nice trick and I thought you should see it. The whole idea is to set up a connection that will be able to filter based on a user selection. if you have other methods of doing that, feel free.

      • First we need to find out the GUID (the id) of the cities list. To do that, open the cities list in the browser, and click on "Settings"->"List Settings". The id of the list is in the address bar - after the bit that says "?List=".

        For example, if the address bar shows
        "http://server/infopath/_layouts/listedit.aspx?List=%7B7DF67EB0%2D723A%2D4897%2DA461%2D09EA9CC0D90C%7D"
        that means the ID is the bit painted in red.
        But, if you will note, it is url-encoded. you will need to replace "%7B" with "{" and "%7D" with "}" and "%2D" with "-" so the end result is: {7DF67EB0-723A-4897-A461-09EA9CC0D90C}
      • Once you have the ID, use it to construct a url like this:

        http://server/infopath/_vti_bin/owssvr.dll?Cmd=Display&List={put the ID here}&XMLDATA=TRUE

        Example: http://server/infopath/_vti_bin/owssvr.dll?Cmd=Display&List={7DF67EB0-723A-4897-A461-09EA9CC0D90C}&XMLDATA=TRUE

        If you open it in Internet Explorer, you should see something like this:



        This gets us the content of the cities list in an XML format that Infopath knows how to read.
      • Go back to infopath, add a new datasource ->Receive Data->XML Document-> paste the path we constructed above->choose "Access the data from the specified location"->Give the data connection a name (Cities) and clear the "Automatically retrieve data when form is opened" (important!)

    • Your data sources screen should now contain two data sources:



    • Lets add two fields into the main data source - City and State:



    • Lets add the two fields to the form as drop downs:




    • Change the properties of the "State" drop down to get the values from the states data source:





    • set up the properties of the city in the same fashion:



    • Ok, test the form. The states drop down should show the states, while the city dropdown should be empty since we told the datasource not to load the values on form load.






    Now that our form is ready, all we need to do is make sure that when a user picks a state, the form loads the cities. Again, it would have been a simple task if we didnt want to publish the form to a web form, but since we do - we will have to do it by code.

    Small note - my code is in C#, and by default Infopath is set to use VB.NET. I suggest that you change the setting for this form - open Tools->Form Options->Programming, and select C# as template code language.


    While you are in the tools->options, you may as well set the compatibility to "Design a form template that can be opened in a browser or infopath"


    Right click the "State" dropdown, and select "Programming"-"Changed Event":





    Visual studio has opened, with an empty new event "State_Changed". Paste the following code into the module


    public void State_Changed(object sender, XmlEventArgs e)
    {
    SetCitiesOptions();
    }

    private void SetCitiesOptions()
    {
    FileQueryConnection q = (FileQueryConnection)this.DataConnections["Cities"];
    q.FileLocation = q.FileLocation + "&FilterField1=State&FilterValue1=" + GetStateValue();
    q.Execute();
    }

    private string GetStateValue()
    {
    XPathNavigator nav = this.CreateNavigator();
    string filterValue = (string)nav.SelectSingleNode("/my:myFields/my:State", this.NamespaceManager).ValueAs(typeof(string));
    return filterValue;
    }


    So, what does this code do?

    • The "GetStateValue" function simply uses the XPathNavigator to get the value the user selected in the "State" field. We can also get that from the "e" object of the event, but to simplify the readability of the code I used functions here.


    • The "SetCitiesOptions" changes the url of the XML file that the cities data connection is using, and adds a filter to it. the filter syntax is "FilterField1=[name of field]&FilterValue1=[Value you want to filter".

      So basically, you can create whatever filter you want on the fields, and as many filters as you want (in an "And" chain).


    • The changed event for the states just makes sure the form loads the city data with the appropriate filter!


    this will work on the client side, but not on the server side. why? because we are doing the re-query by code, the server will not refresh the page (postback). So to force a post back you will have to add a rule to the "State" dropdown. The rule will force the page to get the new information.
    To do that, right-click the "State" dropdown, and choose "Rules" from the menu. Click "Add" to create a new rule and then "Set Condition" to "State is not blank" and add an action "query using a dataconnection" from cities:









    How easy is that?




    Try and preview you'r form in infopath. Now when you select a state, the cities box should show options based on the selection you made:





    Now publish the form to a sharepoint forms server. Since this is a long proccess, and there are enough articles about this on the net, I will leave you to it.




    When you test your form on the web, it should cascade the field:




    You will note that the refresh is done using AJAX, so the page does not postback, but instead just waits for a second (with a nice bar) and then populates the data.




    References and thanks

    • I want to thank my colleague Rai Umair for the "/_vti_bin/owssvr.dll" trick. May he resume blogging again soon.
    • I want to thank Ed Torres for forcing me to take a look at this and listening to me complain as I tried to make this work.

    • While I was writing this article, a colleague (Lee Marriage) sent me a link to an article doing something very similar by Scott Heim from Microsoft's Infopath team. His solution is to use a web service to filter the list items (I like Rai's trick better. no code needed, and easier to deploy) and using a similar rule like I did to refresh the data.

    MOSS gets good reviews - "Is Microsoft's SharePoint 2007 a golden app?"

    take a look at "Is Microsoft's SharePoint 2007 a golden app?" in computerworld.com about MOSS.
    These people did do some real research and are not spouting silly one-liners such as "doesn’t necessarily encourage lot of collaboration".
    The article prounounces MOSS as being such a big collaboration tool that most organizations feel a need to block and limit some of it (sounds familiar? I said that last week!).
    One thing to note in the article - they noted that the BDC is a task for developers (which I agree with) but then they write "a Visual Studio job, no doubt.". Well, just to make things precise - no, you dont need visual studio - any XML editor or even notepad is enough to create a BDC definition. The problem starts when you want to expose your application's data - and if the data is not in SQL, you will need to develop a web service for it, and that's where Visual Studio may come in (you can use other technologies or IDE - no one is forcing you).

    Saturday, January 20, 2007

    Blog Logo

    Do you like it? I made it myself (any volunteers to make this better?):

    Wednesday, January 17, 2007

    Call for Microsoft - SharePoint as Open Source!

    In one of the most interesting articles I've read lately, Stephen Walli is explaining why and how sharepoint should be made open source.
    It is very interesting and I wonder if someone from Microsoft will read this and say "hmmm...let's do it!".
    I really hope so, because I can think of so many changes I would like to do to the sealed classes, and I can only imagine what the hard core developers would do. Next time we find a bug, we can fix it ourselves and not have to wait in queue for the service pack, while our customer is canceling the project.
    Microsoft will gain more developers living sharepoint inside-out and more and more integrating products will come out.
    What do you think?

    Monday, January 15, 2007

    Permission to use my samples

    In a recent comment for one of my posts someone called "S Jaiswal" left a comment asking for my approval to use my code samples in presentations. Since he didnt leave any contact details, I will post this publicly to all of you.

    The rule here is like in the academic world - use it all, change it as much as you want and go wild. Just one thing - give credit when it's due. If you used one of my blog posts to write a blog post - put it in the notes of the post, with a link to the article in my blog.
    If you do a presentation and show something that you learned from me, put a link to my blog and to the article.

    That's it - just use common sense. If someone helped you, give him the credit. I hope I get more such comments - its a wonderful thing to know that the information I post here is getting used. please let me know if you use it (I would love to get a copy of the presentation to see how you did it!)

    A final note to people who organize sharepoint user groups and\or techeds or events like that - I will be happy to get invited to such events. I am very active in the Canberra sharepoint user group, and I have done presentations on the Sydney one as well, not to mention 2 lectures in Teched Israel 2003. I am more then willing to come (you just have to get me there...from Australia).

    SharePoint is misunderstood - it's the corporate world that is still old.

    I today's article in the 360techblog, a guy called Ray Velez from Avenue A | Razorfish is quoted to say:

    ...that price isn’t the only reason SharePoint isn’t getting love from the web 2.0 crowd. It may be very powerful, but it’s also complicated. “Trying to move a portal server is like moving a battleship,” he says.

    Moreover, he says, Microsoft’s products are built on the old intranet model that doesn’t necessarily encourage lot of collaboration. They’re designed for the old corporate world of command-and-control, enabling layers of permissions that can stifle spontaneity. With wikis and blogs, it’s all much more accessible.”

    Although the entire artical deals with the microsoft vs google, and the microsoft office 2007 release, and sharepoint 2007 bdc as a killer, this guy seems to be talking about sharepoint 2003!

    It's either that or he doesnt know what he is saying. SharePoint 2007 encourages collaboration so much out of the box, that most of my clients ask me to restrict the collaboration features, because they are afraid the users will spend time "collaborating" instead of "working".
    Mr. Velez needs to understand that while sharepoint is designed to allow top notch collaboration, most of the corporate world is not prepared to use it. They install sharepoint, and then spend a lot of money to customize it so that collaboration is trimmed to a minimum.
    It's not SharePoint that is "designed for the old corporate world" - its the corporate world that is still old.

    It's a pity sharepoint keeps getting bad reputation because people who havent really been using it, or who are not sharepoint professionals have been covering it in the media. I saw a gartner document about half a year ago that totaly discarded what sharepoint 2007 could do, and reviewed the brand name sharepoint as if 2003 was all there was. I admit that 2007 needs a lot of work, and 2003 wasn't perfect, and I would be the first to shout that the 2001 version was a disaster, but saying that sharepoint is built on the old intranet model? what is that???

    Sunday, January 14, 2007

    Scripts, styles and images dont work on a SharePoint site

    There are a lot of reasons why images, styles and scripts will refuse to work for you on a sharepoint site. I have come across some of them, and I want to share how to troubleshoot this.

    One reason this may happen is that your Internet Explorer is blocking the scripts. I had a lot of people complaining about how they installed sharepoint on the server, then created a web site, then tried to create a list item or upload a document, and non of the buttons would work!
    You will find that often this is accompanied by sharepoint constantly asking you for authentication each time you load a page, and sometimes more than once for each page before letting you see the page.
    Cause
    This was because they were working from the server, which by default has the "Internet Explorer Enhanced Security Configuration" installed.
    Solution
    If you must work from the server itself, either remove the "Internet Explorer Enhanced Security Configuration" (control panel->add remove programs->add/remove windows components) or add the site to the trusted sites list (not guaranteed to work. I suggest you remove the security block).

    Another reason is a problem with the alternate path mapping in central admin. The Alternate Path Mapping are not configured so that the path you are trying to use is properly managed by sharepoint. For example, you may be using http://localhost while sharepoint is configured to accept http://portal.
    Cause
    I dont know why this happens, most of the time the alternate paths are configured correctly for you automtically. But I have seen a server (just today I had 2!) that lost it...
    Solution
    Open the SharePoint Central Administration Page, go to the Operations page, and click on "Alternate Access Mapping". Make sure that the url you are trying to use is in the list, and if not- add it!

    These are the two instances of this problem that I have witnessed. Got more? comment!
    note - if you do comment, feel free to leave your name - otherwise I cant give credit where its due. Also, if you ask questions, leave a way to contact you! the best way is to register in blogger to get a user name and password (not a blog) so I can know who left the comment.

    Tuesday, January 09, 2007

    I have been tagged! 5 things you dont know about me

    Angus Logan from Microsoft Australia has tagged me, forcing me to think about 5 things you dont know about me. So here we go!

    1. While having noo musical talent at all, I love music, but am very picky. I will only listen to classic rock. My favorite band is Jethro Tull, and I went to see them twice when they came to Israel.
    2. When in high school, me and a group of friends spent a whole nights spraying grafiti all over our school. We did one 10 meters high of two giant sheep using a ladder, and a lot of small ones of sheep running all around the school. One of us also lay down on the basketball court, and we painted around him so it would look like a dead body marking, and then his dog joined him and we did the dog as well.
      People could be found around those markings arguing what the small share is supposed to be for the entire year.
      Because the giant sheep were so high, the school couldnt get rid of it and it stayed on the wall a record period of 3 years!
    3. I love computer games, and as a child my dad would complain all the time that I should do something more productive with the computer instead of playing with it.
      Nowdays when he says the same to my brothers I point out to him that I was the same, and then I show him my pay check. Enough said.
    4. I am afraid of fish. If you want to see a 30 years old guy screaming and running like hell - throw a fish at me. Dead or alive, I cant stand the thought of a fish touching me.
      I do love to look at them, so I do scoba dive - but my partners always complain that I run out of air too fast because I start breating heavily every time a fish looks like he is coming towards me.
      I have been known to kick at fish with my flippers underwater, and screaming at them "go away!" while scuba diving.
    5. I was in prison. Yes - as a prisoner. During my reserve duty in the Israeli army as an officer I refused to serve in the occupied territories and was jailed as a conscientious objector. You can read about it in many internet articles, and even one book that included one of my personal stories of what I have done as a soldier and why I refuse to do it again. A short piece that will let you uunderstand can be found here. By the way - this is not the reason I moved to Australia. That is another story.

    My turn to tag people:

    Monday, January 08, 2007

    The SharePoint 2007 Beta Exams tips

    Hi,

    As you may well know, SharePoint 2007 has 2 developer certification exams (1 for WSS and one for MOSS features) in a beta stage, and Microsoft wants people to take them and then collect feedback so they can finalize the exams for release.

    This offers a very good opportunity for you:

    1. The exams are free - just use the promotion codes (see below)
    2. If you take the exams and pass, you will get the credit only after the exam is released (you will not have to take it again)
    3. If you don't pass - think of it as a free exercises for when the actual exam arrives!
    There is also one drawback - the moss exam is 3.5 hours long, and the wss one is 3 hours long, and then you get 0.5 an hour each where you are asked to comment on questions (feedback for the beta). Oh - a minor irritating fact- you don't get the results until after the beta has ended. So if you take it now, you will have to wait at least 2-3 months before finding out if you passed or not (unlike the rest of the mcp exams that tell you immediately)

    I took both exams yesterday, and I can tell you - they are not easy. You need to have experience with every aspect of each product if you want to pass. And the problem with the 2007 version is that it has a lot of aspects.

    Here are the links to the exams and how to register. Below you will find my "prepration guide".


    And here is where you can go to register:
    1. Prometric: http://www.register.prometric.com/ClientInformation.asp
    2. VUE: http://www.vue.com/ms

    To prepare, I suggest you print out the Microsoft preperation guide (see links below) for each exam, and go and make your self a list of development tasks for each of the skills specified. For example - when I saw that a required skill is to add custom actions to menus - I gave myself the task of creating a printlist menu item and adding it only to the list "actions" menu (see my article on how I did it - how to add print list option to list). I then did a similar thing, but adding only to the site actions menu, but allowing only administrators to view the new menu item. This is good preperation for something that has at least 3-5% of the questions about. (by the way - 90 questions for MOSS, 75 questions for WSS)
    Another example - since you need to know about creating custom field types - create one! I did a phone validation field for australian dialing rules. There are a lot of examples on the web. I also did a field that allows only prime numbers (just for fun).

    WSS Exam Recommendations:

    1. Make sure you know how to build a feature, with all the options. best thing - know the feature schema by heart.
    2. How to deploy resources? pages?
    3. How to deploy site definitions? know you'r onet.xml!
    4. Learn about event handlers (for lists, sites and features). I suggest you create a few before trying this exam
    5. Make sure you know enough CAML to do queries to search for information. Also, make sure you know about the GetSiteData function and not just the GetItems. And also learn about how to do the search in an entire site collection.
    6. Uploading, downloading and moving files using code.

    What about MOSS?
    You will need to play around a lot with the search options, with BDC and with the BI options, not to mention Excel.
    Search & Profiles (my strong points):

    1. Create a custom search web part, and use the different kinds of search objects (fulltext, keyword etc) (see my article on the subject)
    2. Customize the search interface by changing the selected columns property of the core results web part.
    3. Customize the xslt of the core results web part so that you know how to change the "no results found" text, the "no keywords" text and change the way it displays the actual results (make it a grid-like view)
    4. Combine the two above - add a custom property to the user profiles, make it index-able, add it to the selected columns, and then edit the xslt so that the new column is visible on the page (see my article on this)
    5. Create an audience by code - set rules to it.
    6. Write code that gets all users from the audience. Create code that gets user properties from his profile.


    Publishing:
    1. Know how to set up a publising workflow
    2. Know how to set up a publishing job between servers
    3. know how to use document conversions.


    BDC, Excel Services and BI(of which I know nothing about and probably failed the exam because of):
    1. Create (manually - don't cheat!) a BDC connection to a SQL database
    2. Create (manually - don't cheat!) a BDC connection to a web service
    3. Create actions to get details on a single row from the rows returned from the above, implement specificfinder and finder and all the rest of the words that I don't really know.
    4. Use the KPI web parts to connect to the above
    5. Use the KPI web parts to connect to sql reporting services
    6. publish an excel spreadsheet to a page, a document library, a trusted location
    7. apply filters on the excel data
    8. apply security on the excel data

    phew...long post this was! I am really skeptic about me passing the MOSS part (I am sure I scored high with search and user profiles and audiences, but all the rest

    Saturday, January 06, 2007

    How to add a "print list" option to the list actions menu


    It's been a long time since I published a cute and useful code sample, so here we go!

    The idea - add a "print list" button to the actions menu of a list, so that when a user click it he will be shown a print-friendly version of the list.



    The print list menu item










    The print view for an announcement list


    Please remember that this is a code sample, and while it works, I can think of many ways to improve it. For example - the current code will always use the default view of the list for the printing, and I would like to improve it so that it shows a print view for the view the user was looking at.
    Another example - the current code doesnt display the list title or any other details on the list, and that will be a useful (and easy) modification. I will leave it up to you to try and do it, and if you find yourself in trouble - comment and I will look into what you want to add.



    Solution Architecture




    The solution will be deployed as a wss feature, which allows us an easy way to add a menu item to the sharepoint menus. The feature will define that the item we want to add will be added to the actions menu of all lists, in a site collection. You can ofcourse change it so that it behaves differently and connects only to lists of a certain type if you so wish, or maybe move the menu item to a different place. I recommend reviewing the msdn article on the possible configurations.
    The solution is based on 3 files:

    1. feature.xml
      Defines the feature, its scope and its title that you will see in the "site features" (or site collection features or farm features - depending on the scope)


    2. PrintList.xml
      Defines what action we want to add to what menu and what will happen when the user clicks the menu item. This is where you configure the text of the item, and the link to the page that will print the list. which just happens to be the last file:


    3. PrintList.aspx
      Contains the code that shows the list in a print-friendly view. This file should be deployed to the layouts folder and must be called with the site's context (more about that shortly).





    To the Code!




    note - when I talk about the "12 hive" I am referring to the folder C:\Program Files\Common Files\Microsoft Shared\web server extensions\12


    Create the page that prints a list:



    1. Log on to the server, and open the template\layouts folder in the 12 hive.

    2. Create a new text file in the folder, and name it "PrintList.aspx"

    3. Open the empty file in your editor of choice (notepad is fine) and paste the following code into it:



      <%@ Page Language="C#" Inherits="System.Web.UI.Page" %>



      <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"


      Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


      <%@ Import Namespace="Microsoft.SharePoint" %>


      <html>


      <head>


      <title>SharePoint List Print</title>


      <link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/core.css" />



      <script type="text/javascript" language="javascript" src="/_layouts/1033/init.js"></script>



      <script type="text/javascript" language="javascript" src="/_layouts/1033/core.js"


      defer></script>



      <script type="text/javascript" language="javascript" src="/_layouts/1033/ie55up.js"></script>



      <script type="text/javascript" language="javascript" src="/_layouts/1033/search.js"


      defer></script>



      </head>


      <body>


      <%




      string listId = "";


      string referrer = "";


      //get the list id (guid in a string format) from the query string


      listId = Page.Request.QueryString["list"];


      //get the http referrer (for the back button\action)


      referrer = Page.Request.ServerVariables["http_referer"];


      //make sure the list parameter was passed


      if (listId == null)


      {


      //if a referrer url exists (since the page may have been opened from a direct link, this is not always the case) redirect the user back


      if (referrer != null && referrer.Trim().Length != 0)


      {


      Page.Response.Write("<p>The list ID parameter ('list') is missing from the address.<br>Please go to the list you want to print and try again.</p>");


      Page.Response.Write("<p><a href=\"" + referrer + "\" title=\"Go Back\">Click here to go back to the page you came from</p>");


      }


      else


      {


      Page.Response.Write("<p>The list ID parameter ('list') is missing from the address.<br>Please go to the list you want to print and try again.</p>");



      }


      }


      else


      {


      try


      {


      //load the web object for the site that the page is now in context of


      using (SPWeb web = SPControl.GetContextWeb(Context))


      {


      //load the list that was passed in the 'list' querystring parameter to the page


      SPList list = web.Lists[new Guid(listId)];


      //load the query of the default view. note - need to modify code in the future to enable multiple view printing


      SPQuery query = new SPQuery(list.DefaultView);


      //write the list to the page


      Page.Response.Write(list.RenderAsHtml(query));


      //add the print script


      %>



      <script type="text/javascript" language="javascript">


      window.print();


      </script>



      <%




      }



      }


      catch (Exception ex)


      {


      Page.Response.Write("<p>There was an error loading the list information:<br />");



      Page.Response.Write(ex.ToString());


      Page.Response.Write("</p>");


      }


      }





      %>


      </body>


      </html>









    Install the feature


    1. Open the \TEMPLATE\FEATURES folder under the 12 hive

    2. Create a folder called PrintListMenuAction

    3. In that folder, create 2 text files, one called feature.xml and the second printlist.xml



    4. In your editor of choice (notepad is fine) open the feature.xml file and paste into it the following:





      <?xml version="1.0" encoding="utf-8" ?>


      <Feature Id="769826dd-9dd2-11db-96ca-005056c00008"


      Title="Print List"


      Description="This feature adds a print command in the Actions menu for Windows SharePoint Services lists."


      Version="1.0.0.0"


      Scope="Site"


      xmlns="http://schemas.microsoft.com/sharepoint/">


      <ElementManifests>


      <ElementManifest Location="PrintList.xml" />


      </ElementManifests>


      </Feature>








    5. In your editor of choice open the printlist.xml and paste the following:


      <?xml version="1.0" encoding="utf-8" ?>


      <Elements xmlns="http://schemas.microsoft.com/sharepoint/">


       


        <!-- Add the action to the List Toolbar Actions Menu Dropdown -->


        <CustomAction Id="SPSTIPS.PrintListActionsToolbar"


          RegistrationType="List"   


          GroupId="ActionsMenu"


          Location="Microsoft.SharePoint.StandardMenu"


          Sequence="1000"


          Title="Print List">


          <UrlAction Url="{SiteUrl}/_layouts/PrintList.aspx?list={ListId}"/>


        </CustomAction>


       


      </Elements>










    Almost done - install the feature and test it!




    To install the feature, open command line (start>run>cmd) and navigate to the bin folder in the 12 hive.

    Once there, run the following command to install the feature:

    stsadm -o installfeature -name PrintListMenuAction -force


    After you ran that command successfuly, you can activate the feature in the site collection either using the user interface (site actions> site settings> site collection features):




    or you can (more easily since you are already in the command line) just run the following command, entering the site path:



    stsadm -o activatefeature -name PrintListMenuAction -url [your site url here] -force




    That's it! if you now go to any list in that site, you should have the print menu action.
    Please let me know if any of the steps doesnt work for you or if there is any problem with the pasted code (I am trying the SourceCodeToHTML addin for visual studio, and I am not sure what that will do to simple copy-paste actions on your side).


    Update 19/1/2007 :
    Some people have remarked that the printlist.aspx isnt working for them. I went over the code and couldnt find a problem with it (well, there are some improvments I can think of, but nothing to cause what they are describing). I suggest you try to troubleshoot it by:


    1. Make sure you copied all of the text in the code sample. Missing a line or even a character will cause what you are describing

    2. Try changing the trust level in the web.config file for the sharepoint application to "Full". This shouldnt be a requirement for this solution, but who knows...

    3. Try removing pieces of code to see what part causes the crash.

    4. Contact me. Write to my anti-spam email address with the subject "Problem with list printing" (any other subject and I will automatically delete the email). The address is (replace the '$' with '@'):
      "dontwantspamhere$gmail.com"
      (replace the '$' with '@')



    Update 28/09/2007 :

    I have noticed that the action only works from within a list view page, and not from a web part (a list view web part) that is displayed on a web part page, not from the list context. I have no idea how to solve it, so for now be aware that this will not work in web parts.

    Monday, January 01, 2007

    A year.


    A year has passed since my first post ever and what a blogging year it was...




    • 90 posts, nearly all of them about SharePoint, and at least 65 of these about the 2007 version, which shows that I was busy with the beta.


    • 30,538 visits since I added a counter (I cant remember when)
    • 100$ made from google ads (still waiting for that first check.)

    • 18 comments that I didnt delete, and quite a few I deleted by mistake. including the one from the guy saying I am "his hero"...what a feed-back!
    • One free web part, and one free utility pack published (still no feedback. I wonder how I can tell if anyone is using these)






    So, not bad for my first blogging year. I thought of setting a numeric goal for my self - something like 365 posts in 2007, but I dont want to be like all of those bloggers who post just for the fun of it. I want my posts to contain meaningful information that is either original or hard to find. So I will make a different commitment - A 3rd of my posts will be code samples, and unless I am on vacations, one post a week minimum. And if I get an MVP, I will publish 3 free web parts + source code (hear that Microsoft?!)




    I had also just learned that one of my articles was among the top 4 posts in 2006 from the SharePoint Buzz blog. While I appriciate the honor, I would like to make a note to the editors of sharepoint buzz - less advertising, more content! that site would be a lot more nicer if half the screen wasnt taken by ads. That said - thanks for the notice!





    Have a good SharePoint year everyone. at least as good as these two seem to be having:




    Picture taken in the Taronga Zoo in Sydney on Sat. 30 december 2006. Shows two turtles celebrating the end of the year.

    InfoPath Form Services Best Practices- The View State

    If you havent read the technet article on infopath form services best practices, now is the time.
    However, The article gives some advice about something called the "form view" and doesnt specify where to set it. So to help you find it - here is where.

    In central administration, open the "application management" page, and under the "Infoopath Forms Services" section you will find a link "Configure Infopath Form Services".
    The bottom of the page contains two options - Session state service and Form view.

    Now, if you had read the technet article on infopath form services best practices (you mean you still didnt? why not?) you will know the difference between the two - the form view reduces database load. it puts everything on the client side, and that means that a lot of data is sent between the client and the server each time something happens on the form.
    This is recommended if you dont have bandwidth problems in your environment, because your SQL server will have less load on it. However, if your deployment is such that you have poor connections for some of the users, I suggest you either set session state, or set a low number of kilobytes in the form view maximum box.

    You should note that session state service is turned off by default on the server. You must set up a shared service provider first, and then enable it (application management page - configure session state). You may also need to allow it in the web.config file (see my previous article on the subject).

    How to get rid of "The form cannot be displayed because session state is not available"

    I know other people wrote about this in the newsgroups, but strangely enough - no blogger bothered to blog about this - so I will.

    When you click on "start workflow" in a publishing site page, you get the annoying error "The form cannot be displayed because session state is not available". This will happen even if the "Configure Session State" in the "Application" section in the administration site is configured properly.
    The solution is simple - open the web.config file for the site, search for the word "SessionStateModule" and uncomment that line.

    Example:
    <!-- <add name="Session" type="System.Web.SessionState.SessionStateModule"/> -->
    should be:
    <add name="Session" type="System.Web.SessionState.SessionStateModule"/>>