SharePoint Designer 2013’s Missing Design View – Still

Here is a question that came in from my blog today.

My company is starting to plan to migrate to SP 2013 and I just found out that the design and split view is not included in SP Designer. This is going to be absolutely devasting for us as this is really the only way we do development. We have so many items created with XSL that I can’t imagine what we are going to do when we migrate. Can you update me on if MS has reconsidered adding that back and if not, where do I go to post my comments and to add my voice to those that are not happy?

Unfortunately, questions about the missing Design View in SharePoint Designer 2013 are fairly commonplace and sadly I have no good news. Those views are gone and as far as I know are not coming back. Any uproar that occurred due to my earlier posts like SharePoint Designer 2013′s Missing Design View – It’s Official fell on deaf ears.

I tend to write my own XSL, and one can certainly continue to do so using SharePoint Designer 2013. The Design View was always inexact, but since it was where we saw any error messages, I find that is why I miss it the most.

Display Templates – which are built of markup and script – are worth looking at, as are frameworks like Knockout or AngularJS. Yes, new things to learn, but more the way Web development is headed.

I also don’t know of anywhere to go to register complaints about this. I find that the MSDN Forums may make you feel better, but are rarely monitored by Microsoft people who can push for changes. Microsoft Connect is supposed to be the place to report bugs and give feedback, but things seem to languish there as well.

None of this is much solace for people who need to maintain existing XSL-based solutions. Bottom line: we all need to learn new tricks and/or rewrite our older XSL-based solutions.

m4s0n501

SharePoint and Exchange Forum (SEF) 2013 Wrap Up

Panorama of Stockholm's Royal Palace

Panorama of Stockholm’s Royal Palace

I’m just returning from another splendid time at the SharePoint and Exchange Forum (SEF) conference in Stockholm, Sweden. This year, the conference was actually international: it was held on the Silja Symphony cruise ship in both the Stockholm and Helsinki harbors. It was an interesting and fun venue for a conference, and for those organizers out there looking for a fresh, new idea, this was a great one.

Silja Symphony at port in Helsinki

Silja Symphony at port in Helsinki

Many thanks to Göran Husman (@GHusman) and the entire Humandata team for a warm welcome (as always), and a job very well done on the conference. I hope to return to Stockholm – or wherever else we might sail – many times in the future.

It was great fun to have my wife Melanie (@koochiku) along on this trip – her first SharePoint conference. Now she will understand just a little bit why I go on and on about why the SharePoint community is such a wonderful thing to be a part of.

I also really enjoyed seeing my compadre in “no code” solutions (we call it code, regardless what everyone else says) and friend Christian Ståhl (@cstahl) and having the chance to take a walking tour of Helsinki with him.

Here are the slide decks from my three sessions at the conference, which are up on SlideShare. Feel free to comment here with any questions or suggestions any time.

Tack för en underbar konferens!

Item ‘Modified By’ Value Doesn’t Change: Fixing a Damaged Column Schema

I ran into an odd situation the other day at one of my clients.

Modified By ExampleWhen people edited existing list or library items in *some* lists (we couldn’t discern a pattern) the Modified By (Editor) column value did not change. The date/time stamp (Modified) was updated, but not the person who made the modification. We found several good posts out there on them Interwebz, but I though it would be useful to pull things together and outline what we tried in case it could help others.

There were two posts we found that got us started:

The first post led us to look at the Modified By column’s schema; the second led me to think that I could do the fixes using the SOAP Web Services.

I was able to pull the schema for the Modified By Site Column using the GetColumns operation in the Webs Web Service. (Of course I turned to SPServices first – it’s my hammer.)

$().SPServices({
  webURL: "/",
  operation: "GetColumns",
  completefunc: function(xData, Status) {
  }
});

I was able to look at the returned XML in Firebug, copy it out, and find the schema for the Modified By column.

Bingo. From Victor Butuza’s post, we know that the schema should look like this:

<Field ID="{d31655d1-1d5b-4511-95a1-7a09e9b75bf2}"
 ColName="tp_Editor"
 RowOrdinal="0"
 ReadOnly="TRUE"
 Type="User"
 List="UserInfo"
 Name="Editor"
 DisplayName="Modified By"
 SourceID="http://schemas.microsoft.com/sharepoint/v3"
 StaticName="Editor"
 FromBaseType="TRUE"/>

