Showing posts with label Code. Show all posts
Showing posts with label Code. Show all posts

Tuesday, March 22, 2011

Updated batch installer for Telerik products

powershell-telerik

As you may recall, with the Q3 2010 release, I created a simple but useful PowerShell script that automates the process of updating your complete Telerik Ultimate Collection toolbox. In short, the script automatically uninstalls all old Telerik installs and then silently runs the MSI installers for all of the new bits. I have updated the script to now work with the Q1 2011 bits!

Usage Reminder

You can review the full overview in the original script post as the core behavior of this PowerShell script has not changed much to support Q1. To use this batch installer, simply:

  1. Download all of the Q1 2011 MSI installers
    • Place them in a single folder (by default, I expect a path of "C:\Program Files (x86)\Telerik\Downloads\Q1 2011\")
  2. Download the latest PowerShell script updated for Q1
  3. Run the script!
    • All pre-Q1 Telerik installs will be removed and all Q1 MSIs that you have downloaded will be installed

You can also always re-run the script and it will only uninstall pre-Q1 installs and only install Q1 bits that are not already installed. In other words, rerunning the script won't uninstall everything and reinstall everything (unless you force it to do that, which is an option when editing the script). This is useful if, for example, an uninstaller fails the first time. Just re-run the batch script to try the uninstaller again.

Download the Script

That's pretty much all there is to it. This is a manual, repetitive task time saver for those of you that, like me, want to update your system or VMs to have all of the latest and great Telerik bits. If you have a clean system with no installs, you can also use this script to quickly string together installs of all Ultimate Collection tools.

Download the updated Q1 2011 batch installer script

Wednesday, August 11, 2010

devLink 2010 Wrap-Up

devlink-2010 This has been a busy summer for speaking and .NET events! After the recent virtual mvcConf and (real) Dallas TechFest, I made my way to Nashville to participate in devLink 2010. If you’re not familiar with devLink, it is one of the largest (and best) community-run conferences in the US. John Kellar and crew put-on a 3-day, multi-track event that rivals the “big shows,” but unlike the big shows, devLink doesn’t cost you a paycheck. This year, devLink returned to the beautiful Lipscomb University campus in Nashville, and the event packed with over 800 paying developers.

I travelled to Nashville to deliver three sessions and participate on an impromptu panel on finding a job (hosted by David Giard or TechnologyAndFriends vidcast). My sessions were for the web developers at devLink, and we packed the rooms standing-room-only:

  • The Rich Standard: Getting Familiar with HTML5
  • Combining WebForms, MVC, and Silverlight
  • Getting the Most Out of What’s New in ASP.NET 4.0

Thanks again to everyone that joined me for the sessions, and big thanks to the person (sorry, didn’t grab your name) that taught that devLink vending machine a lesson for stealing my drink! I had a great time and hope you were able to learn something from the sessions. The code and slides for the sessions is available below for your on-demand learning pleasure.

For now, it’s time to prep and head-off to Baton Rouge for SQL Saturday. See you in Louisiana!

The Rich Standard: Getting Familiar with HTML5
[Slides (PDF)]

Combining WebForms, MVC, and Silverlight
[Slides (PDF)] [Code (Zip)]

Getting the Most Out of What’s New in ASP.NET 4.0
[Slides (PDF)] [Code (Zip)]

Tuesday, August 03, 2010

Using Custom ContentFilters with RadEditor and Telerik Reporting

A scenario popped-up last week that lead to a helpful tip I wanted to share with you. Here’s the scenario:

You are using Telerik Reporting for adding simple Business Intelligence to your ASP.NET applications. You are using RadEditor for ASP.NET AJAX to enable your content creators to input HTML in to your system. The Reporting HtmlTextBox only understands limited HTML tags for “paper oriented” page output, so you need to prevent content creators from adding unsupported HTML to tags that will be displayed in reports.

The first thing to understand is that the HtmlTextBox for Telerik Reporting is primarily concerned with enabling basic text formatting using familiar tags from HTML. It is not designed to render HTML like a browser. If you seek functionality like that, check out RadEditor’s built-in PDF export support.

The easiest way to solve this problem and “force” RadEditor to only accept Telerik Reporting-compatible HTML tags is to use Custom ContentFilters.

A ContentFilter is a simple JavaScript class that extends RadEditor’s functionality and adds processing to RadEditor whenever content is accessed (client-side and server-side). At it’s core, a ContentFilter has two methods: getHtmlContent and getDesignContent. Each receives the current content in the editor and is expected to perform some processing (usually done with RegEx) and return the result.

To target Telerik Reporting, we need a ContentFilter that will remove all HTML tags except those understood by the Reporting export engine (currently: FONT, STRONG, B, EM, I, U, A, OL, UL, LI, DIV, SPAN, P, BR, CENTER). We can do that with some RegEx that looks like this:

<(?!\/?(font|strong|b|em|(i(?!mg))|u|a|ol|ul|li|div|span|p|br|center)(?=>|\s?.*>))\/?.*?>

What’s this RegEx doing? In simple English:

  1. Matching the “<” character literally (start of an HTML tag)
  2. Matching any character except those in our list (list of Reporting-friendly tags) – if we find one of our “allowed” character strings, the tag won’t match our expression (and thus won’t be removed)
  3. Matching any remaining characters within the HTML tag (like attributes)
  4. Matching the closing HTML “>” (with possible “/>” self closing tag)

Using this RegEx, we can create a simple JavaScript file to define our custom ReportingFilter for RadEditor:

ReportingFilter = function()
{
ReportingFilter.initializeBase(this);
this.set_isDom(false);
this.set_enabled(true);
this.set_name("ReportingFilter");
this.set_description("Telerik Reporting HTML filter for RadEditor");
}
ReportingFilter.prototype =
{
getHtmlContent: function (content) {
return this._removeHtmlTags(content);
},

getDesignContent: function (content) {
return this._removeHtmlTags(content);
},

_removeHtmlTags: function (initContent) {
var cleanContent;

//Perform necessary REGEX replacement to remove unsupported HTML tags
//Supported Reporting HTML tags: FONT, STRONG, B, EM, I, U, A, OL, UL, LI, DIV, SPAN, P, BR, CENTER
//HTML must be XHTML valid, too, but Editor already provides that filter

//Following REGEX will remove all HTML tags EXCEPT those expliclitly listed
cleanContent = initContent.replace(new RegExp("<(?!\/?(font|strong|b|em|(i(?!mg))|u|a|ol|ul|li|div|span|p|br|center)(?=>|\s?.*>))\/?.*?>", "ig"), "");

return cleanContent;
}
}
ReportingFilter.registerClass('ReportingFilter', Telerik.Web.UI.Editor.Filter);

With our filter defined, we simply add the JavaScript file to our page and initialize the configuration in the client-side OnClientLoaded event of RadEditor:

<script src="reportingfilter.js" type="text/javascript"></script>
<script type="text/javascript">
function editorLoaded(editor, args)
{
editor.get_filtersManager().add(new ReportingFilter());
}
</script>

And for good measure, we can configure our RadEditor toolbars to “encourage” usage of the allowed, limited HTML tags by removing all other options:

<telerik:RadEditor runat="server" ID="editor1" OnClientLoad="editorLoaded" 
StripFormattingOnPaste="AllExceptNewLines" ContentFilters="DefaultFilters">
<Tools>
<telerik:EditorToolGroup>
<telerik:EditorTool Name="Bold" />
<telerik:EditorTool Name="Italic" />
<telerik:EditorTool Name="Underline" />
<telerik:EditorTool Name="FontSize" />
<telerik:EditorTool Name="ForeColor" />
<telerik:EditorSeparator />
<telerik:EditorTool Name="JustifyLeft" />
<telerik:EditorTool Name="JustifyCenter" />
<telerik:EditorTool Name="JustifyRight" />
<telerik:EditorSeparator />
<telerik:EditorTool Name="InsertOrderedList" />
<telerik:EditorTool Name="InsertUnorderedList" />
<telerik:EditorSeparator />
<telerik:EditorTool Name="InsertLink" />
</telerik:EditorToolGroup>
</Tools>
</telerik:RadEditor>

Result: A RadEditor that will automatically remove any HTML tags that Telerik Reporting’s HtmlTextBox doesn’t like. You can extend this example by adding additional processing to the custom filter to strip away unwanted HTML attributes from allowed tags, but that’s just a matter of finding the necessary RegEx.

Download the code for this example [Requires your own copy of Telerik.Web.UI]

Thursday, May 27, 2010

Improved, Easy Email Template “Engine” with Smarter ToString Extension

This blog often focuses on Telerik and Microsoft news, and rarely do I bring you much “original thought” code (especially lately). But this class is just too useful not to share.

Let me just lead with the scenario:

  1. You have a program that is going to send auto-generated emails
  2. You want templates for your emails that support value merging
  3. You want to maintain your templates as HTML files for easier editing
  4. You want something as easy to use as String.Format

While there are tons of templating engines for C#, I just wanted something simple and to the point. The solution Scott Hanselman provided a couple of years ago was very close to what I wanted, but it doesn’t support collections (very important for Master-MasterDetail type messages). So I added the tweak to support these scenarios.

Here’s how you use it:

//Create a simple template
string template = "Hello {FirstName}! You've ordered: <ul>{Items:<li>{Name}</li>}</ul>";

//Create your object with the template values (can by anonymous type)
//(Let's use some pseduo LINQ to get a customer with a specific ID)
var myTemplateValues = myObjects.Where(o => o.Id == id).Select(o => new
   {
       FirstName = o.FirstName,
       Items = o.Items //Assume each item in ICollection has Name property
   });

//Merge values with template 
string mergedTemplate = myTemplateValues.ToStringWithFormat(template);

The result of the above code should be a string that looks something like:

Hello Todd! You’ve ordered: <ul><li>Item Name 1</li><li>Item Name 2</li></ul> You can, of course, add formatting to your objects in your template, too, such as: {Birthdate:dd MMM yyyy} But when you’ve got a collection, you can use the object format string to include nested property values, like this: {Customers:<li>{Birthdate:dd MM yyy}</li>} Pretty cool! It’s a nice balance between the templating engines that are super complex and a plain-jane String.Format. It doesn’t do everything you could ever want, but it does enough for many auto-email scenarios. In my own usage, I have a simple method that let’s me quickly merge my context values with my template when I’m ready to build an email’s body:
public static string GetMergedTemplate<T>(string template, T contextInstance)
{
   if (String.IsNullOrWhiteSpace(template))
       return null;

   return contextInstance.ToStringWithFormat(template);
} 
Which brings us to the implementation of ToStringWithFormat. This is a modified version of the extension method from Hanselman that gives us the extra power we desire:
/// <summary>
/// Returns a string and replaces named place holders with object values
/// </summary>
/// <remarks>Originally from Scott Hanselman's Blog: http://www.hanselman.com/blog/ASmarterOrPureEvilToStringWithExtensionMethods.aspx </remarks>
/// <param name="anObject"></param>
/// <param name="aFormat"></param>
/// <returns></returns>
public static string ToStringWithFormat(this object anObject, string aFormat)
{
   return StringExtensions.ToStringWithFormat(anObject, aFormat, null);
}

public static string ToStringWithFormat(this object anObject, string aFormat, IFormatProvider formatProvider)
{
   if (anObject == null)//Can't merge null object. Be nice and return original format string.
       return aFormat;

   StringBuilder sb = new StringBuilder();
   Type type = anObject.GetType();
   //Old pattern: @"({)([^}]+)(})" - Doesn't handle nested brackets
   //New pattern:"({)((?:[^{}]|{[^{}]*})*)(})" - Handles ONE LEVEL of nested brackets
   Regex reg = new Regex(@"({)((?:[^{}]|{[^{}]*})*)(})", RegexOptions.IgnoreCase);
   MatchCollection mc = reg.Matches(aFormat);
   int startIndex = 0;
   foreach (Match m in mc)
   {
       Group g = m.Groups[2]; //it's second in the match between { and }
       int length = g.Index - startIndex - 1;
       sb.Append(aFormat.Substring(startIndex, length));

       string toGet = String.Empty;
       string toFormat = String.Empty;
       int formatIndex = g.Value.IndexOf(":"); //formatting would be to the right of a :
       if (formatIndex == -1) //no formatting, no worries
       {
           toGet = g.Value;
       }
       else //pickup the formatting
       {
           toGet = g.Value.Substring(0, formatIndex);
           toFormat = g.Value.Substring(formatIndex + 1);
       }

       //first try properties
       PropertyInfo retrievedProperty = type.GetProperty(toGet);
       Type retrievedType = null;
       object retrievedObject = null;
       if (retrievedProperty != null)
       {
           retrievedType = retrievedProperty.PropertyType;
           retrievedObject = retrievedProperty.GetValue(anObject, null);
       }
       else //try fields
       {
           FieldInfo retrievedField = type.GetField(toGet);
           if (retrievedField != null)
           {
               retrievedType = retrievedField.FieldType;
               retrievedObject = retrievedField.GetValue(anObject);
           }
       }

       if (retrievedType != null) //Cool, we found something
       {
           string result = String.Empty;
           if (toFormat == String.Empty) //no format info
           {
               if (retrievedObject is ICollection)
               {
                   foreach (var item in (retrievedObject as ICollection))
                   {
                       //In this branch toFormat is blank, so just call toString on
                       //each object in collection (ex:{Items})
                       result += item.ToString();
                   }
               }
               else
                   result = retrievedObject.ToString();
           }
           else //format info
           {
               if (retrievedObject is ICollection) //Process first level collection
               {
                   foreach (var item in (retrievedObject as ICollection))
                   {
                       //In this branch toFormat contains nested property name, so
                       //make recursive call to ToStringWithFormat to process property value
                       //(ex: {Items: {PropertyName}})
                       result += item.ToStringWithFormat(toFormat);
                   }
               }
               else
                   result = String.Format(formatProvider, toFormat, retrievedObject);
           }
           sb.Append(result);
       }
       else //didn't find a property with that name, so be gracious and put it back
       {
           sb.Append("{");
           sb.Append(g.Value);
           sb.Append("}");
       }
       startIndex = g.Index + g.Length + 1;
   }
   if (startIndex < aFormat.Length) //include the rest (end) of the string
   {
       sb.Append(aFormat.Substring(startIndex));
   }
   return sb.ToString();
}
A key limit in this approach is the RegEx, which technically is not adept at finding nested bracket patterns. RegEx works fine if you accept a fixed number of supported nested levels, but it cannot dynamically handle unknown levels of nesting. A single level was fine for my needs and thus I left it at that, but this could be extend to provide even richer support for collections if RegEx were replaced.

I hope you enjoy this simple update on a classic. As commenters pointed out in Scott’s original post, this approach does create opportunity for “evil” when it comes to refactoring and performance, so there is still plenty of room to improve. But for a pragmatic solution, I’ve found this very useful.

Monday, March 01, 2010

#SFLCC wrap-up, Twitter insights

As you know from my last minute post on Friday, I spent a part of this past weekend in southern Florida for the South Florida .NET Code Camp 2010. As usual, it was a great time, with lots of eager .NET learners and interesting content. And while it looked like some of the speakers might not make it due to the storms in the North East, I think almost everyone made it to the event. A big thanks to everyone that came to the Code Camp, especially all of you that packed my two sessions!

Meanwhile, I learned, or rather re-enforced, another little tidbit on this trip: Nobody in South Florida uses Twitter.

I’ve polled audiences for well over a year now asking two questions:

  1. How many of you “use” Twitter? That is, do you tweet?
  2. How many of you “lurk” on Twitter (you read, but don’t tweet)?

Those that don’t respond to either question are either A) already sleeping, or B) presumed to not use Twitter at all (read or write). Traditionally, I’ve found that in a “normal” developer audience, no matter where in the world I’ve done this poll, only 10% (or so) of the audience does anything with Twitter. In other words, In a room of 50 people, 5 people (on a good day) use Twitter.

