Monday, December 21, 2009

Master Pages and Master Pages

You might expect that when you want to create a custom Master Page that you can just make a copy of the “default.master” Master Page and customize from there. After all, it is the default Master Page that is used on every site out-of-the-box, so it should be a good starting point.

Unfortunately this is not the case. After using a customized copy of the default Master Page it was noticed that publishing pages, in particular those in Wikis, were not being indexed in search. While these pages appeared normally in the browser, the search logs were displaying the message “Content for this URL is excluded by the server because a no-index attribute”. Poor English aside, this error message completely fails to identify the problem.


Further investigation shows that while the pages pull up fine using the Intranet site URL, they do not pull up when using the server name for the site as defined in the Alternate Access Mappings and as used in the indexing process. Changing the Master Page for the site to one of the various out-of-the-box options fixes the problem.


If you open up the default.master Master Page and the OrangeSingleLevel.master Master Page in SharePoint Designer and compare the Register commands at the top of the code you will notice that OrangeSingelLevel.master has quite a few that are not in default.master. Most of these revolve around Publishing. Copy these to your custom Master Page and it should now be viewable via the server name and indexed properly.

Friday, December 18, 2009

List Checkboxes, Indexing, and Input Forms

When you have a SharePoint List you can easily create columns. The Choice column type is great as you can specify a list of possible choices for the user. If a user should have the option to select multiple options from the list you can set the choice column to display using checkboxes. Good stuff, unless you want the user to be able to search on those choices.

SharePoint has a limitation in that choice columns set to use checkboxes cannot be indexed for searching.

If you must have a list of choices that allow multiple selections via checkboxes and is indexable then a workaround is required. The best option found so far is using a “Multiple lines of text” column, setting it to be indexed, and then modifying the input form with the checkboxes and using that to populate the text box.

After that you must set up your New and Edit import forms. Start off with the steps in the Working with a List Input Form post.

Once you are ready, you can add your choices and the JavaScript needed to add selected choices to the text field. The following work is built off of the following Microsoft post for Using Javascript to Manipulate a List Form Field.

This is a very basic implementation showing the general idea. Future posts will focus on using AJAX to pull lists of items which could be used to automatically populate the set of checkboxes.

The checkboxes can go in the same table cell as the text field. In this case I have 10 checkboxes:

<input name="Checkbox1" id="Checkbox1{generate-id()}" type="checkbox" value="Value1" onclick="updatechoices()" />Option1<br />
<input name="Checkbox2" id="Checkbox2{generate-id()}" type="checkbox" value="Value2" onclick="updatechoices()" />Option2<br />
<input name="Checkbox3" id="Checkbox3{generate-id()}" type="checkbox" value="Value3" onclick="updatechoices()" />Option3<br />
<input name="Checkbox4" id="Checkbox4{generate-id()}" type="checkbox" value="Value4" onclick="updatechoices()" />Option4<br />
<input name="Checkbox5" id="Checkbox5{generate-id()}" type="checkbox" value="Value5" onclick="updatechoices()" />Option5<br />
<input name="Checkbox6" id="Checkbox6{generate-id()}" type="checkbox" value="Value6" onclick="updatechoices()" />Option6<br />
<input name="Checkbox7" id="Checkbox7{generate-id()}" type="checkbox" value="Value7" onclick="updatechoices()" />Option7<br />
<input name="Checkbox8" id="Checkbox8{generate-id()}" type="checkbox" value="Value8" onclick="updatechoices()" />Option8<br />
<input name="Checkbox9" id="Checkbox9{generate-id()}" type="checkbox" value="Value9" onclick="updatechoices()" />Option9<br />
<input name="Checkbox10" id="Checkbox10{generate-id()}" type="checkbox" value="Value10" onclick="updatechoices()" />Option10<br />
<br />


The following javascript is the first thing in the <asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server"> section.

<script type=text/javascript>

// this function will identify the text field that you are adding your choices to
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
var len = identifier.length;
var tags = document.getElementsByTagName(tagName);
for (var i=0; i < tags.length; i++) {
var tempString = tags[i].id;
if (tags[i].title == title && (identifier == "" tempString.indexOf(identifier) == tempString.length - len)) {
return tags[i];
}
}
return null;
}

// put the checked items into the text box
function updatechoices() {
var choicelist = "";
var checkboxidprefix = "Checkbox"; //checkbox id prefix
var numberofchoices = 10; //change to reflect the number of checkboxes
var nameoftextbox = "Choice"; //change to reflect the name of the textarea
// get the values of the checked checkboxes, put them in a semicolon delimented string
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = checkboxidprefix + i;
if (document.getElementById(checkboxnumber).checked == true) {
choicelist = choicelist + document.getElementById(checkboxnumber).value + "; ";
}
}
// trim whitespace off ending
while (choicelist.substring(choicelist.length-1,choicelist.length) == ' ') {
choicelist = choicelist.substring(0,choicelist.length-1);
}
// put the list of choices into the text box
var theSelect = getTagFromIdentifierAndTitle("textarea","",nameoftextbox);
document.getElementById(theSelect.id).value = choicelist;

}

// pull the text out of the text box and set the checked values on the checkboxes (for when page is loaded)
function SetCheckboxes () {
var checkboxidprefix = "Checkbox"; //checkbox id prefix
var numberofchoices = 10; //change to reflect the number of checkboxes
var nameoftextbox = "Choice"; //change to reflect the name of the textarea
var ChoiceField = getTagFromIdentifierAndTitle("textarea","",nameoftextbox);
var ChoiceValues = document.getElementById(ChoiceField.id).value;
//if only one choice is set, check that checkbox
if (ChoiceValues.indexOf(";") <=0) {
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = "checkbox" + i;
if (document.getElementById(checkboxnumber).value == ChoiceValues) {
document.getElementById(checkboxnumber).checked = true;
}
}
} else { //else split up the text box info and check the appropriate boxes
ChoiceValues = ChoiceValues.replace(/; /g, ';');
var ChoiceValuesArray = ChoiceValues.split(';');
for (k=0;k<ChoiceValuesArray.length;k++) {
for(var i = 1; i <= numberofchoices; i++) {
checkboxnumber = checkboxidprefix + i;
if (document.getElementById(checkboxnumber).value == ChoiceValuesArray[k]) {
document.getElementById(checkboxnumber).checked = true;
}
}
}
}
}

// onload set the checkboxes to match the text box
_spBodyOnLoadFunctionNames.push("SetCheckboxes");
</script>

Tuesday, December 15, 2009

Working with a List Input Form

When you have a or document library it is sometimes useful to be able to modify the input forms. You may wish to add browser side validation, AJAX lookup fields, or other options.

The first step is to open your site in SharePoint Designer, navigate to your list, then the Forms folder, and open the New or Edit page. In most lists you'll need to update both, but in Document and Picture libraries you just need to update the Edit page.

On this page you'll see the web part containing the list input fields. Unfortunately you can't edit this web part. Right click on it, select “Web Part Properties”, expand Layout and check the Hidden box. You can't delete this web part or you will have problems with the page, but you can hide it. Next go to Insert on the menu bar, choose “SharePoint Controls” and then “Custom List Form”. Select your list, content type and if this is for the New page or the Edit page type of form. This will place a new web part on the page that you can modify.

It is helpful at this point to right-click on the new web part, choose “Show Common Control Tasks” and on the pane that pops out check the “Show with sample data” check box.

From here you can add JavaScript validation, AJAX lookups, HTML, or whatever else you may need.