ENTERPRISE

Microsoft Content Management Server Development : A Placeholder Control for Multiple Attachments (part 3) - Reusing the Insert Attachment Dialog

6/5/2013 7:19:47 PM

3. Deleting Attachments

To delete attachments, we will write a client-side function that clears the contents of the textboxes, table cells, and hidden form field for the selected attachment. Add the RenderDeleteAttachmentJavascript() helper function to the code.

private void RenderDeleteAttachmentJavascript()
{
  StringBuilder script = new StringBuilder();

  // Get the name of the placeholder
  string sPhName = this.BoundPlaceholder.Name;

  script.Append("<SCRIPT>");
  script.Append("function DeleteAttachment(i)");
  script.Append("{" + crlf);
  script.Append("eval('document.all.MAPH_AttIcon_"+sPhName+"_'
              + i).innerHTML='';");
  script.Append("eval('document.all.MAPH_AttIconUrl_" + sPhName+"_'
              + i).value='';");
  script.Append("eval('document.all.MAPH_AttName_" + sPhName + "_'
              + i).value='';");
  script.Append("eval('document.all.MAPH_AttLink_" + sPhName + "_'
              + i).value='';");
  script.Append("}" + crlf);
  script.Append("</SCRIPT>");

  Page.RegisterClientScriptBlock("MAPH_DeleteAttachment", script.ToString());
}

					  

At the end of the LoadPlaceholderContentForAuthoring() method, call the RenderDeleteAttachmentJavascript() method.

protected override void
LoadPlaceholderContentForAuthoring(PlaceholderControlEventArgs e)
{
   . . . code continues . . .
   RenderDeleteAttachmentJavascript();
}

4. Reusing the Insert Attachment Dialog

We need a dialog for authors to specify the file to attach and its display text. While it is possible to write one from scratch, a better idea would be to reuse the Insert Attachment dialog that ships with Web Author.

The Insert Attachment dialog provides the author with the option of either attaching a shared resource or a local attachment. Depending on the whether the developer has allowed local attachments, the author may be restricted to only selecting attachments from resource galleries. In such cases, the Insert Local Attachment link will not be available. After the author has made the selection, he or she is provided with a field for entering the display text of the attachment.

Calling the Dialog

To call the Insert Attachment dialog, we borrow the WBC_launchAttachmentGallery() method found in the AuthFormClientIE.js used by Web Author. The method accepts six arguments that affect the dialog’s behavior.

ArgumentWhat it does
strPostQueryStringA querystring containing information about the posting in unpublished mode such as its GUID or, if it’s a new posting, the channel’s GUID.
strPhNameThe name of the placeholder.
strPhTypeThe value here determines how the Insert Attachment dialog passes information about the attachment back to the calling control. When dealing with attachments, Web Author recognizes the following values:
  • MultiPurpose. Applies to controls that accept HTML with full formatting.

  • SingleAttachment. Used by the SingleAttachmentPlaceholderControl for single file uploads.

  • ThinEditIE. Similar to MultiPurpose. The difference is that insertions to the placeholder use the placeholder document object model (DOM) instead. We will use this option in this example.

bAllowUploadA Boolean to indicate if local attachments are allowed. A value of false means that only resource gallery items can be attached.
bAttachIconA Boolean flag to indicate if the attachment should be rendered as an icon. When it is set to true, the attachment is added to the content as an icon. Otherwise, it will be displayed as a text link.
bAllowVideoThe last Boolean indicates if video attachments are supported. This is a throwback to the previous version of MCMS where videos were supported. In MCMS 2002, this value should always be set to false.

Putting it all together, here’s the script that launches the Insert Attachment dialog. Of course, the GUIDs and the placeholder name are variables that will have to be dynamically generated. The following code snippet would allow local attachments and use icons to represent attachments:

WBC_launchAttachmentGallery('wbc_purpose=Basic&NRMODE=Unpublished&WBCMODE=Pres
entationUnpublished&FRAMELESS=true&NRCHANNELGUID={C40686DA-83CE-452F-AF24-
3D990FA2BAC1}&NRNODEGUID={7AF93078-5FF8-4963-A9F9-B1A0977258A7}',
'NewHtmlPlaceholderDefinition1', 'ThinEditIE', true, true, false);

					  