Florida was different. In two rooms of 50+ people, only 1 person admitted to using Twitter. More reinforcement of the idea that Twitter is a much smaller active community than the numbers suggest.

Telerik Prizes via Twitter

This created a bit of problem for my swag scheme. To win swag from my sessions, I told everyone to simply follow me on Twitter and on Monday (today) I would select two random winners. Fortunately, with a little coaching, I managed to bring a small chunk of South Florida on to Twitter, and I’ve got my random winners:

@marquinakat
@gardavis

Congrats to both! You each get a Telerik Premium Collection. And you may now resume not using Twitter.

Thanks again for attending my sessions and feel free to grab the session resources below. See you next year!

Resources from my sessions

Being Productive with Telerik Extensions for MVC
[Slides (PDF)]

ASP.NET Fundamentals: ViewState Tips & Tricks (v2)
[Slides (PDF)] [Code (Zip)]

Sunday, October 18, 2009

DevReach Follow-up, Part I

Hello from Bulgaria! This update comes to you direct from Telerik HQ in cold, wet Sofia, Bulgaria. I am seated high atop the Telerik building listening to the sounds of buses and cars cruise by on the wet streets below as I get prepared for a busy week with the local teams, and I figured it was high-time I broke my blog "travel silence" to bring you a quick update.

