Feeds:
Posts
Comments

A little while back I had to create a solution to colour code a 2010 calendar to be used for internal scheduling here at bluesource… so I thought I’d share it with you chaps..!

The idea behind it is that a list can be used to manage unique keys against colour values. For instance, say a single calendar is used to book all projects. Each project has a unique number, and you wanted those to be automatically colour-coded (without having to use calendar overlays). This solution allows you to specify a key against a colour value – eg ‘Whichever calendar entry has [1234AABB] in the title of the entry, I want to be blue (#000066)’ .

 

Download the WSP Here: bluesource.intranet.zip

Please Note: bluesource does not accept any liability for this solution, it is the work of myself only – and as any custom solution, should be installed on development systems first.

It comprises of 2 pieces:

  • A list definition – A list will need to be created from the definition. Unique keys and colour values are entered into the list (in the same site collection as the calendar).
  • A web part – which will need to be added to the calendar page (this injects some javascript goo to do the colour coding). This needs to be pointed at the list (in the web part settings).

 

Installation

  • Deploy the WSP, and activate the Bluesource.Intranet.CalendarColours feature in Site Collection Features.

image

  • Create a new list from the ‘CalendarColours’ list definition.
  • Enter your values in the list (shown below):
    • Title: The unique key to look for the calendar title
    • Background Hex Value: Hex colour value to make item background
    • Text Hex Value: Hex colour value for text

image

 

  • Add the Calendar Colour Coding web part to the calendar page:

image

 

  • Enter your calendar entries, using the unique keys – and voila:

image

 

Hope this helps – if people want the source code leave me a comment…

 

.davros.

So I recently had to write a console application to post data to a SharePoint 2010 list, using the web services – but without using any ‘normal’ .NET web references. The server was set up with Basic Authentication.

This involved forming the SOAP envelope manually, and using a POST command. One thing that tripped me up (…and very nearly made me cry) was that most samples on the net use <soap:Envelope> – whereas it only worked for me when I used <soap12:Envelope> (with the correct namespace of course).

Anyway the code is below – so hopefully it might help some of you not waste so much time as I did… ;/

 

.davros.

 

static void Main(string[] args)
        {

            string soapEnv = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
                " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" +
                " xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">" +
                "<soap12:Body>" +
                "<UpdateListItems xmlns=\"http://schemas.microsoft.com/sharepoint/soap/\">" +
                "<listName>TestList</listName>" +
                "<updates>" +
                "<Batch>" +
                  "<Method ID=\"1\" Cmd=\"New\">" +
                    "<Field Name=\"Title\">Added item</Field>" +
                  "</Method>" +
                "</Batch>" +
                "</updates>" +
                "</UpdateListItems>" +
                "</soap12:Body>" +
                "</soap12:Envelope>";

            string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username@domain + ":" + "password"));

            string uri = "http://sharepoint-url-here/_vti_bin/lists.asmx";
            WebClient client = new WebClient();
            client.Headers["SOAPAction"] = "http://schemas.microsoft.com/sharepoint/soap/UpdateListItems";
            client.Headers["Content-Type"] = "application/soap+xml; charset=utf-8";
            client.Headers["Authorization"] = "Basic " + user;
            client.Encoding = Encoding.UTF8;

            System.Text.ASCIIEncoding encode = new ASCIIEncoding();
            Byte[] bytes = encode.GetBytes(soapEnv);

            try
            {
                string response = client.UploadString(new Uri(uri, UriKind.Absolute), "POST", soapEnv);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Doh!");
            }

        }

2010 in review

The stats helper monkeys at WordPress.com mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

Healthy blog!

The Blog-Health-o-Meter™ reads This blog is doing awesome!.

Crunchy numbers

Featured image

A helper monkey made this abstract painting, inspired by your stats.

A Boeing 747-400 passenger jet can hold 416 passengers. This blog was viewed about 2,600 times in 2010. That’s about 6 full 747s.

