Sys.Extended is undefined

Lately I've been playing around with the ToolKitScriptManager. I've read of some cool tricks to combine all those pesky scripts into one Javascript download. Not only would have make things much cleaner, it would reduce the overhead of files required to download. Now some of the projects that I work on rely heavily on Javascript to display the UI correctly. We love our clients so we wanted to do everything technically possible to speed up their monster application and the ToolKitScriptManager seemed like a logical place to start.

So I dropped a ToolKitScriptManager onto the page with a couple references to some commonly used files. And the result was my entire application breaking horribly in various places. Firebug reported a dreaded Sys.Extended is Undefined. Well that would be reason enough to revert all changes, but I wanted so bad for this feature to work I couldn't help but spend time researching to figure out the issue.

Basically it came down to the order of my composite scripts that fixed the issue. Instead of this

<compositescript>
<scripts>
<asp:scriptreference name="WebForms.js" assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
</asp:scriptreference>
<asp:scriptreference name="MicrosoftAjaxWebForms.js" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
</asp:scriptreference>
<asp:scriptreference name="MicrosoftAjax.js" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
</asp:scriptreference>
</scripts>
</compositescript>



I had to reorder my scripts to this

<compositescript>
<scripts>
<asp:scriptreference name="WebForms.js" assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" scriptmode="Release"></asp:scriptreference>
<asp:scriptreference name="WebUIValidation.js" assembly="System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" scriptmode="Release"></asp:scriptreference>
<asp:scriptreference name="MicrosoftAjax.js" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" scriptmode="Release"></asp:scriptreference>
<asp:scriptreference name="MicrosoftAjaxWebForms.js" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" scriptmode="Release"></asp:scriptreference>
</scripts>
</compositescript>

Hope this helps anyone else with this issue.

OPF3 - How to make relations between objects & tables

Treating tables as objects in my applications is a time saver. I don't have to worry about updating SQL statements, or even sanitizing my data against SQL injections. OPF3 takes care of all this very nicely for you.

Now typically, loading up an object from the database is the most you'll need to do, but like 100% of all the good databases out there, you'll have a relationship between two tables. Depending on the database you can have either a one-to-many or a many-to-many relationship. OPF3 has support to create these same relationships in your code. Best of all the relationships utilize lazy-loading, so they'll only be pulled from the database when they're called.

For our purposes we're going to have three tables (Orders, OrderItems and Customers) in our database. These three tables represent a majority of table relationships out there.

relations

 

Our primary focus will be on the Orders table. This application design allows an Order to have only one customer at a time, but with many OrderItems. We'll start with the simple customer relationship.

OPF3 uses the ObjectHolder class to manage relationships. Within our Order class we'll define a private variable for our relationship.

private ObjectHolder<Customer> _CustomerRelation = new ObjectHolder<Customer>();

We now have an object to hold our relation but we need to define exactly what our relationship is. OPF3 does not, and can not guess your column names. Here's where we use the Relation attribute.

[Relation( "CustomerId=Id", PersistRelationship = PersistRelationships.ChildFirst )]
private ObjectHolder<Customer> _CustomerRelation = new ObjectHolder<Customer>();

Now basically the relation attribute defines our relationship between the Order class and Customer class. This is specified by the "CustomerId=Id". Next, since an Order cannot exist without the Customer, the PersistRelationships.ChildFirst enum tells OPF3 that the Customer relationship should be saved / updated into the database before the Order. Last but not least, we create a property to access our relationship. This just removes one step when accessing the object. The final result looks like this.

[Relation( "CustomerId=Id", PersistRelationship = PersistRelationships.ChildFirst )]
private ObjectHolder<Customer> _CustomerRelation = new ObjectHolder<Customer>();
public Customer CustomerRelation
{
    get { return _CustomerRelation .InnerObject; }
    set { _CustomerRelation .InnerObject = value; }
}

Now the relationship for the OrderItems is a one-to-many relationship. Instead of accessing a single object like the customer, we'll be accessing a enumeration of OrderItems. Instead of using the ObjectHolder class, we'll utilize the ObjectSetHolder class, and our property will return an ObjectSet (collection of Persistent objects). Here's what the result will look like.

[Relation("Id=OrderId", PersistRelationship = PersistRelationships.ParentFirst)]
private ObjectSetHolder<OrderItem> _OrderItemsRelation = new ObjectSetHolder<OrderItem>();
public ObjectSet<OrderItem> OrderItemsRelation 
{
    get { return _OrderItemsRelation.InnerObject; }
    set { _OrderItemsRelation.InnerObject = value; }
}

Three things to note here. First, the PersistRelationships is set to ParentFirst. This is because the parent (Order) must exist within the database before the OrderItems can. Second, the ObjectHolder is replaced with ObjectSetHolder, and third the property returns an ObjectSet instead of a single object. Now in your code your can access and manipulate relationships as easy as this

Order loadOrder = _context.GetObject<Order>( "Id={0}", 15 );