Instead, it looked like this (I’ve changed several of the attribute values to protect the guilty, but you should get the point):

<Field ID="{d31655d1-1d5b-4511-95a1-7a09e9b75bf2}"
 Name="Editor"
 SourceID="http://schemas.microsoft.com/sharepoint/v3"
 StaticName="Editor"
 Group="_Hidden"
 ColName="tp_Editor"
 RowOrdinal="0"
 Type="User"
 List="UserInfo"
 DisplayName="Modified By"
 SystemInstance="SQL_DB_Name"
 EntityNamespace="http://servername"
 EntityName="Partners"
 BdcField="OrganizationId"
 Profile=""
 HasActions="True"
 SecondaryFieldBdcNames="0"
 RelatedField="Partners_ID"
 SecondaryFieldWssNames="0"
 RelatedFieldBDCField=""
 RelatedFieldWssStaticName="Partners_ID"
 SecondaryFieldsWssStaticNames="0"
 AddFieldOption="AddFieldInternalNameHint"
 ReadOnly="TRUE"
 Version="1">
</Field>

Some way or other, the Modified By (Editor) column had been changed. We noticed quite a few odd things in the schema above, which I’ve highlighted. It looks like attributes from some BDC connection had made it into the schema, which wasn’t good. More importantly, the important FromBaseType="TRUE" attribute was missing.

I tried for a while to get the SOAP operation UpdateColumns to work in a test environment. (I was very careful to do this in a snapshot of a VM because messing with the Modified By column could be catastrophic.) Caution proved wise, as each time I tried to update the Modified By schema, the Site Column management pages (_layouts/mngfield.aspx and _layouts/fldedit.aspx) no longer worked properly. Even though I believe I had the syntax correct (based on Karthick‘s post above – note that the MSDN documentation is pretty sparse), I simply couldn’t get UpdateColumns to work without breaking things.

So I turned to Powershell. I’m no Powershell guy, but it’s a scripting language like any other and I found some good starting points out on the Web to get me going. What I ended up with was a script that repaired all of the attributes of the Modified By column in a single list.

$s = get-spsite http://servername
$w = $s.OpenWeb("/sitename/")
$l = $w.Lists["listname"]
$f = $l.Fields.GetFieldByInternalName("Editor")

write-host "BEFORE field at " $w.Url  " List "  $l.Title  "  is " $f.schemaxml

#add at the end of the schema the needed string and update the field and list
$f.SchemaXML = $f.SchemaXML -replace ' SystemInstance="SQL_DB_Name"',''
$f.SchemaXML = $f.SchemaXML -replace ' EntityNamespace="http://servername"',''
$f.SchemaXML = $f.SchemaXML -replace ' EntityName="Partners"',''
$f.SchemaXML = $f.SchemaXML -replace ' BdcField="OrganizationId"',''
$f.SchemaXML = $f.SchemaXML -replace ' Profile=""',''
$f.SchemaXML = $f.SchemaXML -replace ' HasActions="True"',''
$f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldBdcNames="0"',''
$f.SchemaXML = $f.SchemaXML -replace ' RelatedField="Partners_ID"',''
$f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldWssNames="0"',''
$f.SchemaXML = $f.SchemaXML -replace ' RelatedFieldBDCField=""',''
$f.SchemaXML = $f.SchemaXML -replace ' RelatedFieldWssStaticName="Partners_ID"',''
$f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldsWssStaticNames="0"',''
$f.SchemaXML = $f.SchemaXML -replace ' AddFieldOption="AddFieldInternalNameHint"',''
$f.SchemaXML = $f.SchemaXML -replace '/>',' FromBaseType="TRUE" />'

$f.Update()
$l.Update()

write-host "FIXED field at " $w.Url  " List "  $l.Title  "  is " $f.schemaxml

$w.Dispose();
$s.Dispose();

I also wrote a Powershell script to find all of the lists where this aberration had occurred in the Modified By column:

$siteURL = "http://servername"
$site = Get-SPSite($siteURL)

$errors = 0
$thisWebNum = 0