As you know, I am in the middle of the busy "fall travel season," and since I'm in Bulgaria, that means it's time for DevReach 2009. The conference went down last week and it was a great event! Despite the economic turmoil plaguing many events this year, DevReach was as strong as ever, with over 450 attendees packing the two days of sessions delivered by "first class" speakers. Everyone from Richard Campbell to Shawn Wildermuth to Tim Huckaby, Chris Sells, and Kent Alstead (and many others) trekked to the capital of Bulgaria to put on a good show.
I, of course, joined this stellar cast of speakers as the "outlier." I presented three sessions this year at DevReach:
  • Maximizing Ajax Performance with REAL Ajax
  • Building a Common Data Layer for ASP.NET and Silverlight
  • Will It Blend? Building Websites with All Flavors of ASP.NET
All of the sessions were well attended and everyone seemed to have a "good enough" time. The most popular session this year (of mine)? Probably "Will It Blend." A big thanks to everyone that came-out to my sessions and for putting-up with my random Texas trivia. Hopefully you all had a good time and managed to learn something (even if only how great Texas is) at each of my sessions.
I captured some video from around the conference I'll be working to transform in to a new TWM as soon as I can. Stay tuned for that "Part II" update. Until then, enjoy the resources below from my sessions and then watch for more updates as "Fall Travel Season" wears on. Next-stop: Q3 2009 release week!
Maximizing Ajax Performance with REAL Ajax
Will It Blend? Building Websites with All Flavors of ASP.NET
Building a Common Data Layer for ASP.NET and Silverlight
[Slides] [Code coming soon...]