The GetAttachmentDialog() method generates the required client-side script. The script gathers information about:

  • The channel’s and posting’s GUIDs.

  • The name of the placeholder the control is bound to.

  • Whether or not local attachments are allowed.

  • Whether the attachments should be displayed as icons or text. For this control, we will always set this parameter to true as we want icons to be displayed in the authoring table.

Once it has collected the necessary data, it puts them together as arguments of the WBC_launchAttachmentGallery() function. Add the GetAttachmentDialog() method now:

private string GetAttachmentDialog(int i)
{
  // Check to see if the NRCHANNELGUID querystring contains a value
  // If it does, then it's most likely a new posting
  string channelGUID = Page.Request.QueryString["NRCHANNELGUID"];
  if (channelGUID != "")
  {
    channelGUID = "&NRCHANNELGUID="+channelGUID;
  }

  // Get the GUID from the NRNODEGUID querystring parameter
  string postingGUID = Page.Request.QueryString["NRNODEGUID"];

  // Get the name of the placeholder to bind
  string placeholderName = this.PlaceholderToBind;

  // Are local attachments allowed?
  string allowLocalAttachments = (!m_resourceGalleryOnly).ToString();

  StringBuilder script = new StringBuilder();

  // Specify the name of the placeholder that we are adding the attachment to
  script.Append("MAPH_DestPH ='" + placeholderName + "_" + i.ToString()
                                                         + "';");

  // Launch the Insert Attachment Dialog
  script.Append("WBC_launchAttachmentGallery('"
              + "wbc_purpose=Basic&"
              + "NRMODE=Unpublished&"
              + "WBCMODE=PresentationUnpublished&"
              + "FRAMELESS=true" + channelGUID + "&"
              + "NRNODEGUID=" + postingGUID + "',"
              + "'" + placeholderName + "',"
              + "'ThinEditIE',"
              + allowLocalAttachments.ToLower() + ","
              + "true,"
              + "false);");

  script.Append("return false");

  return script.ToString();
}

					  

Returning Values from the Dialog

The Insert Attachment dialog allows the author to specify the attachment and its display text. It’s not a modal dialog. Therefore, in order for content to be written back to the placeholder control, the dialog accesses client-side functions within the calling window.

Depending on the chosen placeholder type, Web Author prepares different client-side routines. The “ThinEditIE” placeholder type used in this example calls the WBC_setThinEditIEAttachment() method found within the AuthFormClientIE.js script (located in the <install directory>\ Microsoft Content Management Server\Server\IIS_CMS\WebAuthor\Client\ PlaceholderControlSupport\ directory).

We need to modify the WBC_setThinEditIEAttachment() routine to update the authoring table with the attachment’s icon, display text, and URL. The tricky part is doing so without modifying the original code (or we will cross Microsoft support boundaries, plus not modifying the original file safeguards the code from being overwritten when future service packs are applied). As a workaround, we will create a modified version of the method and add it to the page. When the browser sees two JavaScript methods with the same name, one defined in within the page and a second in a separate *.js file, the browser will choose to run the one embedded within the page.

To begin, let’s take a look at the original WBC_setThinEditIEAttachment() routine shown below. It accepts three input parameters:

  • The name of the placeholder that’s accepting the attachment

  • The URL of the uploaded attachment

  • The display name of the attachment

It uses the URL and display name of the attached file to construct an HTML anchor tag. The anchor tag is added to the placeholder by calling the insertHtml() method of the placeholder’s DOM. Don’t worry about typing in the code for now. We will be writing a server-side function to generate this script on the fly later.

function WBC_setThinEditIEAttachment(strPhName, strURL, strDispText)
{
  var strMyDispText = strDispText;
  if (strMyDispText == "")
  {
    strMyDispText = strURL;
  }

  document.all["NCPHRICH_" + strPhName].insertHtml("<a href=\"" + strURL
                                           + "\">" + strMyDispText + "</a>");
}

					  

While the WBC_setThinEditIEAttachment() method works perfectly for regular HtmlPlaceholderControls, in order for it to function correctly within the MutipleAttachmentPlaceholderControl, we need to make several modifications:

  • The method calls an object with an ID of NCPHRICH_(PlaceholderName): our custom control has a different naming convention and executing this line of code will result in an error.

  • Instead of inserting an entire anchor tag in an HtmlPlaceholderControl, we need to pass information about the attachment back to the appropriate hidden fields and cells within the table in the multiple attachment placeholder control.

