It’s confirmed: Apple sucks!

I long suspected that Apple played dirty, just didn’t know to what extent. Today I got a chance to find out.

An iPad mini came into my possession, so I registered an online “AppleID” account. This required all kinds of contact information, including cell phone number which I provided. Soon after registration I began to receive spam calls and text messages. No, not from Apple, oh no. These came from auto insurances, money making schemes and other such scum. Wherever did they get my number? I have had it for several years and NEVER received any spam until this fateful day.

But this is just a beginning. I decided – to hell with it, I was willing to give Apple a chance and they blew it. So now I wanted to delete my account and all associated data. Surprise! You can’t do this online. At http://appleid.apple.com you can only change some contact info, but that’s about it.

So I called support. They requested my device serial number. That made me really wonder – why? If I want to cancel my Google account – they don’t request my Droid phone s/n. Ditto Amazon & Kindle. So why, Apple, why?

The support agent enlightened me. This is needed so I could be charged for this paid support call! I needed to pay to get information on how to cancel my account.

Well, this is really it. Back to Android. Oh and by the way, I don’t see what’ s the fuss is about. As a tablet iPad is pretty average, it does pretty much what any other tablet on the marked does. A few years ago when it was the only thing – maybe it was something. But now – Apple lost it.

FusionCharts.RenderChart and ASP.NET UpdatePanel

Fusion Charts

FusionCharts is a very cool cross-platform charting library – it offers huge variety of chart types and mind-blowing special effects. It also offers wide variety of chart rendering options both client- and server-side.

One such option is to render chart in an ASP.NET application. FusionCharts.dll that you get with the package offers handy FusionCharts.RenderChart method that generates all the client-side code you need to display a beautiful chart. Usually it is used something like this:

1xLabel1.text = FusionCharts.RenderChart("FusionCharts/Pie2D.swf", "", sChartXmlData, sChartID, iChartWidth, iChartHeight, False, True)

where xLabel1 is a Label or Literal control in your ASPX page and FusionCharts.RenderChart is a function that accepts number of parameters, like chart type, chart XML data, dimensions etc.

It works very well until you want to render the chart inside of Microsoft Ajax UpdatePanel – then nothing works. This happens because FusionCharts.RenderChart function emits some HTML along with JavaScript that do not work during partial postback. FusionCharts suggest hooking up to UpdatePanel life-cycle events, but it’s seems like an overkill, and often doesn’t work (especially if you have a complex project, which this hookup can interfere with). But there’s an alternative solution.
Continue reading →

Infragistics WebDataMenu last item disappears

While using Infragistics WebDataMenu control from their NetAdvantage for ASP.NET Suite (version 2012.2, current as of this post) I noticed that last menu item in horizontal menu disappears. To me this only happened in Firefox.

Disappearing Act

This post suggested to set EnableScrolling menu property to False as a solution. Which is fine and well, but did not work for me since I need my menu to scroll (it has limited width available and menu items are added programmatically in code-behind so total items width can be wider than width available for the menu).

Continue reading →

Infragistics WebDataGrid: Hidden columns become visible after AJAX postback

A recent update to .NetAdvantage for ASP.NET v12.2 introduced a weird bug – hidden columns of WebDataGrid and WHDG become visible after postback. Service release 12.2.20122.2031 fixed that issue – but only for full postback. Under some circumstances if grid performs an AJAX call (sorting, paging etc.) hidden columns become visible again. This does not happen in IE, but other browsers, such as Chrome and FireFox do exhibit the issue.

This is happening because hidden columns lose “display:none” property in their style. If this happens to you – you have to take matter in your own hands. Continue reading →

Infragistics WebDataMenu: Enable client-side resize with scrolling

Infragistics WebDataMenu control for ASP.NET has a neat feature: if items for horizontal menu don’t fit in allocated width – it automatically adds scroll buttons:

Scrolling in WebDataMenu

Unfortunately this works only if you set menu width in ASPX markup or server-side code. But what if menu is built dynamically and you don’t know in advance how many items there will be. Or if user resizes browser window and available width changes?

We need to be able to set menu width in client-side JavaScript code. Also we need to check whether all items fit into menu width and if not – enable scroll buttons – on demand. The code below does just that. Continue reading →

Solution for: Value of type ‘System.Web.UI.HtmlControls.HtmlGenericControl’ cannot be converted to ‘System.Web.UI.HtmlControls.HtmlTableRow’ error

If you’re trying to compile an ASP.NET project/website in Visual studio 2012 or 2010 and getting error:

Value of type ‘System.Web.UI.HtmlControls.HtmlGenericControl’ cannot be converted to ‘System.Web.UI.HtmlControls.HtmlTableRow’

chances are you have an HTML table in your ASPX markup with runat="server" attribute set and <tbody> or <thead> tags present. Remove <tbody> and <thead> tags and the error should go away.

WebDataTree: Use custom images for Expand/Collapse

Infragistics WebDataTree control offers variety of styles via supplied StyleSets and each StyleSet has its own Expand/Collapse images for tree branches. Unfortunately the control doesn’t offer built-in way to use your own expand/collapse images, to achieve that you need to replace respective images in the StyleSet currently used by the tree.

But if you’re reluctant to go this way for whatever reason (you’re using your own style or don’t want to change canonical Infragistics style) there’s another way – purely client-side JavaScript.

Note: The method below assumes that all the levels the tree are fully rendered on the client. If you’re employing load-on-demand, the method will require some adjustments.

Place the code below in Tree client-side Init event:

01function xwdTree_Init(sender, eventArgs) {
02   /// <summary>
03   /// Fires when tree is initialized
04   /// </summary>
05 
06   //{******* Replacing Expand/Collapse images in the tree with custom ones
07 
08   // Looping thru images in the tree itself
09   var aTreeImages = sender.get_element().getElementsByTagName('img');
10    
11   for (I = 0; I < aTreeImages.length; I++) {
12      if (aTreeImages[I].src.indexOf('Plus') != -1) aTreeImages[I].src = 'images/my_expand.png'
13      else if (aTreeImages[I].src.indexOf('Minus') != -1) aTreeImages[I].src = 'images/my_collapse.png'
14   }
15 
16   // Looping thru images in hidden div used for replacement after click
17   var aTreeActionImages = $get(sender.get_id() + '_Images').getElementsByTagName('img');
18    
19   for (I = 0; I < aTreeActionImages.length; I++) {
20      if (aTreeActionImages[I].src.indexOf('Plus') != -1) aTreeActionImages[I].src = 'images/my_expand.png'
21      else if (aTreeActionImages[I].src.indexOf('Minus') != -1) aTreeActionImages[I].src = 'images/my_collapse.png'
22   }
23 
24   //******* Replacing Expand/Collapse images in the tree with custom ones }
25         
26}

Take a look at Lines 8-14. This code locates Tree control and its respective DOM element. Then it loops thru all the images inside. If it’s an “expand” image (has the word “plus” in its name) – we replace it with our custom expand image. If a tree node already rendered expanded – the code will locate “collapse” image (which has the word “minus” in its name).

This is all good and well for currently rendered nodes. But when you start expand and collapse nodes – images are replaced dynamically (“expand” becomes “collapse” when node is expanded and vice-versa) by Infragistics code. If you only execute code in Lines 8-14 and then expand or collapse tree nodes – your images will get replaced with Infragistics original ones from their secret repository.

Fortunately that secret repository is a plain hidden DIV with the ID “yourTreeID_Images”. Take a look at Lines 16-22. This code locates the DIV that holds replacement images and replaces them with our own similarly to Lines 8-14. After it ran, when Infragistics code needs to grab an image to replace expand/collapse one – it will get yours.

As a result Tree is rendered (both statically and dynamically) with your own beautiful images.

WHDG: Position “Group by” area anywhere on the page

WebHierarchicalDataGrid grouping feature offers handy “Group By” area – a place where columns can be dragged to for grouping. It has one limitation though: by default it can be positioned only on top or the bottom of the grid. But what if you want to place it elsewhere? For example you have a dedicated navigation part of your page where you want to display grouped columns.

DOM to the rescue. As I mentioned in my previous post Group By area is a DIV that can be located by its CSS class name (either assigned by you or, barring that, class of a StyleSet used by the grid control). After the area is located, it can be moved to a location of your choice, for example another DIV by standard appendChild DOM method:

01function positionGroupByArea() {
02   var aGroupAreas = document.getElementsByClassName('ighg_Office2007BlueGroupArea');
03   var oDivActionControls = $get('xdivNavigation');
04 
05   if (aGroupAreas.length > 1) {
06      oDivActionControls.removeChild(aGroupAreas[0]);
07      oDivActionControls.appendChild(aGroupAreas[1])
08   } else {
09      oDivActionControls.appendChild(aGroupAreas[0])
10   }
11}

Lines 2-3 Locate Group By area and target DIV respectfully. Note Line 5: like nature abhors a vacuum – WHDG abhors Group By area missing from its default place, if it is missing – grid will try to recreate it. If this happens you will have 2 Group By areas. If code on Line 5 detects this situation it removes old area and re-adds new one. Otherwise it simple moves original area.

You will have to call this code on initial grid load and after every grid operation (sorting, paging etc.) since grid will try to recreate Group By at the old place. Also, if the grid feels jumpy during this move – hide Group By area initially via it’s CSS class by setting display:none and make it visible again after the move.

Overall effect is quite seamless

WHDG: Give Grouped columns correct captions

If you work with Infragistics WebHierarchicalDataGrid and try to use its grouping features, you may notice that it uses grid column keys instead of column header’s captions to name items in “Group By” area.

To work around this limitation, let’s take a look at how Grouped By area is rendered:

Group By Area in WebHierarchicalDataGrid

Basically a container DIV holds a bunch of SPANs representing grouped columns. Both DIV and SPAN can be located by their CSS class (your own, if it’s assigned or Infragistics StyleSet class name, used by the grid control). Knowing the location of the SPANs we can loop thru them altering their text:

01function renameColumnsInGroupByArea() {
02 
03   //locating GroupBy area DIV
04   var oGroupArea = document.getElementsByClassName('ighg_IGGroupArea')[0];
05 
06   //locating GroupedColumn SPANs
07   var aGroupedColumns = oGroupArea.getElementsByClassName('ighg_IGGroupedColumn');
08 
09   // looping thru SPANS with grouped columns, replacing their text
10   for (var I = 0; I < aGroupedColumns.length; I++) {
11      aGroupedColumns[I].firstChild.nodeValue = // put your new value here;
12   }
13}

One way of using this function is generate a JavaScript associative array (ColumnData['ColumnKey'] = 'Column Caption') in ASP.NET server side code. Armed with such array Line 11 in the previous code could be simple

11aGroupedColumns[I].firstChild.nodeValue = ColumnData[aGroupedColumns[I].firstChild.nodeValue]