foreach($web in $site.AllWebs) {

  $thisWebNum = $thisWebNum + 1
  write-host $thisWebNum " Web " $web.Url  " Created on "  $web.Created

  $listCounter = $web.Lists.Count

  for($i=0;$i -lt $listCounter;$i++) {

    $list = $web.Lists[$i]
    $thisListNum = $i + 1

    write-host "(" $thisListNum "/" $listCounter ") [" $list.Title "] Created on "  $list.Created

    $f = $list.Fields.GetFieldByInternalName("Editor")

    if ($f.SchemaXML -NotMatch 'FromBaseType="TRUE"')
    {
      $errors = $errors + 1
      write-host "  Issue in schema " $f.schemaxml
    }
  }
  $web.Dispose();
}
$site.Dispose();

write-host "TOTAL ISSUES: " $errors

This script told us that we had 283 lists with the issue. Clearly this has been going on for a long time and no one had caught it, though we still can’t see any patterns in the date/time stamps or which lists have the issue.

We’ve fixed the two lists where the client folks had noticed the Modified By issue as well as the Site Column itself. We’re pausing at this point just to make sure that we don’t see any oddities based on the fix, but we’re optimistic that we know what was happening and that we have a valid fix. After we let things settle for a little while, we’ll run the fix script on the rest of the lists with the issue by combining the two scripts to loop through all of the lists with the issue.

Have you ever run into a broken schema issue like this in your environment? If so, how did you fix it?

<UPDATE date=”2013-10-17″>

We hadn’t seen any issues since we’d applied the fix I described above, so today I ran through the rest of the messed up lists and applied the fix. The Powershell script below loops through all of the sites in the Site Collection, then through all of the lists in each site, and fixes the Editor column where it’s got issues.

$siteURL = "http://servername"
$site = Get-SPSite($siteURL)

$errors = 0
$thisWebNum = 0