Client-Side Script for All Types of Placeholder Controls

Let’s tackle the first problem. By default, the WBC_setThinEditIEAttachment() method works only with the out-of-the-box placeholder controls. Placeholder controls that ship with MCMS have IDs prepended with the text NCPHRICH to differentiate them from custom controls that we build. Our control does not have the ID of NCPHRICH_(PlaceholderName). As a result, the following line of code will lead to ’document.all[...]’ is null or not an object errors when the dialog is used with custom controls.

document.all["NCPHRICH_" + strPhName].insertHtml("<a href=\"" + strURL
                                         + "\">" + strMyDispText + "</a>");

On the other hand, we can’t remove the line of code entirely as there may be some out-of-thebox placeholder controls on the same page that require it. To get around this, we will wrap the line in a check to see if the object is undefined (which will be the case for the multiple attachment placeholder control). Again, don’t worry about adding the code to the class file for now, we will show you how the JavaScript gets injected later.

function WBC_setThinEditIEAttachment(strPhName, strURL, strDispText)
{
  var strMyDispText = strDispText;
  if (strMyDispText == "")
  {
    strMyDispText = strURL;
  }

  if(typeof document.all["NCPHRICH_" + strPhName] != 'undefined')
  {
       document.all["NCPHRICH_" + strPhName].insertHtml("<a href=\"" + strURL
                                                         + "\">" + strMyDispText + "</a>");
  }
 }

					  

Passing Attachment Information to the Placeholder Control

Now, on to the second problem of passing information about the attachment back to the multiple attachment placeholder control. We will populate the hidden fields and textboxes with information about the attachment’s icon, display text and URL.

To get this information, let’s look at two input parameters passed into the WBC_setThinEditIEAttachment() method:

Input ParameterWhat it means
StrUrlAs the name suggests, this parameter contains the URL of the attachment.
strMyDispTextStores the icon. The returned HTML is an image tag, which looks like this:
<img alt="Plants are Green!"
src="/NR/rdonlyres/670B7551-5A53-4B0A-
99782B7AD3EE7BC8/0/MyAttachment.doc?
thumbnail=true&label=Plants%20are%20Green%21"
border="0">


So strUrl contains the URL of the attachment and strMyDispText holds the icon as shown in the script below:

function WBC_setThinEditIEAttachment(strPhName, strURL, strDispText)
{
  var strMyDispText = strDispText;
  if (strMyDispText == "")
  {
    strMyDispText = strURL;
  }
  if(typeof document.all["NCPHRICH_" + strPhName] != 'undefined')
  {
    document.all["NCPHRICH_" + strPhName].insertHtml("<a href=\"" + strURL
                                           +  "\">" + strMyDispText + "</a>");
  }
  else
								{
								// Return the image of the icon
								if (typeof document.all["MAPH_AttIcon_" + MAPH_DestPH] !='undefined')
								{
								document.all[\"MAPH_AttIcon_\" + MAPH_DestPH].innerHTML = strMyDispText;
								}
								// Return the attachment's URL
								if (typeof document.all[\"MAPH_AttLink_\" + MAPH_DestPH] != 'undefined')
								{
								document.all[\"MAPH_AttLink_\" + MAPH_DestPH].value = strURL;
								}
								// Return the icon
								if (typeof document.all[\"MAPH_AttIconUrl_\" + MAPH_DestPH]
                                                           != 'undefined')
  {
								document.all[\"MAPH_AttIconUrl_\" + MAPH_DestPH].value = strMyDispText;
								}
 }
}

					  

What about the display text? We need to extract the display text from the alt attribute of the icon’s image tag. To do so, we will split strMyDispText using double-quotes (”) as the separator. Let’s say the original HTML is:

<img alt="DisplayText" src="AttachmentUrl" border="0">

The array formed after splitting is shown below where the second element of the resulting array contains the display text from the alt attribute:

Array Item 0:  <img alt=
Array Item 1:   DisplayText
Array Item 2:  src=
Array Item 3:  AttachmentUrl
Array Item 4:  border=
Array Item 5:  0
Array Item 6:  >

The extracted values are deposited into the hidden form fields and textboxes generated earlier.

function WBC_setThinEditIEAttachment(strPhName, strURL, strDispText)
{
  . . . code continues . . .
  if(typeof document.all["NCPHRICH_" + strPhName] != 'undefined')
  {
    . . . code continues . . .
  }
  else
  {
    . . . code continues . . .

    // Split strMyDispText using the double-quote character as the separator
    elements = strMyDispText.split('\"');

    // Return the Display Text
    if (typeof document.all[\"MAPH_AttName_\" + MAPH_DestPH] != 'undefined')
    {
      // The display name is the second element of the array
      document.all[\"MAPH_AttName_\" + MAPH_DestPH].value = elements[1];
    }
  }
}

					  

Generating the WBC_setThinEditIEAttachment() Method

As our custom placeholder control is constructed entirely from server-side code, we need to generate the client script above on the fly and register it with Page.RegisterStartUpScript(). To do so, we must add the helper function RenderResourceGalleryRelatedJavascript() shown below to the code:

private void RenderResourceGalleryRelatedJavascript()
{
 StringBuilder script = new StringBuilder();

 // Start the script block
 script.Append("<SCRIPT language=\"javascript\">" + crlf);

 // Declare the MAPH_DestPH variable
 script.Append("var MAPH_DestPH = \"\";" + crlf);

 // Define WBC_setThinEditIEImage function to replace one defined by MCMS
 script.Append("function WBC_setThinEditIEAttachment(strPhName, strURL,"
             + "strDispText){" + crlf);

 script.Append("var strMyDispText = strDispText;" + crlf
             + "if (strMyDispText == \"\") "
             + "{"
             + "strMyDispText = strURL;"
             + "}" + crlf);

 script.Append("if(typeof document.all[\"NCPHRICH_\" + strPhName] !=
'undefined')"
             + "{"
             + "document.all[\"NCPHRICH_\" + strPhName].insertHtml"
             + "(\"<a href=\\\" + strURL + \\\">\" + strMyDispText
             + \"</a>\");"
             + "}" + crlf);

 script.Append("else"
             + "{"
             + "elements = strMyDispText.split('\"'); " + crlf);

 script.Append("if(typeof document.all[\"MAPH_AttIcon_\"
             + MAPH_DestPH]!='undefined')"
             + "{"
             + "document.all[\"MAPH_AttIcon_\"
             + MAPH_DestPH].innerHTML=strMyDispText;"
             + "}" + crlf);

 script.Append("if(typeof document.all[\"MAPH_AttLink_\"
             + MAPH_DestPH]!='undefined')"
             + "{"
             + "document.all[\"MAPH_AttLink_\" + MAPH_DestPH].value = strURL; "
             + "}" + crlf);

 script.Append("if(typeof "
             + "document.all[\"MAPH_AttIconUrl_\"+MAPH_DestPH]!='undefined')"
             + "{"
             + "document.all[\"MAPH_AttIconUrl_\"
             + MAPH_DestPH].value =strMyDispText;"
             + "}" + crlf);

 script.Append("if (typeof "
             + "document.all[\"MAPH_AttName_\"+MAPH_DestPH]!='undefined')"
             + "{"
             + "document.all[\"MAPH_AttName_\"
             + MAPH_DestPH].value = elements[1];"
             + "}" + crlf);

     // Close the if-else block
     script.Append("}" + crlf);

     // Close the function
     script.Append("}" + crlf);

     // Close the script block
     script.Append("</SCRIPT>");

     // Register the script
     this.Page.RegisterStartupScript("WBC_setThinEditIEAttachment",
                                                            script.ToString());
   }

					  

Finally, at the end of the LoadPlaceholderContentForAuthoring() method, we add a call to the RenderResourceGalleryRelatedJavascript() method:

   protected override void LoadPlaceholderContentForAuthoring(
                                                 PlaceholderControlEventArgs e)
    {
     . . . code continues . . .

      RenderResourceGalleryRelatedJavascript();
   }

					  
Other  
 
Video tutorials
- How To Install Windows 8 On VMware Workstation 9

- How To Install Windows 8

- How To Install Windows Server 2012

- How To Disable Windows 8 Metro UI

- How To Change Account Picture In Windows 8

- How To Unlock Administrator Account in Windows 8

- How To Restart, Log Off And Shutdown Windows 8

- How To Login To Skype Using A Microsoft Account

- How To Enable Aero Glass Effect In Windows 8

- How To Disable Windows Update in Windows 8

- How To Disable Windows 8 Metro UI

- How To Add Widgets To Windows 8 Lock Screen
programming4us programming4us
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone