Dynamically load AngularJS controller within a modal

First of all, the idea was to have modal dialog using Bootstrap modal (More info.) and hookup controllers dynamically as the new controllers will be registered dynamically when needed.

Now, let’s move into action:

1- Normal AngularJS app definition, just notice the reference of the $controllerProvider (More info.)

image 

2- Main controller definition

image

3- In our index.html we add the AngularJS controller binding and a simple Bootstrap modal link with the associated target template.

image

4- Modal target page definition, notice the child controller hookup and the Ajax loading for the child controller definition at the end.

image 

5- Child controller definition, notice it’s done via the cp.register (Controller Provider)

image

6- Last and the magic trick Smile , after all loaded force compiling the modal main element within the prospective scope.

image

7- Finally, result will be like the following:

image

Sample code can be obtained from (here)

P.S. The sample in html only, just open directly from the folder.

I hope that helped

Ahmed

Using SharePoint 2013 Word Automation Services to convert Word file to PDF

In below example, we will demonstrate the solution of converting Word file to PDF file by using the SharePoint 2013 Word Automation Services.

First of all, make sure that the service is configured and running, you can refer to Configuring Word Automation Services for Development.

Initially, add a reference to “Microsoft.Office.Word.Server.dll” which normally resides in:

C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.Office.Word.Server.dll