string message = "Dear " + loadOrder.CustomerRelation.FirstName + " " + loadOrder.CustomerRelation.LastName + ". Here is a summary of your order." + System.Environment.NewLine;

foreach(OrderItem item in loadOrder.OrderItemsRelation)
{
     message += item.ProductRelation.Name + " x " + item.Quantity + " @ " + item.ProductRelation.Price.ToString( "C" ) + " = " + ( item.Quantity * item.ProductRelation.Price ).ToString( "C" ) + System.Environment.NewLine;
}

//TODO send an the message via email

Inserting and Updating

Now while these relationships are awesome for loading, they're fairly straight forward for persisting to the database. Lets pretend that your shopping cart was going to create the order, customer and order items all at once. Here's what it would look like in your code.

Order newOrder = new Order();
newOrder.EmployeeId = CurrentUser.Id;
newOrder.OrderNumber = GenerateOrderNumber();
newOrder.OrderDate = DateTime.Now;
newOrder.OrderStatus = ( int ) eOrderStatus.New;
newOrder.Status = 1;

newOrder.CustomerRelation = new Customer();
newOrder.CustomerRelation.FirstName = txtFirstName.Text;
newOrder.CustomerRelation.LastName = txtLastName.Text;

newOrder.CustomerRelation.Address1 = txtAddress1.Text;
newOrder.CustomerRelation.PostalCode = txtPostalCode.Text;
newOrder.CustomerRelation.City = txtCity.Text;

newOrder.OrderItemsRelation = new ObjectSet<OrderItem>();
newOrder.OrderItemsRelation.Add( new OrderItem { ProductId = 1, Quantity = 3 } );
newOrder.OrderItemsRelation.Add( new OrderItem { ProductId = 4, Quantity = 1 } );
newOrder.OrderItemsRelation.Add( new OrderItem { ProductId = 5, Quantity = 6 } );

try
{
    using(Chili.Opf3.Storages.Transaction t = _context.StartTransaction())
    {
        _context.PersistChanges( newOrder );
        t.Commit();
    }
    //Success with the order, redirect
}
catch ( Exception ex )
{
    MessageDisplay( ex );
}

Wrap it all up in a transaction and you're all set. OPF3 will find the relationships you created and insert the objects in this order: CustomerRelationship, Order, and finally OrderItemsRelationship.

Umbraco & XSLT

I've recently been falling in love with XSLT and what it can accomplish for me. The heart and soul of Umbraco is built upon XSLT, so when I was first introduced I had a hard time adjusting to how everything would work. Last night that all changed. If you're in anyway confused as to how XSLT works, you should read the articles on WC3 Schools. Their XPATH chapter greatly helped me get a grasp on all the select statements going on.

Next you need to burn this XSLT element into your brain.

<xsl:copy-of select="" />

One of the major issues I've had with XSLT is not being able to see the XML/data that I'm playing with. This handy little element outputs whatever you put into the select attribute as XML that you can work with.

So if you want to learn XSLT and XPATH quicker, and you want to know where all the built-in Umbraco values come from, simply put this in your XSLT template.

<xsl:copy-of select="$currentpage" />

Now view source on the page calling the marco and you'll have some XML that you can touch and feel!

Combined with some reading at W3Schools for XPATH and you'll be well on your way to coding XSLT in no time!

 

 

Syntax Highlighter for Umbraco 4

Syntax Highlighter for Umbraco 4

It's been a challenge for the past couple weeks to integrate a syntax highligher into Umbraco. I've done countless Google searches, read blogs, form posts and how-to articles, but I still haven't come across an update-to-date syntax highlighter tutorial for Umbraco 4. Well I came across an article here that came very close, but was slightly outdated. Kristian has done a great job though of outlining what needs to be done though. My goal is to target a more update-to-date version of SyntaxHighlighter.

You can follow Kristian's howto, but once you get to the part to install the SyntaxHighlighter you'll need to follow these steps.

Download SyntaxHighlighter here. At the time of this article the version is 2.1.364

Place the script and style folder in a new directory called "SyntaxHighlighter" in your umbraco root folder.

Place the following code right before the </body> tag in your master:

 

<!-- SyntaxHighlighter CSS and JavaScript -->
    <link type="text/css" rel="stylesheet" href="/syntaxhighlighter/styles/shCore.css">
    </link>
    <link type="text/css" rel="stylesheet" href="/syntaxhighlighter/styles/shThemeDefault.css">
    </link>

    <script type="text/javascript" src="/syntaxhighlighter/scripts/shCore.js"></script>
    
    <!-- Brushs! Include the file for each language you want to use -->
    <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushCSharp.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushJava.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushXml.js"></script>
    <script type="text/javascript" src="/syntaxhighlighter/scripts/shBrushSql.js"></script>
    
    <script type="text/javascript"> 
        SyntaxHighlighter.config.stripBrs = true;
        SyntaxHighlighter.defaults['smart-tabs'] = true;
        SyntaxHighlighter.all(); 
    </script>

 

Last but not least the SyntaxHighlighter Plugin for Tinymce that you downloaded needs to be updated. Right now the plugin uses a textarea, and the name attribute to work. This will need to be modified to work with a pre tag and class attribute instead. Crack open \umbraco_client\tinymce3\plugins\codehighlighting\js\codehighlighting.js and modify it like so.

function Save_Button_onclick() { 
        var lang = document.getElementById("ProgrammingLangauges").value;
        var code = WrapCode(lang);

        code = code + document.getElementById("CodeArea").value.replace(/&lt;/g, "&lt;").replace(/&gt;/g, "&gt;").replace(/&/g, "&amp;");
        code = code + "&lt;/pre&gt; ";
        if (document.getElementById("CodeArea").value == '')
        tinyMCEPopup.close(); return false;
    
        tinyMCEPopup.execCommand('mceInsertContent', false, code); 
    
        tinyMCEPopup.close();
    }



Basically what I've done is changed the code to output a pre tag instead of a textarea, and included the brush: syntax right before the language type in the class attribute.

 

Thats it! I later plan to rewirte the tinyMCE plugin to include the new features of SyntaxHighlighter. Enjoy!

 

Welcome to OPF3

OPF3: The Painless ORM

I've been working with OPF3 for the past three years and I tell you, it has been a huge time saver. During my schooling, the standard method for manipulating a database would include writing SQL stored procedures, and then write methods within your data access layer to communicate with these stored procedures. Return values, @@IDENTITY, and methods taking lengthy parameters are all but a thing of the past, thanks to OPF3. When I was first introduced to OPF3, my first and initial thoughts were "huh?" and "what's wrong with stored procedures?

First of all, there is nothing wrong with stored procedures. In fact I still use them alongside the OPF3 framework. OPF3 isn't without its limitations though. Currently there is no support for return values. OPF3 was designed as a lightweight ORM (Object Relationship Manager) to eliminate mundane coding.

How does OPF3 work?

Imagine each table in your database as an object. For every table you have an object equivalent in your application. And just as you might expect, each object would have properties that map to the corresponding column in your database. It's a pain free process. Here's a tiny example of what such a class would look like.

[Persistent( "WebUsers" )]
        public class WebUser :ISelfContainingObject
        {
            [Field( "Id", Identifier = true, AutoNumber = true, AllowDBNull = false )]
            public int Id { get; set; }

            [Field( "Login", AllowDBNull = false )]
            public string Login { get; set; }

            [Field( "FirstName", AllowDBNull = false )]
            public string FirstName { get; set; }

            [Field( "LastName", AllowDBNull = false )]
            public string LastName { get; set; }

            [Field( "SALT", AllowDBNull = false )]
            public string SALT { get; set; }

            [Field( "HASH", AllowDBNull = false )]
            public string HASH { get; set; }

            [Field( "CreateDate", AllowDBNull = false )]
            public DateTime CreateDate { get; set; }

            [Field( "Status", AllowDBNull = false )]
            public int Status { get; set; }

            private ObjectInfo _ObjectInfo = new ObjectInfo();
            public ObjectInfo ObjectInfo
            {
                get { return _ObjectInfo; }
                set { _ObjectInfo = value; }
            }
        }


As you can see from my WebUser class, I've got full control of all columns in the WebUsers table. Now inserting / updating is as easy as this!

public enum eWebUserStatus
        {
            Active,     
            Pending,     
            Inactive
        }

        public void btnSaveWebUser_Click( object sender, EventArgs args )
        {
            //instansiate our WebUser class and assign the variables     
            WebUser newUser = new WebUser();
            newUser.FirstName = "Matt";
            newUser.LastName = "Tycholaz";
            newUser.Login = "matty";
            newUser.CreateDate = DateTime.Now;
            newUser.SALT = Tools.GenerateSALT();
            newUser.HASH = Tools.GenerateHASH( newUser.SALT + "secretpassword" );
            newUser.Status = ( int ) eWebUserStatus.Pending;

            try
            {
                //do an insert using a transaction         
                using ( Chili.Opf3.Storages.Transaction t = ObjectContextFactory.ObjectContext.StartTransaction() )
                {
                    //push our changes into the database             
                    ObjectContextFactory.ObjectContext.PersistChanges( newUser );
                    //commit the transaction             
                    t.Commit();
                }
            }
            catch ( Exception ex )
            {
                //if an error occurs then display it         
                MessageDisplay.DisplayMessage( ex );
            }
        }


Stay tuned for my next post where I'll show you more advanced scenarios.

Pure Logic has moved

I just got back from a week long trip to Jamaica (which was pretty sweet), but during my absence the office has been relocated. We're now at Suite 202, 17930 105 Ave NW

Stop on by and we'll help you grow your business!

Welcome

Hi there! , welcome to my blog! This is my first attempt blogging, but I do promise to make it informative and entertaining. I'm exciting to get the show on the road so check back in a bit for some new posts!