Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Friday, October 25, 2013

Creating a printable InfoPath form

I don't like printing.  But inevitably, someone will want to do it somewhere.

We have a list, which uses an InfoPath form for data entering and viewing.  In here, we created a Print view, which is basic black text on white background, and read-only.

However, when trying to print this view, the rest of our SharePoint master page and branding is printed with it, and it doesn't look very professional.  So we needed to create a printable version of this Print view.

Some suggestions online included using jQuery to remove everything BUT the InfoPath form, but this sounded like a messy way of doing things.  Instead, I figured I could just create a new blank page in SharePoint Designer and grab the item ID from the URL.

My first attempt failed.  I tried using a Query String Filter Web Part, but then realised that sending an ID to an InfoPath Web Part doesn't do what you'd think it would do.  It doesn't magically open the item you're referencing with the ID, it simply changes the InfoPath form item ID.  You could use this method for pre-populating an InfoPath form based on parameters in your query string, but not for actually loading an already-existing form.

I figured that you could instead use that ID to filter a List View of your list, and then send that single item to the InfoPath web part.  This would also mean I wouldn't need the Filter Web Part, as a List View has its own Filter and Parameter settings.  So, here's what I did.

  1. Using SharePoint Designer, create an ASPX page in your site called PrintForm.aspx.
  2. In the ASPX page, add an InfoPath form web part, and configure the web part to use the list you're trying to print items from.  Configure this web part to use the correct Print view that you've already created in InfoPath Designer.
  3. Somewhere else on the page, add a Data View, and again configure to use the list you're trying to print items from.  Configure this web part to be hidden or not visible (unless you want to see the list view as well).
  4. With the List View web part selected, add a Parameter.  This will be a query string parameter with the name ID, and the Query String Variable of ID as well.  (You can change this to ItemID or something else if you want)
  5. Next, add a Filter for the List View web part.  This will get the Field Name ID to equal the parameter you just created, which will be displayed as [ID] or [ItemID] or whatever you chose in the previous step.
  6. Finally, Add a Connection from the List View to the InfoPath web part.  You want to Send Row of Data To the InfoPath web part, using the Target Action "Get Form From".  
  7. Save and check in the file as appropriate.

Now, if you try to access the URL of this page with an ID added to the end, you will get a nice, basic printable view of your data.  You'll want the URL to look like this:

http://sharepoint/sitename/Pages/PrintForm.aspx?ID=25

What you'll need to do then is add a Print button to the normal Read or Edit view of the InfoPath form, which will send the user to that URL above, with the current item ID after the ID= (in the example above, the item ID is 25).

There's also a little bit of JavaScript you can throw in to your PrintForm.aspx page which will tidy up a few last remnants of the InfoPath web part - namely, the web part name, and the light blue border.  It also presents the user with their browser Print dialog, to save them having to go to File/Print.  It looks like this:

<script src="/scripts/jquery-1.9.1.min.js" type="text/javascript"></script> 
<script type="text/javascript">
  $('.ms-WPHeader').hide();
  $('.ms-WPBorder').css('border', 'none');
  setTimeout(function() {
    window.print();
  }, 500);
</script>

Edit: added a setTimeout before printing, because it was printing a blank page, even though print preview was working correctly.

Friday, September 6, 2013

How to search a list using a Content Editor web part

Had a challenge for a little while - a large list, over 4000 items, that need to be searchable.  Our staff don't want to understand how to use columns to filter, and they like text boxes that they can type in to.

Only found out today that you can search a list using a query string, a la:

http://sharepoint/Lists/Applications/AllItems.aspx?FilterName=Title&FilterMultiValue=*adobe*

This will bring back all items in this list that has a title containing the word "adobe".  Changing FilterName to the name of the column you wish to search will enable you to search other columns as well.

So, with a bit of a kickstart from here - SharePoint List Search in Moss 2007 - I adapted and came up with this code, which you can easily shove into a Content Editor web part at the top of your list page (AllItems.aspx, in this case).