Thursday, October 08, 2009

RadGrid optimization webinar on Telerik TV

Did you miss last week's RadGrid for ASP.NET AJAX optimization webinar? Then don't miss this recorded video. This session covers the basics of optimizing RadGrid for ASP.NET AJAX and introduces a handful of techniques you can use to make your ASP.NET pages with RadGrids faster. Catch the video above and grab the session slides and demo code below. Enjoy!

SW Florida Code Camp 2009 wrap-up

The fall travel season is swinging in to full gear and already blog posts are getting behind (which reminds me, I need to create a post about the "fall travel season"...). Kicking-off the season of conference travel was last weekend's trip to Fort Myers, Florida for the SW Florida Code Camp. A full-day Saturday event held on the campus of Florida Gulf Coast University, the 2nd Annual SWFLCC brought out almost 150 people to engage in .NET learning.

This was my first trip to the SWFLCC and it was a great time! I presented 3.5 sessions- 3 scheduled + 1 "pinch hit" for a speaker that had a family emergency. My sessions were packed to capacity, and aside from some slow morning grogginess during my 8:30 AM slot, the audiences were very involved with great questions. To everyone that attended my sessions, a big thanks for coming out and being involved! Hope you learned something.
For sessions, I covered a lot of ground, with topics ranging from Silverlight to MVC to Dynamic Data. You can grab all of the slides from this even below along with relevant demo code. Enjoy the resources and stay tuned for an updated list of my conference stops this fall.
Rich Islands of Functionality: Silverlight in ASP.NET
Will It Blend? Building Websites with All Flavors of ASP.NET
Being Productive with ASP.NET MVC: Telerik Open Source Extensions for MVC
P.S. Big congrats to John Dunagan for playing such a big role in the success of this year's event! John is doing a great job unifying the .NET community in SW Florida, and with a little encouragement, I think he could expand SWFLCC to 300 people next year. Easily.

