Tuesday, May 27, 2014

Using the SharePoint RichTextBox

Through the course of my own development projects, I had a need to for a rich textbox, for which SharePoint does support OOTB. However, here is the catch - if you wish to employ it, I discovered through rigorous research that manual calls to SharePoint javascript libraries are necessary to invoke needed features, such as full HTML support within the rich textbox. After piecing together all the different namespaces and javascript libraries \ functions from several different informative sites, I arrived at the following working solution. Two functions (With a parameter) are needed that are referenced in the ...\layouts\forms.js library; CreateRichEdit(id), and IsSafeHrefAlert().

CreateRichEdit along with the below script will render out the text box and toolbars, based on the RichTextMode speficied in the InputFormTextBox. IsSafeHrefAlert will ensure that any hyperlinks or pictures inserted via the toolbars will function properly, if used in the way I've documented below that forces the result to be TRUE.

Hope it helps!

______________________________

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<%@ Page Language="C#" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>


<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
<meta name="WebPartPageExpansion" content="full" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>
<SharePoint:CssLink runat="server" Version="4"/>
                <SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true"/>
<SharePoint:SPShortcutIcon runat="server" IconUrl="http://fcbc-sp3/images/Icon3.ico"/>
               
                <SharePoint:SPPageManager runat="server"/>
                <SharePoint:SPHelpPageComponent Visible="false" runat="server"/>


<script type="text/javascript">

function CreateRichEdit(id) {

if (browseris.ie5up && browseris.win32 && !IsAccessibilityFeatureEnabled()) {

g_aToolBarButtons = null;

g_fRTEFirstTimeGenerateCalled = true;

RTE_ConvertTextAreaToRichEdit(id, true, true, "", "1033", null, null, null, null, null, "Compatible", "\u002f", null, null, null, null);

RTE_TextAreaWindow_OnLoad(id);

}

else {

document.write("&nbsp;<br><SPAN class=ms-formdescription><a href='javascript:HelpWindowKey(\"nsrichtext\")'>Click for help about adding basic HTML formatting.</a></SPAN>&nbsp;<br>");

};

}
   var id = "<%= txtmsg.ClientID %>";
  

function IsSafeHrefAlert()
{
return true;
}
   
</script>
</head>

<body  >

<form id="form1" runat="server">
  <asp:ScriptManager id="ScriptManager" runat="server" EnablePageMethods="false" EnablePartialRendering="true" EnableScriptGlobalization="false" EnableScriptLocalization="true" />
<SharePoint:InputFormTextBox ID="txtmsg" runat="server" Rows="20" Columns="50" TextMode="MultiLine"
                RichText="true" RichTextMode="FullHtml" />
                </form>

</body>

</html>

Tuesday, May 20, 2014

Back to Basics - Understanding How JQuery Animate Works

It occurred to me that I should scale back just a bit to help break down the basics of my favorite JQuery feature - the animation. You'll see this come up a lot in my write-ups, as this is such a simple, yet incredibly powerful feature. It calculates and literally "plays out" the difference between a start point and end point, which is not just limited to page locations. To begin, the following items are needed

  • Reference to JQuery library in the header (Latest is currently v 1.11.1)
    • <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.js"></script>
  • Method to invoke the function (Can be bound to whatever handler, such as onLoad, onClick, etc., using JQuery or plain Javascript)
    • function animateThis()
    • {
    • $('#myDiv').animate({
    •    opacity:'0.0',
    •    },1024,function(){doMore())}
    • );
    • }
  • A container to be animated (Div works best)
    • <div id="myDiv">This container will be animated using my parameters</div>