<script type="text/javascript">
function RedirectUrl() {
var cs = document.getElementById("searchText").value;
var url = '';
url = "FilterName=Title&FilterMultiValue=*" + cs + "*";
window.location.href = "AllItems.aspx?" + url;
};
</script>
<div style="border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; background: #efefef; border-bottom: #cccccc 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; margin: 10px auto 0pt; border-left: #cccccc 1px solid; display: block; padding-right: 5px; width: 60%">
<h3 style="text-align: center">
Type in this box to filter the list below:
<input class="search" id="searchText" type="text" style="padding-bottom: 10px; padding-top: 10px; padding-left: 10px; padding-right: 10px"/>
<input id="btnSearch" onclick="return RedirectUrl();" type="button" value="Search"/>
</h3>

</div>

If you would like more information on throwing things around in a query string to filter or sort a list, have a look at this lovely blog post: Search, Filter or Sort Lists from a Query String.

Wednesday, November 7, 2012

Removing a document/list web part from a page if the list is empty

I have a web part page which has a few document web parts - the web parts have filters applied so they only show relevant items to that particular user.  However, sometimes there are no items to show, and then the user is shown a box with nothing in it, apart from a typical SharePoint message about how there are no items.  This can look a bit messy.

I finally found a solution, posted by Mike Smith (of Mike Smith's Tech Training Notes), which uses JavaScript to remove the empty web part.  If I had spare time, I would rewrite this in jQuery (as everything else on my SharePoint environment is in jQuery), but it's perfectly functional as it is now.  Thanks Mike, you're a star!

Friday, June 15, 2012

Getting started with the Facebook API

I'm developing a site that requires users to log in, but I've opted to only allow access from Facebook users for now.  I need the user to grant access for Facebook to give me access to their profile, and then I need to actually get their profile.  The Facebook API documentation is thorough, but still wouldn't work without a few experiments and changes, so I figured this might be useful for someone else.

The code will present a button for the user to Login to Facebook, which will request access from Facebook.  The user will get a window asking for permission.  This only occurs once per user, or if they're not logged into Facebook.

The code will then grab the user's Facebook profile details, such as their name.

Don't forget to change <MY APP ID> to the app id given to you by the Facebook Developer site when you create your app.

Javascript:
// Initialise the Facebook API - note that the API itself is loaded
        // further down in the code
        window.fbAsyncInit = function() {
          FB.init({
            appId      : '<MY APP ID>',
            status     : true,
            cookie     : true,
            xfbml      : true,
            oauth      : true,
          });
         
        // Subscribe to an event in the Facebook API - this event
        // will fire whenever a change in authorisation status occurs.
        // This will happen when the user's Facebook account is
        // connected (essentially, authorised), or if the access token
        // expires.
        FB.Event.subscribe('auth.statusChange', function(response) {
            if(response.status == "connected") {
                // Logging lots of stuff to the console - you won't need all of this
                console.log(response);
                // Facebook account connected successfully - can now do things
                // with the Facebook API. First we really need the access token.
                useraccesstoken = response.authResponse.accessToken;
                console.log(useraccesstoken);
                // I'm taking the userID but only because I'm keeping a record
                // of who's connected. You might not need this.
                fbuid = response.authResponse.userID;
                               
                // Let's get the user's Facebook profile information, by passing
                // the useraccesstoken to prove that we have access.
                FB.api('/me?access_token=' + useraccesstoken, function(response) {
                    // Log the user's Facebook profile data object to the console,
                    // using the useraccesstoken taken from the auth.statusChange
                    console.log(response);
                });

            } else {
                // If status changes to anything other than "connected",
                // it's assumed the connection has been lost or there is
                // an error.
                console.log("Facebook login lost.");
            }
          });

        };
        // Load the Facebook API
        (function(d){
           var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
           js = d.createElement('script'); js.id = id; js.async = true;
           js.src = "//connect.facebook.net/en_US/all.js";
           d.getElementsByTagName('head')[0].appendChild(js);
         }(document));
HTML:
<div id="fb-root"></div>
<div class="fb-login-button">Login with Facebook</div>