Monday, September 28, 2009

Houston TechFest 2009 wrap-up, Slides and Code

This past Saturday played host to the 3rd (4th?) annual Houston TechFest, and this year's event was record setting! There were well over 1200 people registered for this year's event, and- if I've heard the reports correctly- almost 1,000 people joined in the day of technology festivities at the University of Houston. That makes this easily the most attended TechFest in Houston to date and it also makes Houston TechFest one of the largest "regional events" in the US!

And thanks to sponsors, like Telerik, the event was once again 100% free to attendees (with a provided lunch)! Obviously, a great place to be if you are a .NET (or Java or whatever else was covered on Saturday) developer. At the Telerik "micro-booth" I had a great time meeting a lot of you and introducing you to the All-in-one .NET Toolbox.
Usually I like to "pre-promote" my attendance at these events on Telerik Watch, but time escaped me last week to update the blogs (all the more reason to follow me on Twitter for "quick updates"). So instead, a quick post-event recap:
I presented three sessions on Saturday: one-and-a-half on Silverlight, one-and-a-half on ASP.NET/Ajax ("havles" because one session talked about using Silverlight in ASP.NET, so it covered both technologies). All of the sessions were well attended and (with the help of some t-shirt bribes) all were very interactive. Big thanks to those of you that attended all of my sessions on Saturday! I don't know if I could even tolerate 4 hours of listening to me...
As promised, I am making the slides and code from the sessions available for everyone here. Find my full session list with accompanying resources below. Until next year, make sure you stay plugged-in to the Houston .NET community through the area DNUGs, like NHDNUG in my neck of The Woods!
What's New in Silverlight 3 [Sept09 update]
Rich Islands of Functionality: Silverlight in ASP.NET
Maximizing ASP.NET Performance with REAL Ajax

Tuesday, September 01, 2009

Changing RadTicker content with nuthin’ but JavaScript

radticker As the Interwebs mature, and as web developers are pushed to deliver increasingly rich experiences through the browser, there are two technologies a developer can use to deliver to richness: (plug-in based) RIAs and JavaScript. Each technology has it’s pros and cons, but JavaScript has the serious advantage of being the “native” programming language for all Internet connected devices.

The Telerik RadControls for ASP.NET AJAX enable you to deliver standards-based richness using JavaScript, and in most cases you can deliver it without writing any code yourself. But what about those cases when you do want to take more control?

For that, the RadControls provide a very robust client-side API. In fact, most methods and properties available in the server-side API are available under the same (or very similar) names on the client. That means you can increasingly do more of your programming on the client (moving data with web services) and rely less on the “heavy” server-centric model.

That is a long introduction to get to today’s central point: how can you use JavaScript and the RadTicker client-side API to update RadTicker’s items on the fly?

RadTicker is unquestionably one of the “smaller” RadControls (when compared to RadGrid or RadScheduler), but it’s useful nonetheless. Unfortunately, today’s RadTicker doesn’t have a simple client-side API for changing items with JavaScript. But with a little jQuery and an understanding of how RadTicker works, we can easily change RadTicker items on the client and even bind our RadTicker to web service data.

Click to continue reading and see code for RadTicker client-side API

There are a couple of key concepts that you must understand to make this undocumented approach to changing RadTicker content work:

  • RadTickerItems are rendered as SPAN tags in a parent "itemContainer" SPAN. The RadTicker object simply rotates through displaying the content of all child SPANs in the itemContainer. Removing or adding SPANs to this collection allows you to change RadTicker's contents.
  • Related, the RadTicker object looks for specific SPAN IDs when rotating through items. Specifically, each TickerItem SPAN must have the ID "RadTicker1_i2"- where "RadTicker1" is the control's ClientID and "2" is the "index" of the item in the list of TickerItem SPANs.

Expressed in in code, this is how a basic RadTicker with three RadTickerItems renders on the page:

<span id="RadTicker1" style="display:inline-block;height:30px;width:400px;">
  <span id="RadTicker1_itemsContainer" style="display:none;">
      <span id="RadTicker1_i0">This is ticker item 1</span>
      <span id="RadTicker1_i1">Ticker item 2 is this</span>
      <span id="RadTicker1_i2">Finally, Ticker item 3</span>
  </span>
  <input id="RadTicker1_ClientState" name="RadTicker1_ClientState" type="hidden" />
</span>

By writing JavaScript that manipulates RadTicker's SPAN item collection, we can easily update the RadTickerItems completely client-side. For example, we can write code like this to append a new item to the RadTicker:

//Get reference to RadTicker and text input
var ticker = $find('RadTicker1');        
var container = ticker._getChildElement("itemsContainer");

var index = container.childElementCount;

//Create new SPAN - this will be our new Ticker item
var newElement = document.createElement("span");
newElement.setAttribute("id", 'RadTicker1_i'+ index);
newElement.innerHTML = txtEle.value;
     
$(newElement).appendTo(container);

//Tell RadTicker to recalculate number of Ticker items
ticker.set_numberOfItems($telerik.getChildrenByTagName(ticker._itemsContainer, "span").length)

Using this same basic pattern, we can easily expand on this example to also replace ticker items and bind ticker items to web service data. Check out a live running example showing this client-side approach for appending, replacing, and web service binding RadTicker.