Now, to break down the animate method.


  • $('#myDiv') tells JQuery which element or container ID to animate (Match to the "id" attribute). 
  • .animate tells JQuery to use the "animate" method and perform it
  • ({opacity:'0.0',} tells JQuery which options to use for the animation math. I'm using opacity as example in this case, which, currently set to "0.0", instructs JQuery to animate myDiv from it's current opacity to 0% opacity (invisible). This can be set to different levels, such as "0.5", which would be 50% opaque - put another way, half transparent. The effect for this example is that the contents of myDiv would fade into nothing and disappear. 
    • Many CSS attributes can be used to animate, using any combination there-of
      • Positions can be used (margin-left, left, top, bottom, etc.) - *Interestingly right and margin-right are not supported
      • Sizing can be used (height, width, etc.)
  • 1024, tells JQuery how long the animation should take to finish out, in milliseconds (1024 ms = 1 second)
  • function(){doMore())}tells JQuery to call a new function at the completion of the animation (this is totally optional and can be omitted, if not needed)
That's it! Give it a try!

Thursday, May 8, 2014

Fluid Navigation using JQuery Animate Function

I promised I would do some writing on JQuery and give some examples of how to easily leverage that technology. JQuery can be an incredibly powerful enhancement to the UX of a page and (in some cases) the aesthetics. For the moment, I'm going to avoid the many plug-ins and add-on libraries, because they are as numerous as the stars. I highly recommend taking an evening and Googling or Binging (If that's a word?) "JQuery plugins", just to get a look at what's out there. It's truly amazing!

For one project, I needed to create a navigation process to scroll through different views of interactive elements, without leaving the homepage. All within the core library for JQuery, it has extensive support for animation, using the function example:

$('#[Tag to be animated]').animate({[CSS property]:'[Value]',},[speed in milliseconds, where 1000 = ~1 second]);

