Create a jQuery + SharePoint instant search/filter

We’re going to use jQuery and SharePoint to create an “instant” search/filter of a Content Query WebPart and/or List View. This uses the .find(), :contains(), .val(), .hide(), .show(), :not(), .change(), and .keyup() jQuery codes. You can learn all about those from the jQuery documentation. This is all client-side, and only deals with what shows on the page. I’m not going to deal with any server requests, pagination of lists, etc. That’s for later.

Check out the video tutorial below:

Skip ahead:

You’ll be creating something like this:

Step 1: Load jQuery script in your master page

Because our SharePoint installation is secured, I downloaded the latest jQuery build instead of sourcing it from online. So my script in the master page looks like this:

<script type="text/javascript" src="/Style Library/scripts/jquery.js"></script>

Step 2: Create a page with a CQWP or a list view

Doesn’t matter which one you create, but just have some content we can filter.

Step 3: The Code

I built a lot of this from scratch using the jQuery documentation, but a big shout-out goes to Kilian Valkhof’s article, which helped me organize a lot of what I had. This first part enables case-insensitive searching. It came from Kilian Valkhof, who apparently sourced it from Mike Merrit’s LiveFilter jQuery Plugin, but I’m not sure. Either way, I didn’t write it :). Note:if you use this expression, it means you need to change every instance of contains (small C) to Contains (capital C).

<script type="text/javascript">// <![CDATA[
jQuery.expr[':'].Contains = function(a,i,m){return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;};

Now we start our function anytime the search input box is changed. Once it’s changed, it sets the value of a variable we have called “txt”.

$(document).ready(function(){
  $("input.search").change(function() {
      var txt = $("input.search").val();

Here we have an IF statement that just checks if there is indeed something in the search box, ELSE everything goes back to normal. If there is something inside the search input box, we are going to do two things. First, we’ll find any row that does NOT contain the string, and we’ll hide that row. Then we’ll find any row that DOES contain that string, and we’ll show that row. Finally, we chain a “keyup” function to the change function so that as we type everything is happening all together.

    if (txt) {
     $("#WebPartWPQ4").find("tr.ms-itmhover:not(:Contains("+txt+"))").hide();
     $("#WebPartWPQ4").find("tr.ms-itmhover:Contains("+txt+")").show();
    } else {
     $("#WebPartWPQ4").find("tr.ms-itmhover").show();
    }
  }).keyup(function(){$(this).change();
 })
})
// ]]></script>

And last but not least, we’ll create a simple search input box with a class of “search”. My styling is attached, feel free to erase and do your own:

<div style="padding: 5px; border: 1px solid #cccccc; width: 60%; margin: 10px auto 0pt; background: none repeat scroll 0% 0% #efefef; display: block;">
<h3 style="text-align: center;">Instant search: <input class="search" style="padding: 10px;" type="text" /></h3>
</div>

Step 4: Final touches

The final step is to put this code inside a Content Editor WebPart (I know, I know, but this is for the sake of this tutorial, definitely not best practice). You’ll have to change the target it’s searching and replace it based on whether or not you’re using a CQWP or a list view. A few tips:

#WebPartWPQ4 is the ID of the webpart on my page, but it might change depending on how many webparts you have, what kind they are, etc.

tr.ms-itmhover seems to be the correct selector for any row in a list view

For searching in a Content Query WebPart, I use this:

find("a:Contains("+txt+")").parents("li.dfwp-item").show();

Note that I used parents instead of parent because the latter only searches one level up. CQWP list items are so intricately embedded deep down that you have to find the text inside the link, and then hide the whole list item. Just play around with it, let me know if you need any help.

Create a feedback button for Sharepoint 2010

Ever want to get feedback from your users without making them go through some laborious process of filling out a survey or sending an email to the helpdesk?

Introducing: the feedback button. It allows your users, no matter what page they are on, to submit their feedback. I’ve found this to be an extremely useful tool for gathering, you guessed it, feedback. And now I’ll teach you how to create one.

Click below to skip ahead:
Create a new list: feedback
Apply the workflow
Edit your master page


Create a new list: feedback


The first step in making this feedback button is to make a custom list into which your feedback will be input. For my list I have two columns. The first column (renamed the required “title” column) is “What page are you on?” I haven’t made the system intelligent, I’m leaving it up to the user to tell me where they are on the site. You never know, it could provide a little hint if they have no idea where they are, or they think they are somewhere they are not. The second column I create is a multi-line textbox column called “Comments”. That’s all I want from my users. Their feedback. Simple.

List Settings

  • Turn approval off, turn off version history
  • Item-level read permissions: read items that were created by the user
  • Item-level create/edit permissions: create items and edit items that were created by the user
  • Disable items to show in search results

Permissions
You’ll want to break permissions on this specific list and allow your users to have contribute permissions on this list alone. Otherwise they will not be able to submit items when they click the feedback button.


Apply the workflow


Create a new workflow on this list called “Feedback Workflow”. I always turn the start options to “start automatically when item is created”. That is really the only scenario with this list.

There is only one step in the workflow, and it should be an “email” step. If you check out my settings, I have put the contents of the comment box, including who wrote it, when they created it, and the page they were on.

Don’t forget to save and publish the workflow!


Edit your master page


This bit is slightly tricky. Not only do you need to put the button on your master page sidebar, but it needs to open the form in a modal dialog box window (at least that’s my preference). So below you’ll see the javascript I use to enable that dialog box on the link:

<div class="feedback"><a href="javascript;" onClick="javascript:SP.UI.ModalDialog.showModalDialog({ url: '/Lists/Feedback/NewForm.aspx', title: 'Add item' }); return false;"><h4>Questions?</h4><span>Click to send feedback</span></a></div>

Also, for some reason you want to style your feedback button like mine is style, here’s my CSS:

.feedback {
	margin-top:10px;
	text-align:center;
}
.feedback a {
	text-decoration:none;
	color:inherit;
	background:transparent url('/Style Library/images/feedback.png') no-repeat top center;
	display:block;
	height:40px;
}
.feedback a:hover {
	background:transparent url('/Style Library/images/feedback.png') no-repeat bottom center;
}
.feedback a h4 {
	color:#FFFF99;
	font-family:'Ubuntu Bold';
	font-weight:bold;
	font-size:1.3em;
	padding-top:2px;
}
.feedback a span {
	color:#ffffff;
	font-size:0.9em;
}

Append the URL with a Date selected from the jQuery “datepicker”

This will append you url so it will display “&date=2011-10-14″ using jQuery + jQuery UI (for the calendar picker).

<form action="" method="post" class="datepickerform">
<input id="datepicker"/>
<input type="submit" value="Go" />
</form>

and the javascript

<script type="text/javascript">
	// Datepicker
        $(document).ready(function(){
	$('#datepicker').datepicker({inline: true, dateFormat: 'yy-mm-dd'});

$("form").submit(function() {
  var pathname = window.location.pathname;
  var datepickedup = $("input#datepicker").val();
  window.location.href = (pathname + "?date=" + datepickedup);
  return false;
});
});
</script>

HTML5 Master Page in Sharepoint

Unfortunately I haven’t gotten around to customizing my own, because instead I ran across Kyle Schaeffer’s HTML5-ready Master Page for Sharepoint 2010. So far it seems to work pretty well, but had a bit of trouble up front on a mac. Seems to be working now.

Time will tell how well the replacement of Sharepoint’s ribbon-controlling javascript with using custom CSS & javascript to control it will work well for all situations. I’m really hoping it will though!

So shout-out to Kyle for awesome work. Go to his site, download it and try it out!

The Perfect Text Editor: TextMate

I code in html, css, php, javascript, the list goes on. The most important feature of an editing program to me is speed. For several years I have used Textwrangler, but this week I have switched. In fact…I paid actual money for a text editor. The features it has are great. Here is my synopsis of TextMate (for mac).

1. lightweight. loads very fast, no frills
2. powerful. it understands many many languages. autocomplete tags, auto-close brackets.
3. shortcuts. for end tags, forward and backwards indent, selecting whole lines, typing MULTIPLE LINES at the same time (think large list of ‘li’ tags you want to setup)
4. ability to open a folder structure in the program and keep the folder structure visible and in place as you flip between pages to edit. Very useful for editing themes in wordpress & drupal. in fact, you can save that folder structure as a project for re-opening.
5. pasting from history. that’s right, there is a clipboard history that will allow you to copy things from multiple places in the document, then iterate through your clipboard to paste them one by one elsewhere.

I work for a school, meaning I was able to get the educational discount. But I think with the time that this is going to save me would be well worth the investment even of the full price version.

Download your copy at Macromates.com

Happy coding!

Create a jQuery Accordion with 4 lines of code

This is for anyone who is NOT a pro at javascript or jQuery yet. A super easy way to get an accordion to display things like FAQs. Watch the screencast, or read the tutorial steps below.

Step 1: Create your accordion in HTML
This is a basic wrapper, and then within that wrapper, each question gets wrapped in a div with the class of “question” and each answer gets wrapped in a div called “answer”. Note: I do not put the answer inside the question. You could probably use ul and li code here and be a bit more creative, but this is just one way.

<div class="accordion"> 
 <div class="question">What is the square root of 9?</div>
  <div class="answer">3</div>
 <div class="question">Why is the sky blue?</div>
  <div class="answer">Who knows!</div>
</div>

Step 2: Style the accordion in CSS
Pretty straightforward. I’m giving my questions a bit of a “boxed” look, and then the questions that come from underneath are in an outlined box.

.question {
	display:block;
	background:#330000;
	color:#ffffff;
	font-weight:bold;
	padding:10px;
	cursor:pointer;
	}
.answer {
	padding:5px;
	display:block;
	border:1px solid #ccc;
	margin:5px;
	}

Step 3: Make it all work with jQuery
The jQuery here isn’t that bad. You declare a function when the document is ready. Then you slide up all of the answers so they are hidden. And last but not least, you add a function so that when you click any question, it slides the answer down. I use a slideToggle(); because I like to be able to leave questions open. You could set it so that when you click on any question, it first closes all answers, and then opens the one you like (more of a true ‘accordion’ feel). Onto the code!

$(document).ready(function(){
$(".accordion .answer").slideUp();
$(".accordion .question").click(function(){$(this).next(".accordion .answer").slideToggle('fast')})
});

You should wind up with something like this:

Include external javascript in your Drupal theme file

Go to your theme’s .info file.

Insert a line that says this:

scripts[] = js/script.js

Everything after the ‘=’ is the relative path to your javascript file. This is where you can put your custom actions.

delay: 1d12h