NOTE: This is an undocumented client-side approach. RadTicker may (and probably will) provide a better API for doing this in the future. Use this approach in the mean time if you need to change RadTicker on the fly. Also note, if you do POST the page, your client-side changes will be lost.

Hopefully this tip will help you fully embrace client-side programming in your rich, standards-based web applications. The fully-commented code for this live demo is available for download below. Enjoy!

Live demo – Using JavaScript to change RadTicker Items

Download RadTicker JavaScript demo source code

Saturday, August 01, 2009

Code: SQL script for dropping all Sitefinity objects

sitefinity-sql I don’t often post code snippets on Telerik Watch. I tend to save posts like that for the official Telerik Blogs or my more general Code Campground blog. But today I’ll make an exception since my snippet is covering a topic I rarely get to cover these days: Telerik Sitefinity CMS. I used to spend more time covering Sitefinity on Telerik Watch, but as that platform has grown and become increasingly popular (and powerful), I’ve let the experts (like Sitefinity Evangelist Gabe Sumner) bring you the regular news, updates, and snippets.

Today I faced the challenge of upgrading an old Sitefinity site (v3.0 – used by my wife for her class website) to the latest and greatest v3.6 SP2. Like a new OS install, I wanted to start with a “clean slate” instead of trying to work through an upgrade, and to do that I needed to remove all Sitefinity v3.0 objects from my SQL Server database.

Should be easy, but I’ve got a couple of challenges I’m sure some of you face:

  • My SQL Server is hosted, meaning I don’t have complete control over the server to drop and recreate entire databases
  • More significantly, this database is hosting tables for multiple applications- not just Sitefinity. I need to leave my other DB objects in-tact and only remove my Sitefinity-specific objects.

To solve my problem, I need a SQL script that will go through my database and delete all Sitefinity tables, stored procedures, and relationships. Thankfully, Sitefinity prefixes all of the objects it creates with either “sf_” or “telerik_”, so we can us that fact to create a script that will delete all objects that meet our prefix search criteria.

Continue reading to see SQL solution

Based on a helpful “generic” script on Paige Cook’s blog, the following script can be used delete all (and only) Sitefinity objects in a SQL Server database:

-- Drop all Sitefinity stored procs
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0
   AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
WHILE @name is not null
BEGIN
   SELECT @SQL = 'DROP PROCEDURE [dbo].[' + RTRIM(@name) +']'
   EXEC (@SQL)
   PRINT 'Dropped Procedure: ' + @name
   SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'P' AND category = 0
       AND [name] > @name AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
END
GO

-- Drop any Sitefintiy views (none in current default install)
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0
   AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
WHILE @name IS NOT NULL
BEGIN
   SELECT @SQL = 'DROP VIEW [dbo].[' + RTRIM(@name) +']'
   EXEC (@SQL)
   PRINT 'Dropped View: ' + @name
   SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'V' AND category = 0
       AND [name] > @name AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
END
GO


-- Drop any Sitefinity functions (none in current default install) 
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT')
   AND category = 0 AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
WHILE @name IS NOT NULL
BEGIN
   SELECT @SQL = 'DROP FUNCTION [dbo].[' + RTRIM(@name) +']'
   EXEC (@SQL)
   PRINT 'Dropped Function: ' + @name
   SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] IN (N'FN', N'IF', N'TF', N'FS', N'FT')
       AND category = 0 AND [name] > @name AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
END
GO

-- Drop all Sitefinity Foreign Key constraints 
DECLARE @name VARCHAR(128)
DECLARE @constraint VARCHAR(254)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
   WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY'
   AND (TABLE_NAME LIKE 'sf_%' OR TABLE_NAME LIKE 'telerik_%') ORDER BY TABLE_NAME)
WHILE @name is not null
BEGIN
   SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
       WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY'
       AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
   WHILE @constraint IS NOT NULL
   BEGIN
       SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT ' + RTRIM(@constraint)
       EXEC (@SQL)
       PRINT 'Dropped FK Constraint: ' + @constraint + ' on ' + @name
       SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
           WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY'
           AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
   END
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
   WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY'
   AND (TABLE_NAME LIKE 'sf_%' OR TABLE_NAME LIKE 'telerik_%') ORDER BY TABLE_NAME)
END
GO

-- Drop all Sitefinity Primary Key constraints 
DECLARE @name VARCHAR(128)
DECLARE @constraint VARCHAR(254)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
   WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY'
   AND (TABLE_NAME LIKE 'sf_%' OR TABLE_NAME LIKE 'telerik_%') ORDER BY TABLE_NAME)
WHILE @name IS NOT NULL
BEGIN
   SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
       WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY'
       AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
   WHILE @constraint is not null
   BEGIN
       SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT ' + RTRIM(@constraint)
       EXEC (@SQL)
       PRINT 'Dropped PK Constraint: ' + @constraint + ' on ' + @name
       SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
           WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY'
           AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
   END
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
   WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY'
   AND (TABLE_NAME LIKE 'sf_%' OR TABLE_NAME LIKE 'telerik_%') ORDER BY TABLE_NAME)
END
GO

-- Drop all Sitefinity tables
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0
   AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