Second, below is the code for taking the SPFile object and pass it to the conversion method, and then wait for the conversion to finish to proceed:

  1. public bool ConvertWordFileToPdf(SPFile file, SPUser user) {  
  2.     if (file == nullreturn false;  
  3.     var fileExtention = System.IO.Path.GetExtension(file.Url);  
  4.     var filePath = string.Format(“{0}/{1}”, file.Web.Site.Url, file.Url);  
  5.     var pdfPath = System.IO.Path.ChangeExtension(filePath, “pdf”);  
  6.     if (fileExtention == “.docx” || fileExtention == “.doc”) {  
  7.         var conversionItemInfo = ConvertWordFileToPDF(filePath, pdfPath, user);  
  8.         if (conversionItemInfo == null) {  
  9.             throw new AccessViolationException(“Word automation services is not accessible”);  
  10.         } else {  
  11.             while (conversionItemInfo.InProgress) {}  
  12.             if (conversionItemInfo.Failed) {  
  13.                 return false;  
  14.             }  
  15.             if (conversionItemInfo.Succeeded) { // Proceed with your own code here  
  16.             }  
  17.         }  
  18.     }  
  19. }  

     

    Finally, here is the conversion method which creates the conversion job settings which takes care if the conversion for us:

  20. public ConversionItemInfo ConvertWordFileToPDF(string sourceFilePath, string destinationFilePath, SPUser user) {  
  21.     try {  
  22.         var serviceContext = SPServiceContext.GetContext(SPContext.Current.Web);  
  23.         var wordProxy = (WordServiceApplicationProxy) serviceContext.GetDefaultProxy(typeof(WordServiceApplicationProxy));  
  24.         var jobSettings = new ConversionJobSettings();  
  25.         jobSettings.OutputFormat = SaveFormat.PDF;  
  26.         var converter = new SyncConverter(wordProxy, jobSettings);  
  27.         converter.UserToken = user.UserToken;  
  28.         return converter.Convert(sourceFilePath, destinationFilePath);  
  29.     } catch (Exception ex) { // Log the exception    
  30.         return null;  
  31.     }  
  32. }  

     

    Notes:

  • Make sure that the used SPUser has access to the Word Conversion Service.
  • This method output the exact output of Microsoft Word save as PDF.
  • In the case of PDF conversion, you can use some libraries to optimize the file size (if needed), personally I have tried some but didn’t notice a remarkable difference in the case of text based Word files.
  • Here are the available save formats as well:
  1. namespace Microsoft.Office.Word.Server.Conversions { 
  2. // Summary: //     Represents the supported save formats for output files.  
  3.     public enum SaveFormat { 
  4. // Summary: //     Use the file extension of the output file to determine output format.  
  5.         Automatic = 0, // // Summary: //     Save output file as a Word Document (.docx).  
  6.             Document = 1, // // Summary: //     Save output file as a Word Macro-Enabled Document (.docm).  
  7.             DocumentMacroEnabled = 2, // // Summary: //     Save output file as a Word 97-2003 Document (.doc).  
  8.             Document97 = 3, // // Summary: //     Save output file as a Word Template (.dotx).  
  9.             Template = 4, // // Summary: //     Save output file as a Word Macro-Enabled Template (.dotm).  
  10.             TemplateMacroEnabled = 5, // // Summary: //     Save output file as a Word 97-2003 Template (.dot).  
  11.             Template97 = 6, // // Summary: //     Save output file as a Single File Web Page (.mht).  
  12.             MHTML = 7, // // Summary: //     Save output file as a PDF (.pdf).  
  13.             PDF = 8, // // Summary: //     Save output file as a Rich Text Format document (.rtf).  
  14.             RTF = 9, // // Summary: //     Save output file as a Word XML Document (.xml).  
  15.             XML = 10, // // Summary: //     Save output file as a XPS Document (.xps).  
  16.             XPS = 11, DocumentStrict = 12,  
  17.     }  
  18. }  

Modifying Microsoft Office Word Content Control OpenXml

In my case I had a Microsoft Office Word document which contains content place controls which needs to be filled by specific data after specific business action.

The idea is to select all the descendants from type “SdtElement” which has a tag name specified and then compare it with the provided tag name.

Next, remove all the text from the content control and add our new value.

Sample code:

private void ModifyDocumentPlaceHolder(Document document, string tagName, string value)
        {
            // Find all placeholders with Tag name
            var placeHolders = document.MainDocumentPart.RootElement.
                Descendants<SdtElement>().
                Where(P => P.Elements<SdtProperties>().FirstOrDefault().
                    Elements<Tag>().FirstOrDefault() != null);

            // Select the required element by tag name
            var requiredPlaceHolder = placeHolders.FirstOrDefault(P =>
                P.Elements<SdtProperties>().FirstOrDefault().
                Elements<Tag>().FirstOrDefault().Val == tagName);

            // Remove all text from the place holder
            requiredPlaceHolder.Descendants<Text>().ToList().ForEach(
                delegate(Text textObj)
                {
                    textObj.Text =
 string.Empty;
                });

            // Add the required text
            requiredPlaceHolder.Descendants<Text>().FirstOrDefault().Text = value;

        }

I hope that helped

Ahmed

Kuwait Civil ID Validator

In the following solution, I had implemented a custom Enterprise Library Validator for Kuwait Civil ID.

The validation logic has been acquired from PACI as the following:

1 /// <summary> 2 /// Represent the associated validator attribute for <see cref="CivilIdValidator"/> 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 5 public class CivilIdValidatorAttribute : ValidatorAttribute 6 { 7 /// <summary> 8 /// Creates the <see cref="T:Microsoft.Practices.EnterpriseLibrary.Validation.Validator" /> described by the attribute object providing validator specific 9 /// information. 10 /// </summary> 11 /// <param name="targetType">The type of object that will be validated by the validator.</param> 12 /// <returns> 13 /// The created <see cref="T:Microsoft.Practices.EnterpriseLibrary.Validation.Validator" />. 14 /// </returns> 15 /// <remarks> 16 /// This operation must be overriden by subclasses. 17 /// </remarks> 18 protected override Validator DoCreateValidator(Type targetType) 19 { 20 return new CivilIdValidator(); 21 } 22 }

and the validator class:

1 /// <summary> 2 /// MS EL Custom Validation Attribute for Civil ID validation 3 /// </summary> 4 public class CivilIdValidator : Validator<decimal> 5 { 6 7 8 /// <summary> 9 /// Initializes a new instance of the <see cref="CivilIdValidator"/> class. 10 /// </summary> 11 public CivilIdValidator() : base("","") { } 12 13 /// <summary> 14 /// Does the validate. 15 /// </summary> 16 /// <param name="objectToValidate">The object to validate.</param> 17 /// <param name="currentTarget">The current target.</param> 18 /// <param name="key">The key.</param> 19 /// <param name="validationResults">The validation results.</param> 20 protected override void DoValidate(decimal objectToValidate, object currentTarget, string key, ValidationResults validationResults) 21 { 22 if(!Utilities.IsValidCivilId(objectToValidate.ToString())) 23 { 24 LogValidationResult(validationResults, "???? ????? ??? ???? ???? ?? 12 ???", currentTarget, key); 25 return; 26 } 27 } 28 29 /// <summary> 30 /// Gets the message template to use when logging results no message is supplied. 31 /// </summary> 32 protected override string DefaultMessageTemplate 33 { 34 get 35 { 36 return ""; 37 } 38 } 39 40 41 }

The validation logic:

1 /// <summary> 2 /// Custom utilities used by the applciation 3 /// </summary> 4 public class Utilities 5 { 6 /// <summary> 7 /// Determines whether [is valid civil identifier] [the specified civil identifier]. 8 /// </summary> 9 /// <param name="civilId">The civil identifier.</param> 10 /// <returns></returns> 11 public static bool IsValidCivilId(string civilId) 12 { 13 if (string.IsNullOrEmpty(civilId)) 14 return false; 15 16 if (civilId.Length != 12) 17 return false; 18 19 decimal civilIdDecimal; 20 21 if (!decimal.TryParse(civilId, out civilIdDecimal)) 22 return false; 23 24 int calculation; 25 26 int monthPart = int.Parse(civilId.Substring(3,2)); 27 int dayPart = int.Parse(civilId.Substring(3,2)); 28 29 30 if ((monthPart > 12 || monthPart <1) || (dayPart > 31 || dayPart <1)) 31 { 32 return false; 33 } 34 35 calculation = 2 * int.Parse(civilId.Substring(0,1)) + 1 * int.Parse(civilId.Substring(1, 1)) + 6 * int.Parse(civilId.Substring(2, 1)) + 3 * int.Parse(civilId.Substring(3, 1)) + 7 * int.Parse(civilId.Substring(4, 1)) + 9 * int.Parse(civilId.Substring(5, 1)) + 10 * int.Parse(civilId.Substring(6, 1)) + 5 * int.Parse(civilId.Substring(7, 1)) + 8 * int.Parse(civilId.Substring(8, 1)) + 4 * int.Parse(civilId.Substring(9, 1)) + 2 * int.Parse(civilId.Substring(10, 1)); 36 37 calculation = calculation % 11; 38 39 calculation = 11 - calculation; 40 41 if (calculation != int.Parse(civilId.Substring(11, 1))) 42 return false; 43 else 44 return true; 45 } 46 }

I hope that helped.

Ahmed

Using Enterprise Library to Map Data Into Objects (Simple ORM)

In a recent project – working with developers just started using MS Enterprise Library – I had the need to implement a simple framework for them to deal with relational database as objects in a simple ORM.

The idea was to create a layer utilizing Enterprise Library 6.0 to encapsulate the database objects mapping plus having a way for validation.

The solution can be highlighted as below:

 image

First, we have implemented a base Adapter of T – T is the object type – as the following:

1 /// <summary> 2 /// The base class for the adapter 3 /// </summary> 4 /// <typeparam name="T">The type of the associated object</typeparam> 5 public class AdapterBase<T> 6 { 7 /// <summary> 8 /// Gets the object. 9 /// </summary> 10 /// <param name="objectData">The object data.</param> 11 /// <returns>One instance of the associated object</returns> 12 protected static T GetObject(DataRow objectData) 13 { 14 var objectInstance = (T)Activator.CreateInstance(typeof(T)); 15 16 var databaseDefinedProperties = ExploreDatabaseDefinedProperties(objectInstance); 17 18 return GetObject(objectData, databaseDefinedProperties); 19 } 20 21 /// <summary> 22 /// Gets the collection. 23 /// </summary> 24 /// <param name="collectionData">The collection data.</param> 25 /// <returns>Collection of the associated object</returns> 26 protected static Collection<T> GetCollection(DataTable collectionData) 27 { 28 var objectCollection = (Collection<T>)Activator.CreateInstance(typeof(Collection<T>)); 29 30 var objectInstance = (T)Activator.CreateInstance(typeof(T)); 31 32 var databaseDefinedProperties = ExploreDatabaseDefinedProperties(objectInstance); 33 34 foreach (DataRow row in collectionData.Rows) 35 { 36 objectCollection.Add(GetObject(row, databaseDefinedProperties)); 37 } 38 39 return objectCollection; 40 } 41 42 /// <summary> 43 /// Gets the object. 44 /// </summary> 45 /// <param name="objectData">The object data.</param> 46 /// <param name="databaseDefinedProperties">The database defined properties.</param> 47 /// <returns></returns> 48 private static T GetObject(DataRow objectData, Collection<PropertyInfo> databaseDefinedProperties) 49 { 50 var objectInstance = (T)Activator.CreateInstance(typeof(T)); 51 52 foreach (PropertyInfo propertyInfo in databaseDefinedProperties) 53 { 54 if (Attribute.IsDefined(propertyInfo, typeof(DbField))) 55 { 56 var dbAttribute = propertyInfo.CustomAttributes.Single(p => p.AttributeType == typeof(DbField)); 57 58 if (dbAttribute != null) 59 { 60 var dbFieldName = dbAttribute.NamedArguments.Single(p => p.MemberName == "DbfieldName").TypedValue.Value.ToString(); 61 62 if (objectData.Table.Columns.Contains(dbFieldName)) 63 { 64 var dbFieldValue = objectData[dbFieldName]; 65 66 if (dbFieldValue != DBNull.Value) 67 { 68 propertyInfo.SetValue(objectInstance, objectData[dbFieldName]); 69 } 70 } 71 } 72 73 } 74 } 75 return objectInstance; 76 } 77 78 /// <summary> 79 /// Explores the database defined properties. 80 /// </summary> 81 /// <param name="objectInstance">The object instance.</param> 82 /// <returns></returns> 83 private static Collection<PropertyInfo> ExploreDatabaseDefinedProperties(T objectInstance) 84 { 85 var databaseDefinedProperties = new Collection<PropertyInfo>(); 86 87 var info = objectInstance.GetType().GetTypeInfo(); 88 89 foreach (PropertyInfo propertyInfo in info.DeclaredProperties) 90 { 91 if (Attribute.IsDefined(propertyInfo, typeof(DbField)) && propertyInfo.CanWrite) 92 { 93 databaseDefinedProperties.Add(propertyInfo); 94 } 95 } 96 97 return databaseDefinedProperties; 98 } 99 100 /// <summary> 101 /// Validates the specified object to validate. 102 /// </summary> 103 /// <param name="objectToValidate">The object to validate.</param> 104 /// <returns></returns> 105 public static ValidationResults Validate(T objectToValidate) 106 { 107 return Validation.Validate<T>(objectToValidate); 108 } 109 110 /// <summary> 111 /// Validates the specified object to validate. 112 /// </summary> 113 /// <param name="objectToValidate">The object to validate.</param> 114 /// <param name="ruleSet">The rule set.</param> 115 /// <returns></returns> 116 public static ValidationResults Validate(T objectToValidate, string[] ruleSet) 117 { 118 return Validation.Validate<T>(objectToValidate, ruleSet); 119 } 120 121 public static string ToXml(T objectToConvert) 122 { 123 var objectXml = new XmlDocument(); 124 125 var parentNode = objectXml.CreateElement("ObjectData"); 126 127 var info = objectToConvert.GetType().GetTypeInfo(); 128 129 foreach (PropertyInfo propertyInfo in info.DeclaredProperties) 130 { 131 var xmlNode = objectXml.CreateElement(propertyInfo.Name); 132 var nodeValue = propertyInfo.GetValue(objectToConvert); 133 xmlNode.InnerText = nodeValue == null ? "" : nodeValue.ToString(); 134 parentNode.AppendChild(xmlNode); 135 } 136 137 objectXml.AppendChild(parentNode); 138 139 return objectXml.InnerXml; 140 } 141 142 143 }

The base adapter have the needed functions to convert relational data – Data Tables or Data Rows – into the respective objects, also have the function to do validation which will be described later in this post.

Next, the DBField class which is required to do the actual mapping between the class property and the field name from the relational database:

1 /// <summary> 2 /// Custom attribute to hold the databse field name for a defined object property 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Property)] 5 public class DbField : Attribute 6 { 7 /// <summary> 8 /// Gets or sets the name of the dbfield. 9 /// </summary> 10 /// <value> 11 /// The name of the dbfield. 12 /// </value> 13 public string DbfieldName { get; set; } 14 15 /// <summary> 16 /// Initializes a new instance of the <see cref="DbField"/> class. 17 /// </summary> 18 public DbField() 19 { 20 } 21 }

Last part of the mapping solution is the object itself which can be as the following:

1 /// <summary> 2 /// Represent the bank object 3 /// </summary> 4 public class Bank 5 { 6 /// <summary> 7 /// Gets or sets the identifier. 8 /// </summary> 9 /// <value> 10 /// The identifier. 11 /// </value> 12 [DbField(DbfieldName="BNK_MGR_ID")] 13 public Nullable<int> Id {get; set;} 14 15 /// <summary> 16 /// Gets or sets the name. 17 /// </summary> 18 /// <value> 19 /// The name. 20 /// </value> 21 [StringLengthValidator(1, 255, MessageTemplate = "???? ????? ??? ?????")] 22 [DbField(DbfieldName="BNK_NMA")] 23 public string Name { get; set; } 24 25 /// <summary> 26 /// Gets or sets the telephone. 27 /// </summary> 28 /// <value> 29 /// The telephone. 30 /// </value> 31 [DbField(DbfieldName="BNK_TEL")] 32 public string Telephone { get; set; } 33 34 /// <summary> 35 /// Gets or sets the fax. 36 /// </summary> 37 /// <value> 38 /// The fax. 39 /// </value> 40 [DbField(DbfieldName="BNK_FAX")] 41 public string Fax { get; set; } 42 43 /// <summary> 44 /// Gets or sets the email. 45 /// </summary> 46 /// <value> 47 /// The email. 48 /// </value> 49 [DbField(DbfieldName="BNK_EMAIL")] 50 public string Email { get; set; } 51 52 /// <summary> 53 /// Gets or sets the address. 54 /// </summary> 55 /// <value> 56 /// The address. 57 /// </value> 58 public string Address { get; set; } 59 /// <summary> 60 /// Gets or sets the note. 61 /// </summary> 62 /// <value> 63 /// The note. 64 /// </value> 65 [DbField(DbfieldName="BNK_NOTE")] 66 public string Note { get; set; } 67 68 /// <summary> 69 /// Initializes a new instance of the <see cref="Bank"/> class. 70 /// </summary> 71 public Bank() { } 72 }

As you can notice, DbField attribute is used to tell the adapter of the actual field name which comes from the data source.

Finally, the adapter itself to be created as the following:

1 /// <summary> 2 /// Bank adapter 3 /// </summary> 4 public class BankAdapter : AdapterBase<Bank> 5 { 6 /// <summary> 7 /// Gets the by identifier. 8 /// </summary> 9 /// <param name="id">The identifier.</param> 10 /// <returns></returns> 11 public static Bank GetById(int id) 12 { 13 return GetObject(BankRef.GeById(id).Tables[0].Rows[0]); 14 } 15 16 /// <summary> 17 /// Gets all. 18 /// </summary> 19 /// <returns></returns> 20 public static Collection<Bank> GetAll() 21 { 22 return GetCollection(BankRef.GetAll().Tables[0]); 23 } 24 25 /// <summary> 26 /// Adds the specified new bank. 27 /// </summary> 28 /// <param name="newBank">The new bank.</param> 29 /// <returns></returns> 30 public static string Add(Bank newBank) 31 { 32 return BankRef.Insert(newBank.Name, newBank.Telephone, newBank.Fax, newBank.Email, newBank.Address, newBank.Note); 33 } 34 35 /// <summary> 36 /// Updates the specified edited bank. 37 /// </summary> 38 /// <param name="editedBank">The edited bank.</param> 39 /// <returns></returns> 40 public static bool Update(Bank editedBank) 41 { 42 if (BankRef.Update(editedBank.Id.Value, editedBank.Name, editedBank.Telephone, editedBank.Fax, editedBank.Email, editedBank.Address, editedBank.Note) > 0) 43 return true; 44 else 45 return false; 46 } 47 48 /// <summary> 49 /// Gets all lite. 50 /// </summary> 51 /// <returns></returns> 52 public static Collection<Bank> GetAllLite() 53 { 54 return GetCollection(BankRef.GetAllLite().Tables[0]); 55 } 56 57 public static Collection<Bank> GetAllLiteForElevation() 58 { 59 return GetCollection(BankRef.GetAllLiteForElevation().Tables[0]); 60 } 61 62 }

You can notice the usage of the GetCollection and GetObject methods which is inherited from the base adapter class.

The solution can be used to teach starters the basics of ORM and the usage of Enterprise Library.

I hope that helped

Ahmed