In 2010, there were 2 new posts, growing the total archive of this blog to 14 posts. There were 8 pictures uploaded, taking up a total of 1mb.

The busiest day of the year was March 2nd with 38 views. The most popular post that day was About Me.

Where did they come from?

The top referring sites in 2010 were baddaz.com, topsharepoint.com, spqteams, google.com, and linkedin.com.

Some visitors came searching, mostly for sharepoint makes me cry, javascript popup div, mail2sharepoint, infopath popup window, and javascript popup.

Attractions in 2010

These are the posts and pages that got the most views in 2010.

1

About Me August 2009

2

InfoPath Popup Forms for Public Facing Websites (Web 2.0 Style) September 2009
2 comments

3

InfoPath Custom Save Action: Save as Draft and Avoid Validation July 2009
1 comment

4

InfoPath and Windows 7: System.Security.SecurityException September 2009
2 comments

5

InfoPath Rich Text Display in Form: Expression Box December 2008

We’ve just launched our latest MOSS website here:

http://www.GeorgeBurrows.com

Much of the site is standard MOSS functionality – apart from custom built top and left navigation web parts (shown below)…

 

Top Nav

To enhance the user experience in navigating the site, I developed a custom Top Navigation control (pictured below). The control cycles through each subsite and it’s Pages library, bringing back all the Pages which the user has declared to be on the navigation. Then the Title, Description and a custom ‘NavImage’ image field is displayed in the flyout. The Flyout is standard CSS and JS.

image

 

image 

 

Left Nav

The left navigation control was built to enable more accessible <UL> and <LI> elements to be output.

image

 

.davros.

I’ve been working on a WSS site for a friend of mine in my spare time lately, and it’s finally ready to launch!

Take a look if you’re interested: http://www.CambridgeAutogleam.com

image 

 

Main highlights of development…

1) Portfolio. Mapping a drive to the image library behind the scenes, he’s able to drag and drop a new folder in per car he details. So – content management requiring no SharePoint skills. In the front end – the latest 3 cars are shown on the homepage, and a customised CSS + JavaScript PopUp layer are used to show more photos of the car without navigating the user away from the page.

JQuery is used to highlight the selected image, and JavaScript swaps the images from the thumbnails to the main image – so no postback.

image  image

image

 

2) Banner Image. You’ll notice that the main image in the banner on each page is different. A standard image library contains a number of possible images, a data view is inserted in a DIV layer in the master page, and a JavaScript function runs to select one of the images randomly and display it.

 

3) Testimonials. Testimonials are driven from a list in the administration site. To add a new testimonial, he just has to add a new item to the list. Items are just ordered by date created, keeping things nice and simple. Data views are used to display them.

image  image

 

4) Twitter interaction. I initially used some of the standard twitter XML data to display updates in the footer of the site – but after deployment to 1and1 it seemed that these feeds were blocked. To work around the issue, I took the approach detailed here: http://blog.bullseyeconsulting.com/archive/2009/01/04/twitter-on-sharepoint.aspx , which meant the call to the twitter update runs from the client rather than server.

 

Hopefully this proves that interesting and dynamic websites can be built on a WSS platform! Let me know what you guys think…

 

.davros.

So, we finally managed to carve out enough time between customer projects to update our own website, and bring it onto MOSS.

Below are some screenshots of the site, as well as some mock-ups I produced whilst planning the site and working with management here.

image

image

image

 

So here are my top tips for creating a MOSS website:

1. Avoid restricting SharePoint functionality

Try to always work with SharePoint, not against it. Of course, there are times when custom elements need to be brought into the site, but use standard functionality where possible. If we can re-brand or customise SharePoint elements rather than bringing in new ones it means we’re reusing the same skill sets, both for developers and content authors.

2. Be consistent

Content authors are not ‘SharePoint people’ and they probably have no intention on being one. Their job is to create content, so we should create a system that caters for them, and allows them to reuse the same authoring skills throughout.

3. Remove the Name.dll message!

If you’ve been using SharePoint already, you may well have not noticed the warning message IE users will get when viewing an un-trusted website trying to run an ActiveX control. MOSSMan has a great and simple workaround.

4. Re-use page layouts

Can we make page layouts flexible enough to cater for varieties of content? This really depends on how much time the development / design team have, and how technical the content authors want to be. Simple layouts could be created and the authors told to insert web parts to customise pages etc. Or – a page layout for every imaginable type of content could be created, and content authors are channelled into selecting one and sticking to it. I would suggest a balance is required, and will be different in each implementation.

5. Remember SharePoint is a CMS

Even if we need to use custom site elements – custom forms / flash / silverlight forms – can we store the resulting data collected from users in SharePoint? Again, it’s one set of skills for everyone to reuse.

 

davros

I’ve recently gone onto Windows 7, and, like every one else it seems, I’m pretty happy with it. Only thing I have found is that using Managed Code in InfoPath 2007 now requires the form to be fully trusted.

It used to be the case that on your own machine, you could allow the form manage it’s own trust level whilst developing with managed code. However, this has changed in Windows 7 – and you may get the error shown below:

image

System.Security.SecurityException
Request failed.
   at Microsoft.Office.InfoPath.MsxmlNavigator.IsValidNode(MsxmlNode test)
   at Microsoft.Office.InfoPath.MsxmlNavigator.MoveToFirstChild()
   at MS.Internal.Xml.XPath.XPathChildIterator.MoveNext()
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.ChildrenQuery.Advance()
   at MS.Internal.Xml.XPath.XPathSelectionIterator.MoveNext()
   at System.Xml.XPath.XPathNavigator.SelectSingleNode(XPathExpression expression)
   at System.Xml.XPath.XPathNavigator.SelectSingleNode(String xpath, IXmlNamespaceResolver resolver)
   at ContactForm.FormCode.SubmitToList()
   at ContactForm.FormCode.cmdSubmit_Clicked(Object sender, ClickedEventArgs e)
   at Microsoft.Office.InfoPath.Internal.ButtonEventHost.OnButtonClick(DocActionEvent pEvent)
   at Microsoft.Office.Interop.InfoPath.SemiTrust._ButtonEventSink_SinkHelper.OnClick(DocActionEvent pEvent)

 

To fix this, the form needs to fully trusted:

image  -> image

 

 

A minor annoyance, but hopefully it might save you guys some time…

 

davros.

I’ve recently been doing some work updating our MOSS website (http://www.isc-software.com – article coming soon), and the need arose to capture user information in two scenarios: Event Registration and Sales Queries. Initially, I saw two options: A customised list item form, or a full blown InfoPath Forms Services form. Since I didn’t want to hack around with securities and lists too much, and keep things as clean as possible, IPFS was the only choice. I didn’t want the user to have to navigate to another page to fill out the form, but rather I wanted to mimic some of the newer popup styles seen on sites like Facebook, LinkedIn etc.

forma    formb

 

For events registration, the user journey takes the following route:

1. User clicks “Register Now” on the event page.

2. A CSS / JavaScript popup window appears in the browser, and passes the form an event ID.

3. The form loads in the DIV layer, and queries the SharePoint page library to get summary details of the event.

4. The user fills out the form and submits (all standard InfoPath validation + formatting apply).

5. The form submits the data to a SharePoint list behind the scenes, using the SharePoint web services. (Custom code – future article?)

5. The form shows a summary and the user closes the popup.

 

Anyway this is really just a short summary I know, but if anyone wants me to blog any part of it in greater detail then I can – just drop me a comment.

 

See it in live: http://www.isc-software.com/events/Pages/Seminar1.aspx

 

davros.

Recently i’ve been working on a project that has required a user to be able to save a form to SharePoint as they are working on it, a kind of draft. The only way to do this is to allow the user to use the standard ‘Save’ function on the toolbar (in IP client or browser). This offers the user the option to choose a filename – fine if there’s going to be 10 forms in the library, but if there are 000’s then users are going to be overwriting each other’s work.

First step was to set up a Submit Data Connection to the SharePoint library. This is good because I can generate a unique filename and post the document there. However, since the connection is a ‘Submit’, the form will not allow you to run it until all validation errors are cleared… no good for draft forms.

Next step was to jump into code behind – clear the validation errors in the collection, then submit the form:

this.Errors.DeleteAll();
this.Submit();

This works fine, BUT – if the user wants to save a draft and continue working, all the validation has been basically disabled in the form until it is reloaded. SO: final solution was to manually write the xml file into the forms library. This was actually less hairy than it sounds. It consists of 2 methods in code behind – 1 to process a HTTP PUT command, and one to basically call it. The web request method is pretty generic: url: The full URL of the file (http://sharepoint/forms/myform123.xml)

header: The header information in an infopath file (the xml declaration and processing instructions). The method takes the header, selects the form data from the root node (in this case /my:Application), and builds a string before pushing that through the web request.

private System.Net.WebRequest BuildRequest(string url, string header){     string xmlString = header;
     xmlString += MainDataSource.CreateNavigator().SelectSingleNode
("/my:Application", NamespaceManager).OuterXml;
     //now send the web request to load the document
     System.Net.WebRequest request = System.Net.WebRequest.Create(url);
     request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
     request.Method = "PUT";
     System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
     byte[] buffer = enc.GetBytes(xmlString);
     using (Stream stream = request.GetRequestStream())
     {
         stream.Write(buffer, 0, buffer.Length);
     }
   return request;}

The following method just sets up the header (copied from a locally saved infopath form), and calls the web request method. Note: for a filename, I am using a field in my form called ‘GUID’, so I just select that from the form and build my url string with it.

public void SaveAndContinue(){    string guid = MainDataSource.CreateNavigator().SelectSingleNode
("/my:Application/my:Logic/my:GUID", NamespaceManager).Value;    string url = "http://chamois.dev.iwdev.isc-software.local/
ChamoisPOC/" + guid + ".xml";    string relativeUrl = "/ChamoisPOC/" + guid + ".xml";    string header = @"<?xml version='1.0' encoding='UTF-8'?>
<?mso-infoPathSolution name='urn:schemas-microsoft-
com:office:infopath:MasterSipp:-myXSD-2009-07-21T08-09-49'
solutionVersion='1.0.0.650' productVersion='12.0.0.0' 
PIVersion='1.0.0.0'
href='http://chamois.dev.iwdev.isc-software.local/
FormServerTemplates/MasterSipp.xsn'?>
<?mso-application progid='InfoPath.Document' 
versionProgid='InfoPath.Document.2'?>";
    System.Net.WebRequest request = BuildRequest(url,header);
    //request.Credentials = objCredentials;
    System.Net.WebResponse response = request.GetResponse();
    StreamReader rdr = new StreamReader(response.GetResponseStream());
    string htmlresponse = rdr.ReadToEnd();
    rdr.Close();
    response.Close();
    //check item was added
    int itemID = CheckItemExists("FileLeafRef", guid + ".xml", "Chamois-POC");
    if (itemID == -1)        throw new ApplicationException("Document has not been loaded. 
See server response\n" + htmlresponse);}

(In production, you’d also want to call the GetListItems webservice to ensure it was saved correctly)

So, after being tied up to whichever event you choose (i’m saving in the background as the user fills out the form) this should quietly dump the xml file into a library. For some reason the library doesn’t recognise the xml as being an InfoPath file, so to open the form again you’ll need to send the user to the FormServer.aspx?xmllocation=http://sharepoint/forms/123456.xml page, and it will work fine.

If you publish the form as administrator approved, and apply the content type to the library you’re saving into, it will automatically populate the promoted properties as it saves. Lucky, eh…

Hopefully this makes sense – I searched for a neater way of doing this for ages, but i’ve found this approach to be the most manageable.

.davros.

Older Posts »

Follow

Get every new post delivered to your Inbox.