WHILE @name IS NOT NULL
BEGIN
   SELECT @SQL = 'DROP TABLE [dbo].[' + RTRIM(@name) +']'
   EXEC (@SQL)
   PRINT 'Dropped Table: ' + @name
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0
   AND [name] > @name AND ([name] LIKE 'sf_%' OR [name] LIKE 'telerik_%') ORDER BY [name])
END
GO

When this runs it will delete about 670 objects from your database, printing the name of each dropped object to the query output window. If you refresh your objects and still see Sitefinity objects in your database, just run the script a second time and that should fully clean your database. You now have a clean starting point to re-install Sitefinity in your database, and you’ve done your cleaning without touching any of your other, non-Sitefinity database objects. Hope this helps!

Monday, June 22, 2009

Dallas TechFest Wrap-up, Slides and Code

With the weekend squarely in the rear view mirror, it's time to close the books at this year's Dallas TechFest. The event, which was held on Friday, was a full-day of not only .NET learning, but Java, Cold Fusion, Flex, and Ruby, all held in the setting of the beautiful Westin Stonebriar Resort. I never saw an official "numbers" report, but it looked like there were easily 250 - 350 people taking part in the fun (maybe even more), so by all accounts I think the event was a success. Both of my Silverlight 2/3 sessions went well, too. Aside from my ThinkPad giving me plenty of reason to think about shortening its life, the demos went well and the crowds got a good taste of SL3. In fact, Building Business Apps with SL3 was a standing room only session, so extra special thanks to those of you that came and stood through it all! Below you can find the slides and code from my sessions. Be sure you have Silverlight 3 installed to work with the code, and don't forget that installing SL3 means the end of your SL2 development. Until the tooling gets better, it's an either-or choice. Building Business Applications with Silverlight 2 (and 3) [Slides (PDF)] [Code (8MB Zip)] What's New in Silverlight 3? [Slides (PDF)] [Code (3MB Zip)]

Monday, June 08, 2009

Austin Code Camp 2009 wrap-up, Session slides and code

Sometimes it's just incredible how fast time flies. It's already been a full week since I spoke at the 2009 Austin Code Camp, so it's high time I posted my follow-up materials! In general, ACC09 was a great event. Both of my sessions were packed- standing room only- and the audiences were very engaged. For an Austin .NET community that occasionally gets a bad rap in Texas for not being as active as Houston or Dallas, this event was a strong showing- probably close to 250 to 300 people. As a reminder, I did two sessions, one on ASP.NET MVC and one on Silverlight 3. Both sessions seemed to go well except for an unfortunate Visual Studio gremlin with Silverlight 2 during the last session of the day. I suppose that's the end result of sleeping for 3 hours, driving to Austin at 5:00 in the morning, and then doing the last session of the day. Se la vie! The slides from both of my sessions and some of the code is available below. I say only "some" of the code because some it is not worth packaging- just simple demos created on the fly that don't offer much "after the fact" learning value. Even the code posted here is very basic- nothing special- so don't lean on it too heavily for learning. Enjoy the resources, though, and then get ready to come back out and hang-out with me at the Dallas Tech Fest in a couple weeks! ASP.NET MVC: Red Pill or Blue Pill? (Updated for MVC v1) [Slides (PDF)] [Code (ZIP)] (NOTE: Code includes updated RouteDebugger assembly for MVC v1) Building Business Applications with Silverlight 3 [Slides (PDF)] [Code (ZIP)] (NOTE: Code is for Silverlight 3 beta 1) P.S. As mentioned in my Silverlight session, here is a link to my Silverlight 2 Hands-On-Labs that guide you through the process of learning how to build business apps with Silverlight 2.

Friday, May 29, 2009

Skinning Deep Dive Webinar Follow-up

Miss today's fun skinning webinar? No worries- I've got the on-demand resources ready for your immediate enjoyment. As promised, today's webinar covered a wide range of skinning topics for the RadControls for ASP.NET AJAX. We discussed skinning basics and highlighted how the "OTBE" (Out-of-The-Box Experience) for the RadControls makes it very easy to get started with professional skins. We moved on and gained a deeper understanding of how the RadControl's skin CSS is structured and how it can be very easily customized. We took a deep look at how you consume customized skins. And we even spent some time looking at ways to optimize your skin performance. Thanks to everyone that turned-out for the live event! I hope you enjoyed the content. For everyone else, the session recording is available above and on Telerik TV. Slides and demo code used in today's presentation is below. No go forth and be confident Telerik skin masters! Skinning Deep Dive for the RadControls for ASP.NET AJAX [Slides (pdf)] [Code (zip)] [Full-res Video on Telerik TV (online)]

Thursday, May 07, 2009

RadControls for Silverlight in ASP.NET

For those of you that missed today's Weekly Webinar, you missed a fun topic! We looked at how you can use the RadControls for Silverlight in ASP.NET. Specifically, we looked at how you can use RadChart, RadGauge, and RadUpload for Silverlight in an existing ASP.NET application by utilizing the DOM Integration features of Silverlight. There were lots of demos and we covered a lot of ground, but hopefully everyone that attended live (thanks, by the way, for watching today!) feels like they have the knowledge they need to start leveraging Silverlight controls in ASP.NET. For everyone else, all resources from today's session are now available online. Below you can download the slides and demo project code, and above you can watch the recorded session (or you can watch it on Telerik TV, of course). Enjoy and watch for more follow-up resources soon! RadControls for Silverlight in ASP.NET [Slides] [Code] Watch recorded webinar in full resolution on Telerik TV