foreach($web in $site.AllWebs) {

  $thisWebNum = $thisWebNum + 1

  $listCounter = $web.Lists.Count

  for($i=0;$i -lt $listCounter;$i++) {

    $list = $web.Lists[$i]
    $thisListNum = $i + 1

    $f = $list.Fields.GetFieldByInternalName("Editor")

    if ($f.SchemaXML -NotMatch 'FromBaseType="TRUE"')
    {
      $errors = $errors + 1

      # fix the schema and update the field and list
      $f.SchemaXML = $f.SchemaXML -replace ' SystemInstance="GivingData"',''
      $f.SchemaXML = $f.SchemaXML -replace ' EntityNamespace="http://servername"',''
      $f.SchemaXML = $f.SchemaXML -replace ' EntityName="Partners"',''
      $f.SchemaXML = $f.SchemaXML -replace ' BdcField="OrganizationId"',''
      $f.SchemaXML = $f.SchemaXML -replace ' Profile=""',''
      $f.SchemaXML = $f.SchemaXML -replace ' HasActions="True"',''
      $f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldBdcNames="0"',''
      $f.SchemaXML = $f.SchemaXML -replace ' RelatedField="Partners_ID"',''
      $f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldWssNames="0"',''
      $f.SchemaXML = $f.SchemaXML -replace ' RelatedFieldBDCField=""',''
      $f.SchemaXML = $f.SchemaXML -replace ' RelatedFieldWssStaticName="Partners_ID"',''
      $f.SchemaXML = $f.SchemaXML -replace ' SecondaryFieldsWssStaticNames="0"',''
      $f.SchemaXML = $f.SchemaXML -replace ' AddFieldOption="AddFieldInternalNameHint"',''
      $f.SchemaXML = $f.SchemaXML -replace '/&gt;',' FromBaseType="TRUE" /&gt;'

      $f.Update()
      $list.Update()
      write-host "FIXED field at " $w.Url  " List "  $l.Title  "  is " $f.schemaxml
    }

    if ($errors -gt 0)
    {
      write-host $thisWebNum " Web " $web.Url  " Created on "  $web.Created  " had " $errors " errors"
    }
    $errors = 0;

    $web.Dispose();
  }
$site.Dispose();

</UPDATE>

SharePoint Saturday New Hampshire (SPSNH) 2013 Wrap Up

Thanks to everyone who attended my session at SharePoint Saturday New Hampshire (that’s SPSNH to many of you) over the weekend.

Thanks also to everyone who worked so hard to make SPSNH happen this year. It’s a helluva lot of work to put together events like this, and everyone deserves a big round of applause, no matter how many times they do it.

Slides for my session SharePoint Solutions with SPServices are posted on SlideShare, or you can view them here.

Rock on with SPServices, and let me know what cool stuff you come up with!

How to: Selecting Multi-Select Choice Columns in Forms with jQuery

As I’ve written many times in the past, I get a lot of questions via this blog. I try to answer some of them, but often they simply come in too fast and furious for me to get to them all.

Answering the questions gives me some benefits, too, or course. First, I often learn something I didn’t know (always a good thing), and second, I often turn the question and its answer into a blog post like this.

This one came in a few weeks back and I just found it as I was cleaning out my inbox.

Your blogs, post really helpful to me. [Nice – always start a blind question with some sort of pleasant preface. Really.]

Currently I am working in a project with SharePoint Server 2013. I am using jquery/javascript for few custom operations. I have a list “Task Assignment” where I am using a choice type column with “checkboxes multiple selection” enabled named “Task Category”. I need to trigger onchange or click event when user check/uncheck any items of the choice field.

But I could not get the element by id or tag name. I have worked with radio button using below statement.

$('input:radio[name$="0b57f_$RadioButtonChoiceField"]').bind("change", reviewedChanged);

I have tried to change this to work with multiple selection choice field.

$('input:checkbox[name$="f7c37_MultiChoiceTable"]').bind("change", assignTask);

But it is not working. Can you please suggest me.

Thanks in advance. [Also nice. It’s amazing how few people ever say please or thank you.]

When I answer, I always preface my answer with something like this. (I have a signature set up in Outlook with this text because I use it so much.)

First off, thanks for turning to me with your question.  I’m happy to try to help, but you should really use a public forum to post your question. Some of the forums that can be useful are:

* SharePoint forums on MSDN (http://social.msdn.microsoft.com/Forums/sharepoint/)

* SharePoint on StackExchange (http://sharepoint.stackexchange.com)

Many people are active in these forums and you’re likely to get prompt responses. Additionally, others can benefit from finding any useful answers you get in the forums.

I was off the grid in Africa when this question came in. If it had any sort of time sensitivity, then sending it just to me wasn’t a good strategy. Plus, I may simply have never answered.

9-17-2013 2-19-59 PMThen I get to the answer. In this case, in my SharePoint Online (2013) test environment, a multi-select checkbox renders as a set of input elements like so:

<table id="test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceTable" cellspacing="1" cellpadding="0">
  <tr>
    <td>
      <span title="a" class="ms-RadioText">
      <input id="test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceOption_0" type="checkbox">
      	<label for="test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceOption_0">a</label>
      </span>
    </td>
  </tr>
  <tr>
    <td>
      <span title="b" class="ms-RadioText">
        <input id="test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceOption_1" type="checkbox">
        <label for="test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceOption_1">b</label>
      </span>
    </td>
  </tr>
...

My column name is “test”, so we see ids like “test_2b0bc958-232c-4e77-a8b1-7b3a1745f84d_MultiChoiceOption_0″. This means the selector could be something like:

$("input[id^='test_'][id*='_MultiChoiceOption_']").change(function() {
  alert($(this).attr("id"));
});

The code above is what I used to test. I find that this syntax makes more sense from a readability perspective over using bind, but that’s more of a stylistic thing.

The selector breaks down like this:

  • find input elements – $(“input
  • where the id starts with “test_” – [id^=’test_’]
  • and the id contains “_MultiChoiceOption_” – [id*=’_MultiChoiceOption_’]”).

The most important message here is that you can’t make any assumptions about the way ids are constructed in SharePoint because they are all over the map. You simply have to get good at using the various DOM inspectors, including the Internet Explorer Developer Toolbar and Firebug.

Keep in mind that some controls (not this one) may be rendered differently in IE than in other browsers – even in SharePoint 2013 – so you need to test your selectors in multiple browsers. Once you get familiar with how things like ids and “controls” – on the browser side, controls are collections of HTML elements and script – are rendered, you’ll feel more comfortable knowing when you’ve got it right.