Keeping in mind, that I had nine "windows" or collections of differing interactive elements (Images, links, etc.), this is the code that drives things. It answers to handlers from different menu options or elements within the "windows" themselves, giving me the ability to scroll through a large Div, by showing only a fixed portion (Equally spaced nested Div's) at a time.

The below function allowed me to pass in a parameter to tell the function were to navigate next, based on static logic (The content of the "window" elements are in most cases dynamic, but they will always appear on the same static "window" position). These elements are refreshed with each "if" case, as it can't be known from which "window" the visiting human will be on when selecting a new option. When a match is found in the "if" cases, it performs the animation at the bottom, were all other windows are animated to full transparency, while the selected "window" is animated to full opacity. Hence, not only are the "windows" moving in and out of view to guide navigation, but they are also fading in and out. Visit www.tmcacademy.com and try a few options to see it in action!

function MoveOver(option)
{
var scrollThis;
var boxHome = 'home';
var boxPrograms = 'programs';
var boxEnrollment = 'enrollment';
var boxAboutUs = 'aboutus';
var boxFaqs = 'faqs';
var boxStaff = 'staff';
var boxCalendar = 'calendar';
var boxDirections = 'directions';
var boxContactUs = 'contactus';
var boxCommunityLinks = 'communitylinks';
var show;
var wipe1;
var wipe2;
var wipe3;
var wipe4;
var wipe5;
var wipe6;
var wipe7;
var wipe8;
var wipe9;

if(option=='home')
{
scrollThis = 0;
wipe1=boxPrograms;
wipe2=boxEnrollment;
wipe3=boxAboutUs;
wipe4=boxFaqs;
wipe5=boxStaff;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxHome;
}
if(option=='programs')
{
scrollThis = 1000;
wipe1=boxHome;
wipe2=boxEnrollment;
wipe3=boxAboutUs;
wipe4=boxFaqs;
wipe5=boxStaff;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxPrograms;

}
if(option=='enrollment')
{
scrollThis = 2000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxAboutUs;
wipe4=boxFaqs;
wipe5=boxStaff;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxEnrollment;
}
if(option=='about')
{
scrollThis = 3000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxFaqs;
wipe5=boxStaff;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxAboutUs;
}
if(option=='faqs')
{
scrollThis = 4000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxStaff;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxFaqs;
}
if(option=='staff')
{
scrollThis = 5000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxFaqs;
wipe6=boxCalendar;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxStaff;
}
if(option=='calendar')
{
scrollThis = 6000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxFaqs;
wipe6=boxStaff;
wipe7=boxDirections;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxCalendar;
}
if(option=='directions')
{
scrollThis = 7000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxFaqs;
wipe6=boxStaff;
wipe7=boxCalendar;
wipe8=boxContactUs;
wipe9=boxCommunityLinks;
show=boxDirections;
}
if(option=='contact')
{
scrollThis = 8000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxFaqs;
wipe6=boxStaff;
wipe7=boxCalendar;
wipe8=boxDirections;
wipe9=boxCommunityLinks;
show=boxContactUs;
}
if(option=='community')
{
scrollThis = 9000;
wipe1=boxHome;
wipe2=boxPrograms;
wipe3=boxEnrollment;
wipe4=boxAboutUs;
wipe5=boxFaqs;
wipe6=boxStaff;
wipe7=boxCalendar;
wipe8=boxDirections;
wipe9=boxContactUs;
show=boxCommunityLinks;
}

 $("#insideFooter").animate({
    marginLeft: '-'+scrollThis+'px',
     },500);
    $('#'+show+'').animate({
    opacity:'1.0',
    },1000);  
    $('#'+wipe1+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe2+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe3+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe4+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe5+'').animate({
    opacity:'0.0',
    },1000);            
    $('#'+wipe6+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe7+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe8+'').animate({
    opacity:'0.0',
    },1000);
    $('#'+wipe9+'').animate({
    opacity:'0.0',
    },1000);    
}

Just in case, an example of a calling handler would be the following (Being included within an HTML element):

<a href="#" onclick="javascript: MoveOver('home');">HOME</a>



Saturday, April 5, 2014

Mobile Posting to SharePoint 2010 Lists

In working with one of my latest projects (www.tmcacademy.com), I needed to create a process by which announcements could be easily updated in the event of a school delay or closing. One could argue that posting is a relatively simple task by flipping on the computer, logging in via the web, and creating an announcement that is pre-programmed to post on the homepage by a variety of methods, but this is the age of mobile computing. There should be an easy method for posting from a tablet or smartphone that doesn't require third party software (There are many mobile apps that allow for this, but setting it up for clients is not a easy process and simply not a supportable scenario). There is, of course, the text-only "mobile" translation, built in to the SharePoint 2010 web delivery mechanism, but this is of virtually NO value. It is WAY too confusing to navigate and FAR too different from the "real" web experience to fulfill anything useful (Again, like updating the site in the event of a delay or closing). This is an unfortunate shortcoming of SharePoint thus far, considering what mobile devices are actually capable of (The same technology delivers full-featured game consoles that support HD textured 3D engines). I digress.

An easy approach for the project is to leverage a very useful feature built into SharePoint; email-enabled lists. In the case of having a SharePoint server in-house, the farm(s) would first need to be setup to accept inbound email (Web or cloud hosted arrangements often set this part up for you). An excellent tutorial for this process can be found here. Once this part is up and running, enabling lists and or document libraries is simple.

View the list or document library in a browser and make sure to be signed in with an administrator account.

  • Under List Tools, click List, then List Settings



  • Under Communications, click Incoming e-mail settings


  • Flip "Allow this list to receive e-mail?" to Yes, then enter the beginning of the email address. This can be just about anything, baring odd characters, such as !@#$%^&*()/ \
  • The domain of the email address is determined by the server \ farm setup, and cannot be changed from here
  • The other options can be configured as needed and appropriate to the scenario




  • Click OK to finish


From here, we have effectively built a way to simply email in updates to the site from any devices that supports email, regardless of technology. This eliminates the need for an additional interface and is immediately ready to accept information from clients. The rest is up to filtering, formatting, and web part controls, which is a matter of preference and fit to the business need.

Enjoy!

Wednesday, April 2, 2014

Projects with Details to Come

So I've kept quite busy working on new projects. I was contracted to re-imagine the web presence for The Mission Church Academy and Preschool (http://www.tmcacademy.com), and I'm excited to have a brand new web environment in full production and receiving new visitors. Please stop over and take a frolic through the new site! I'm planning a few posts on how to accomplish some of the nifty elements within the upcoming weeks, such as leveraging SharePoint email-enabled document libraries and jQuery animation. See you again soon!

Thursday, March 13, 2014

SharePoint 2010 - The data source control failed to execute the insert command

I wanted to take a moment to highlight an extremely helpful post, answered by Siraj regarding the intimidating error "The data source failed to execute the insert command" error in SharePoint 2010. The issue surfaces when customizing the ...\newform.aspx of any list and attempting to submit the completed form. Per his writing, this is the diabolical aftershock of implementing Service Pack 2 on the perspective SharePoint 2010 farm. This was absolutely the crux of the trouble in my case, although I had to take one or two more steps after updating the SharePoint:SPDataSource as he notes (I won't spoil it for you by copying his answer - you can visit his notes for the specific change!).

To fully conquer this trouble, I enacted the following:

  1. Updated the SharePoint:SPDataSource as noted in Siraj's answer
  2. Included ALL required fields in the custom newform.aspx
This second item may not cause as much consternation, but for some forms, I didn't want to populate the "title" field with user input, but rather later with system calculated or concatenated data. For initial releases of SharePoint 2010 up through Service Pack 1, this worked fine to omit "title" from my custom forms. Going forward, this is sadly no longer the case. If you find yourself in similar state of woe, the following will work!

  1. Set a default text value for the affected field in the affected List Settings (This MUST be done via the web GUI, as no one seemingly thought it important enough to include in the Designer column edit tools)
  2. Add the field to the custom newform.aspx
  3. Embed the field within a <div> tag using the following CSS styling to hide it (The exact ID is not important and could be virtually anything, but if left to the system generated Id, it will be something like "ff[Number]{$Pos}"):
    • <div style="display:none">
    • <SharePoint:FormField runat="server" id="ff6{$Pos}" controlmode="New" fieldname="Title" __designer:bind="{ddwrt:DataBind('i',concat('ff6',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@Title')}" />
    • </div>
  4. I tested adding the field as an "ASP:TextBox" to enact code-enforced default text rather than setting the default in the List Settings web GUI, but didn't seem to satisfy the mean warnings
That should do it!

Wednesday, December 4, 2013

SharePoint 2010 Mobile Site - A Clever Work-Around

If you're faced with a challenge of attempting to accommodate mobile browsers on your SharePoint site, you've probably encountered a frustrating limitation of SharePoint - the "scaled, mobile edition", which is stripped to text-only browsing within SharePoint sites, lists, etc. I've read of ways to conquer this via mods to the web.config, but this solution unfortunately wasn't a good fit in my case, as I was limited to designer access only to the SharePoint collection (No back-end access what-so-ever). If this headache is / was yours as well, please read on!

SharePoint uses a "homepage" flag to determine which page within a site should be the landing page. This feature can be utilized to your advantage. These are the steps that allowed me to arrive at victory (Noting that the scenario is using a SharePoint 2010 site as a public facing website):


  • Create a document library, allowing Anonymous the right to view all objects (I would advise breaking inheritance and manually setting the privilege, as inheritance doesn't usually work for Anonymous rights)
  • Upload any graphics needed for the mobile version of the site into this library
  • Create an html or aspx page within the library that will be the new mobile homepage (This would be the page you would like mobile visitors to see)
  • Create a "dummy" html page that is blank, but contains some basic Javascript to re-route, based on the detected browser (Code sample further below)
  • Right click the "dummy" html page and select "Set as Home Page"
  • *Note - it's key to setup this "special document library" and nest the landing page inside it, as simply rerouting to your full version homepage triggers an authentication challenge on mobile browsers without tweaking the web.config
This does assume that the domain or DNS entry connecting to SharePoint is pointed without targeting a specific page, but rather a site. This will effectively bypass the "mobile version" of SharePoint and allow you to control the UX with much more granularity. Just be sure to hook the function into the onLoad handler. Enjoy!


function mobileCatch()
{
if ((navigator.userAgent.indexOf('iPhone') != -1) || (navigator.userAgent.indexOf('iPod') != -1) || (navigator.userAgent.indexOf('iPad') != -1) || (navigator.userAgent.indexOf('Mobile') !=-1))
{
location.href='MobileWebSite.aspx';
}
else
{
        location.href='FullWebSite.aspx';
}
}