Thursday, February 12, 2009

South Florida Code Camp 2009 Wrap-up (update)

As everyone knows, this past Saturday I made a quick trip from Texas to attend and speak at the 2009 South Florida Code Camp (#SoFlCC, for all you twits out there). It was another outstanding event and I'm very glad I made the trip! Registration numbers topped 800 and over 600 people turned-out for the day-long event, which for anyone not "in the know" is pretty incredible for a "code camp." I'm always amazed by the size and involvement of the Florida .NET community, and this year's Code Camp did nothing but further that amazement. My two sessions also went very well. Both were packed and both sessions generated a lot of good questions. A big thanks to all of you that came out to one (or both!) of my sessions. Hopefully you enjoyed the content despite my speaker "idiosyncrasies." Congrats to all of the t-shirt and Telerik license winners, too! As promised, I'm making the slides from both sessions available on this blog post (see links below). I'll be making the code available, too, but there are some problems with the server hosting my downloads, so the links aren't live yet. Check back soon for live downloads. Finally, I couldn't call this a real wrap-up post if I didn't mention Telerik's sponsor involvement. I had a great time manning the Telerik "micro booth" and talking to many of you between sessions. I always enjoy meeting Telerik "fans" and people that want to join the club. I learned about some very cool projects being built this year and I'm thrilled that Telerik has been selected as the trusted partner for .NET tools and components. The Telerik-sponsored after-party was fun, too. If you missed it, you missed a good time- don't miss it next year! Needless to say, SoFlCC remains a bright spot on my calendar and I look forward to heading back to Florida next year for SoFlCC 2010! ASP.NET MVC: Red Pill or Blue Pill? [Slides] [Code] ASP.NET ViewState Tips & Tricks [Slides] [Code]

Thursday, October 02, 2008

RadGridView webinar follow-up (update)

Today Lino Tadros from Falafel held the first RadWebinar on Telerik's RadGridView for WinForms. The event went very well and we hope that everyone that attended enjoyed the format and was able to learn something new about RadGridView. If you weren't able to make today's event, or if you'd just like to study the material presented in-depth, Lino has gone the extra mile and prepared PDF courseware and numbered demos for your reference. You can download those resources below. The video of today's event will be available online soon, too. It will take some more time to process the video for online viewing, but to avoid any delays (and to have access to the "full size" video), you can download the "raw" GoToWebinar recording below. A lightly edited version will be available for online viewing in the coming days. Enjoy the content and keep your RSS readers tuned-in for the next RadWebinar details! Download PDF courseware [3 MB] Download demo code [1 MB] Download RadWebinar video (MOV) [650 MB] UPDATE: The online version of the webinar is now available for those that want to stream it.

Thursday, August 28, 2008

Telerik Watch Minute: Highly Optimized RadEditor Auto Save

In this week's longer than usual update (about 5 minutes total), I bring you some essential news updates and then show you quickly how to build a highly optimized auto save form with RadEditor and WCF. The form utilizes RadEditor's rich client-side API to implement a non-intrusive auto save feature that only saves content when an user stops typing. And WCF is used to persist data back to the server so that communication is light-weight and highly optimized (if we use "normal" ASP.NET AJAX UpdatePanels, a ton of unnecessary data would be included in our saves...specifically, ViewState).

I apologize for "streching" the TWM format a little longer than normal; hopefully the more complete demo will make it worth your time. You can download the files for the demo (including a trial version of the RadControls for ASP.NET AJAX Q2 2008 SP1) below.

Download Auto Save demo project

Wednesday, August 27, 2008

devLink 2008 wrap-up (update)

Another event, another wrap-up. And I'm happy to report that this was another great event. DevLink 2008 saw well over 400 .NET developers converge on speed-ticket happy Murfreesboro, Tenessee for two days of (as one attendee put it) "better than TechEd quality" sessions. For my part, I tried to bring as many updates from the conference as I could while running between sessions and conference parties. If you haven't seen the video updates, check out Live from devLink 2008, devLink 2008 Montage, and my Silverlight Intro Session Replay. Of course, nothing beats actually being at the event, so start making plans now to attend next year's festivities.

As far as sessions go, my two Silverlight sessions went very well. Well, actually, my "Intro" session went really well and my deep dive was okay. Not that the session was bad, but a day that started with a speeding ticket didn't get better when the original room's projector failed and I discovered I had 2.5 hours for a "3 hour deep dive." So apologies to those of you at the deep dive that didn't get to see as much as I had planned.

As promised, below are links to download the slides and code from both of my Silverlight sessions. They are great resources if you're trying to get started with Silverlight, and they're completely updated to reflect the latest changes in Silverlight 2 beta 2.

Enjoy the learning resources. I'm off to count 120,000 12,000 pennies to mail to the fine state of TN.

Intro to Silverlight 2
Silverlight 2 Deep Dive
[Slides] [Code] UPDATE: Josh caught my decimal point error: I only owe TN 12,000 pennies for driving 50 in (as far as my time on the road was concerned) an unmarked 40.