2011-12-17

Innocent by Law, Guilty by State Farm

Several months ago, I was involved in a traffic accident. The police officer who arrived on the scene took statements from three witnesses and the other driver before approaching me with a ticket in his hand charging me with "careless driving".

A few things annoyed me about the charge. For one thing, the term "careless driving" is really broad. It doesn't really tell you what you did wrong, just that you didn't do something right. For another, I believed I was following the laws and acting not only according to what I believe was correct (especially with reference to what the Colorado Driver's Handbook says to do at a malfunctioning traffic light), but with how other cars present at the intersection at the time were behaving. Also, the fact that the cop issued the ticket without getting my view, but only that of the other driver and some witnesses, made me feel like the decision was obnoxiously one-sided. Finally, the fact that the officer's report stated the other driver was being cautious didn't fit the facts that, I felt, were obvious.

I was determined to fight what I felt was an unfair assessment. And after finding out how much it would cost to obtain a lawyer (from the one firm that found it worthwhile to actually return my call), I decided I could only afford to fight it if I fought it on my own.

To make a very long story short, the judge agreed with me, that I did take into account the situation (the malfunctioning traffic light, the large number of cars stopped at this light in all directions). One of the witnesses was key in this decision, as she happened to be behind me at the time of the accident, and she testified that I did in fact stop for plenty of time to analyze the situation before entering the intersection. It also sounded like the was about to say the other driver was at fault for entering against a flashing yellow when there was a car already in the intersection (which I was able to prove I had first, by a large margin), before she interrupted herself and gave her ruling, that the prosecution failed to prove my guilt. So, against the odds of representing myself in court, I prevailed.

With that ruling, I thought it would be prudent to contact State Farm and let them know that not only was I found not at fault, but a competent lawyer could likely take this case and go after the other driver's insurance for the loss — hey, if an incompetent fool like myself could win the case, imagine what someone with appropriate skill could do. Boy, was I ever in for a surprise. When I was connected to the agent in charge of processing my claim, and I explained the situation, she told me she didn't think they had a case. And then this State Farm agent proceeded to tell me why: because the other driver had the right of way, she had no obligation to watch for traffic in the intersection because I should not have been there; basically all the arguments the prosecution made at my trial, that were ultimately rejected by the judge. When she mentioned details that were just wrong (like the other driver having a regular yellow light and I ran a red light) and I tried to correct her, she accused me of changing my story. (I don't know if, in the heat of the moment when I first reported the accident, I got some details wrong; but the condition of the traffic light was a fact clearly spelled out in the police report for crying out loud.) She even went so far as to claim that there was no difference between a flashing yellow light and a green light! I was in shock.

I suppose ultimately it's their decision to pursue the case or not, but to just dismiss the results of a trial and accuse me of guilt after I had been found not guilty, does not sit well with me. I believe it is time for me to find a new insurance agent, one that does not stubbornly hold to an assumption of my guilt even after being found not guilty in a court of law, like State Farm has done.

2011-11-21

Hitting the wall

Looks like it might actually happen. With my nephew staying with us while he goes to college, his additional gaming and Netflix bandwidth has pushed our internet usage up over 210MB this month, with still a third of a month to go.

To get comparable internet speeds from Comcast Business (which is not, reportedly, subject to bandwidth caps), I would have to pay triple my current monthly internet bill. I was unable to get comparable numbers from CenturyLink Business (the only other viable internet service provider in my area) without providing my home address and phone number.

My nephew is off spending the Thanksgiving holiday with his immediate family, and I've told my wife we need to use our shiny plastic (and completely unrestricted) discs for home entertainment, so we have a chance of making it through the month under the cap; but now, it's clear that the bandwidth cap is making a clear impact on our internet usage.

It's interesting to note that Microsoft has announced that they are going to be bringing even more streaming video content to the Xbox in the coming months, including (but not limited to) YouTube, UFC shows, and various cable providers' on-demand content (which would be delivered over capped internet, rather than the limitless pipe that carries regular cable content).

Internet use and services are going up (and Comcast even occasionally increases its speeds to deliver more of that content faster), but the cap doesn't move. How many people are going to find themselves over the cap soon? When will Comcast realize "generous" is becoming "too restrictive"? And, most importantly, when will I see a viable option that gives me reliable connection and speed, and the ability to actually use it to its potential?

2011-09-27

So soon, Firefox?

I stepped away for a cup of coffee, and when I came back, there's a new version of Firefox.

I thought my co-worker was kidding, but sure enough, when I started Firefox, it started downloading the installer for version 7.0. Out of curiosity, I went to the options panel to look at the update history. It showed Firefox 5, then Firefox 6, both listed as "security updates" — version 6 installed only last month.

Curiously, after installing version 7, the "update history" list was cleared out. A little embarassing, perhaps?

Seriously, Firefox; this is just silly.

Besides, Chrome has you beat by miles (version 14 as of this post).

2011-08-16

Firefox 6 - Major version, major pain

I was testing out my web code in Firefox today, and I got a message saying that Firefox 6 had been released. Wanting to make sure I was keeping up to date with our users, I installed the update. After restarting the browser when prompted, I noticed that it looked exactly the same. So I went online to check what's new.

Apparently, not much. Oh, there's a small list, but nothing really visible, and it's not really any faster than before. It seems that Mozilla's accelerated release schedule is nothing more than releasing what would normally be a "point release" as a major version instead.

But to what end? Chrome is on version 13; IE's current release is version 9 (with 10 available for preview); Opera is on version 11. Could this be nothing more than a way to "catch up", so "Firefox 5" doesn't sound like it's way behind the other browsers? It was speculated that Microsoft named their second console the "Xbox 360" because "Xbox 2" would sound like it was behind "Playstation 3"; this could be another example of toying with customer mindshare.

Or could it be a way to flush some of the old versions out of general support? Many companies I worked at had a policy such as, "Support the current major browser versions minus two", which today would mean "IE 7 and above, Firefox 4 and above, Chrome 11 and above, etc." — releasing a few major versions quickly would push older browsers that don't support up-and-coming standards like HTML5 out of the support window rather quickly.

Whatever the reason, there is one rather large detrimental effect. Extension authors have to certify that their code is compatible with major releases. Because Firefox just got a new major version number, all of my extensions were marked as "incompatible" and disabled, and that way they will remain until their authors update their xpi packages to mark them as compatible with this new major version. Essential debugging tools like FireQuery, HttpFox, even the Java console are among those that are off-limits until they are updated. Even the extension for the corporate virus scanner is disabled, as is Skype's "click to call" extension (which wasn't marked compatible with Firefox 5 either; not that I use it myself, but I have to be able to confirm that, for customers who do use it, its phone number reformatting doesn't make the page unusable).

Firefox, you used to be cool. I didn't mind inviting you over and letting you crash on my couch. But now you've stolen the food from my cupboards, gotten fat and lazy, started leaving your dirty clothes lying all over the house; and you're wild parties broke my antique table lamp without so much as a "sorry" from you. I grow tired of having to clean up after your mess. IE used to be where you are now, but at least he's been working on cleaning up his act.

2011-08-12

Does courtesy fade with age?

I'm sitting on the train, headphones on, playing a game on my Windows Phone, as normal, when I hear a demanding voice from over my shoulder say, "Do you see that sign!?"

My brain attempts to disengage from my virtual world and process this. Usually, when a voice like that is heard, it's from the train police, asking to see passengers' tickets. But wait, that's not what he asked for. Do I see the sign? There are a few posted signs asking for certain behavior. I'm not playing loud music, I'm not eating or drinking, my feet aren't on the seat… Ok, something's wrong, and I guess I need to turn to this mysterious voice and figure out what it is.

I turn and see an elderly man, looking a bit angry, glaring at me, with his finger pointed at the sign that indicates priority seating for elderly or disabled passengers and asking to comply with all requests to vacate the seat for a disabled passenger.

So, I figured I'd give him the opportunity to request my seat. "Do you want to sit down?"

"DO YOU SEE THAT SIGN?" he yells again.

The people in the rear-facing seat across from me offer their seat and practically stumble over themselves to get up and move to one of the several other vacant seats on the train. "No, I can't sit backwards," the old guy complains after them.

"All right," I said, giving up on any chance of civility with this curmudgeon. I stand up, turn around, and sit in the hastily-vacated rear-facing seat.

The old fart then sits down, pulls out a 12oz Coke bottle, and starts drinking it, right under the sign that says "No Eating or Drinking".

I guess he didn't see the sign.

2011-08-09

RJ11 to RJ14 - easier than I thought

I've just switched from Comcast's VoIP to a third party VoIP provider (the company formerly known as VoIP.com, now a part of Phone Power). When I got my box (slightly smaller than a 3"x5" card and just thick enough to have phone and ethernet jacks on its back), I noticed it had Phone Line 1 and Line 2 as two separate RJ11 jacks. Why they didn't just use a single RJ14 jack is beyond me. It's not like A splitter that takes an RJ14 two-line jack and converts it to two RJ11 one-line jacksline splitters are that expensive — they retail for a couple bucks and probably cost half that wholesale. But where splitters are apparently plentiful, a combiner, something that takes two separate single-line jacks and makes a single two-line jack out of it, is impossible to find in a store and even extremely rare online. So, how was I supposed to take these two RJ11 outputs and plug them into the single RJ14 jack that serves as input for my house wiring?

I found instructions for rewiring a CAT-5 ethernet cable to do the job, but I didn't want to have to buy a crimping tool to form the plugs, nor did I feel comfortable splicing it into existing phone cords (the last time I tried something like that, it ended badly). But then I had a sudden revelation.

You see, there's really nothing special about telephone cord accessories. A splitter just takes the pins in a given plug and wires them to the appropriate pins in the right jacks. In the splitter pictured above, the first pair on the RJ14 plug is wired to both the first (and only) pair on the L1 jack and the first pair on the L1+L2 jack. The second pair on the RJ14 plug is wired to the first (and only) pair on the L2 jack and the second pair on the L1+L2 jack. All those associated pins are interconnected; there is no special circuitry that separates the connections (i.e., nothing keeping the L1 jack and the first pair on L1+L2 from talking to each other) — that's why these things are so cheap. Further, wires are bi-directional. If you apply an input voltage to one end, it will carry it to the other end; conversely, if you apply an input voltage to the other end, it will carry it back to the first end. Wires don't care which end is labeled "input" and "output".

And neither does a splitter. With all the pins interconnected by wires, you can just as easily send a signal input into L1 and L2, and get the combined output in both the L1+L2 and the RJ14 plug on the back side.

So that's what I did. I connected the VoIP adapter's Phone 1 and Phone 2 jacks to the L1 and L2 jacks of a splitter, and connected the L1+L2 jack to my house wiring input jack. (I could've used the RJ14 plug on the splitter itself instead of another phone wire, but there wasn't enough room around the input jack on the patch panel for a splitter to fit.)

So why is this so important that I bothered writing a blog post about it? Because, as I was searching out a solution to this problem (which apparently plagues users of Vonage equipment as well), I couldn't find this very simple solution. Maybe someone else will stumble upon this blog post as they search for their own solution and discover just how easy it is.

2011-08-02

Firefox, jQuery, and event binding, revisited

While I had decided for myself that I didn't want to support Firefox anymore, the company that signs my paychecks respectfully disagreed. Because my project is an internal admin tool, we were able to tell our user base not to use Firefox for the time being and assign the bug a relatively low priority — but, it was something that should be revisited and fixed. Having completed my tasks well ahead of schedule, the time was at hand.

The bug had to do with Firefox failing to fire off a jQuery click event handler. I had long since installed the Firebug extension, but all it could tell me for certain was that the event handler code was not being called. I was fortunate, in my searching, to find another extension, FireQuery, which extends Firebug by adding jQuery information to the debug panels. Installing that and viewing the HTML, I could see that the jQuery click event handler simply wasn't there on the switches that weren't working.

Using the development version of jQuery, I stepped through the code that attaches the event handler, and I could find no difference in code execution between the switches that worked and the ones that didn't (unsurprising, since I attached to all of them at once).

The solution, surprisingly, came about when I started mucking around with elements and styles, substituting divs for lis in a desperate attempt to find the cause. To make a long story short, it was the fact that, later in the code, I called a jQuery plugin called "text-overflow" that emulated the text-overflow: ellipsis stylesheet directive that every browser but Firefox supports.

The problem with the code is that, in order to emulate the feature, the plugin creates a cloned copy of the node to "ellipsify" and progressively removes characters until the width of the cloned node fits in the desired width of the original. Then, it sets the contents to be the new text, and destroys the copy. Unfortunately, there are a couple side effects:

  1. If no truncation happens, the contained elements lose their event bindings, since they end up not being the original elements, but copies.
  2. If truncation does happen, when the contents are replaced with the new text, any other elements contained therein (i.e. hidden form fields holding data for a form post) are wiped out.

The first problem might have been overcome by using jQuery's own clone method which clones nodes and any events associated to them. (This was added after the plugin was written, so I don't fault the author for oversight). To be safe, though, I changed the class on the switches' containers and excluded them from my .ellipsis() call. That successfully kept the slider click event handlers from disappearing.

The second problem was the source of another bug, where a jQuery function attempting to look up values from hidden form fields was failing to find the data on elements that were truncated by the text-overflow plugin. I moved the hidden form fields outside of the elements targeted by the function call, and that, too, was magically fixed.

Internet Explorer has a bad (and well-deserved) reputation for needing special development time to do the same thing that other browsers do (although, in my experience, a lot of this would be unnecessary if it weren't for a requirement, usually from an upper-level executive or, worse, marketing, mandating pixel-perfect replication across all browsers), but I've found lately that the pendulum has swung far the other way to deal with the quirks in Firefox.

2011-07-24

Problem with your phone? We'll call you...

Years ago, I was somewhat amused when we had a problem with our internet, and when I called Comcast service, the automated message suggested reporting the problem on their website.

Last week, when our internet went out and took the Comcast VOIP service with it, we had to call Comcast customer service from our cell phone and set up service. The customer service rep asked if there was a phone number by which we could be contacted (since our home phone was out), and we gave them the cell number.

Today, I finally got around to checking the messages on Comcast voice mail that came in while our service was out. The message left was from Comcast customer service, telling us we had an appointment set up.

insert eye roll here

2011-07-19

Why is the internet not a utility?

I've been following the plight of Ozymandias and his issues with Comcast cutting off his service with great interest, since I've been concerned with their bandwidth caps since they announced them about three years ago. He has argued that, because of how important internet usage has become in this day and age, it should be considered a "utility" instead of a generic service. I don't disagree, and my own recent experiences helped bring this point home.

Recently, my mother had issues with her Comcast phone service, where she had not had a dial tone for a few days. Having a busy work schedule and some remodeling done on her house, she didn't get around to calling Comcast about it for some time. When she finally called Comcast to get it resolved, the tech on the phone determined the cable modem was working correctly, but it was reporting a phone off the hook somewhere in the house. Because she had no phone service, however, the tech said she would schedule a service call at the first opportunity — which, due to severe storms in the area, would be the next day; notable since that next day was a Sunday.

Note that this was not Comcast's fault. I happened to be over to help with some other items, and as I was there, I noticed that one of her contractors had inexplicably taken a network cord from a hub in the office and plugged it into a phone jack. Once I pulled that plug, dial tone was restored.

Over the past couple days, we've been having issues with our internet going up and down intermittently. Yesterday, it was bad enough that our phone service went with it, too. (It could easily have been going up and down all along as well, but this was the first we'd actually noticed it.) My wife called Comcast, and they said that because we weren't getting a dial tone, they would send a tech out that day — which they did.

The reason I find this interesting is, in both cases, Comcast sounded like they were more motivated to act not because the internet service was down (in my mother's case, her internet service was fine), but because there was no phone service. I did a very quick internet search, and although I couldn't find an official statement, I found several allusions to law that require a dial tone be available for everyone for 911 service at a minimum. If this is true, it would certainly explain their motivation in getting service restored.

But it does bring up a few interesting questions. First, if I had my VOIP phone service through some other provider, such that my phone service depended on my internet even though Comcast itself was not providing that phone service, would they be likewise motivated and/or obligated to get my internet service restored in the event of an outage? Although my cynical side believes no simply on the grounds that they're not responsible for that service, I think the fact that any competing VOIP provider's traffic is subject to the bandwidth cap whose penalty is a disconnection of service, is evidence that they would not, in fact, take a loss of non-Comcast VOIP as reason to expedite internet service repair.

Second, if you get your VOIP through Comcast, does this mean they can't eliminate your service completely if you go over their bandwidth cap? This one, I'm a little uncertain about. I don't know if it's possible to get Comcast phone without Comcast internet. Maybe you can, and maybe the 1 year ban on Comcast service only applies to the internet service and not phone (or TV for that matter). I don't know about this one.

Third, and most important I think: if telephone service is a utility, and its function is directly dependent on internet service (as is the case of VOIP), how is internet service not a utility? I suppose one could argue that service could still be provided by the copper wires still in place left by US West Qwest CenturyLink, but I'm not so sure; not only are those lines disconnected (as evidenced by my complete loss of dial tone when Comcast VOIP was down), but it wouldn't explain why Comcast seems so concerned when their dial tone is not being provided. By failing or refusing to provide the service that telephone depends on (when the internet is down, or Comcast cuts you off for so-called "excessive use"), Comcast effectively cuts off your access to a utility. It would seem that they should either be obligated to provide your service, or re-connect your copper lines to get at least emergency dial tone service restored as soon as possible.


Now, a hype and gripe about Comcast service. First, the gripe: when the tech came out to fix our service, the modem was getting an inconsistent signal, so he decided to replace the (leased) modem with a newer model. The new model, an SMC model SMCD3GNV, had some extra features, like a built-in router with four gigabit ethernet ports and a WiFi access point. While this might be convenient for some, it was not for me. I already had a Linux server acting as my home router, and I had my own WiFi access points configured for my home network. I did not want an extra level of NAT or another WiFi network, even if I never used it. Unfortunately, the ability to either disable NAT or turn off WiFi were not available in the modem's UI. Doing a little internet searching, I found that this was a common complaint. While I was able to set up a serviceable alternative by putting my server in the router's DMZ, I still was not happy with the double-NAT, and I definitely was not comfortable with the enabled WiFi.

Now, the hype. The Comcast tech, Justin, promised he would ask his more experienced techs about this the next morning and find a solution for me. In the meantime, my internet searches pointed to the fact that some of these "advanced" configurations could (only) be done by Comcast remotely, and contacting the Twitter account @ComcastCares can get the WiFi turned off. I also came across a recommendation to contact an admin on the Comcast forums. I did both. As I was composing my message to the forum admin, I got a reply from someone monitoring @ComcastCares, who, after getting my service phone number, promised to have a tech take care of it in the morning.

The next morning, I saw a reply from @ComcastCares saying they had turned the WiFi off. I then saw a slightly later reply from the forum admin, saying the WiFi had already been turned off, but he put the modem into bridging mode, and that I should be able to control everything from my own router again. Since I was already at work, I had to call my wife and walk her through the steps to reset networking on the Linux server, and as soon as she did and networking came back up, everything was back to normal.

I called Justin (who had left me his cell number) to let him know we were ok, and he thanked me for the call, as he had talked with techs in his office about the issue (and their frustrations at not being able to change these settings themselves), and was preparing to make another trip out to simply replace that modem with one that didn't try to do everything for me.

Kind of a crappy situation brought on by Comcast's own choice in modems and firmware with inaccessible configuration settings, but the three people involved were willing and able to work through it to get me what I wanted.

2011-07-16

My $6000 mistake

After my 2004 Prius was totaled, I had one prevaling thought when it came to transportation: I needed to replace the car. As such, I went looking for another Prius, loaded, with the JBL sound system, bluetooth, and GPS navigation. My wife strongly encouraged me to look for a later model, as it would be better covered by warranties and have less of a chance of something going wrong. Because rising gas prices have been driving up the demand for hybrids, and because the recent tsunami in Japan was hindering supply, my choices were rather limited. I found a couple dealers with Priuses, and it came down to a 2005 base model and a 2009 loaded touring edition. The '05, without any options, felt too much like "just a car"; while the loaded '09 offered all the bells and whistles I was used to, plus had newer components which made for a better warranty and piece of mind.

The cost, however, was really tough to swallow. After the check from my insurance company, I ended up owing over $13k, which I financed with the intention of pulling money from various accounts and paying off as soon as possible.

After a couple weeks of driving, however, I noticed the strong new car scent had given way to a strong cigarette smell. Not a smoker myself, the smell was beyond irritating — and the fact that I take my kids to school in the morning made me more concerned about the environment I was using for transportation. This and the out-of-pocket expense weighed heavily on me for the following weeks.

When fabric cleaners and deodorizers failed to improve things, I came to the conclusion that I had made a terrible mistake.

I knew I would take a small bath on the cost of the car compared to its trade-in value, so I began the search for an inexpensive and economical car (and, to satisfy my wife's concerns about warranties, a relatively late-model with a good warranty). My search led me to a used 2010 Chevy Cobalt previously used as a rental car, which I couldn't beat for the mileage/year/economy at that price.

It's a good car, drives well, is comfortable, and, very imporantly, does not have a cigarette smell. It doesn't have the bells and whistles of the Prius, but those are features I didn't really need — my phone can serve as a GPS well enough (and one that's continually up-to-date), and plugging the phone's headphone jack into the stereo's auxillary input (which I do out of habit anyway, as I listen to podcasts or audiobooks almost exclusively) is a more-than-acceptable substitute for a wireless handsfree bluetooth connection. Plus, the Cobalt has features that even the 2009 Prius didn't: a tire pressure and oil life monitor, daytime running lights, automatic headlights (seriously, for all the bells and whistles, how can the Prius not have automatic headlights?), and doors that automatically lock when the car is in gear. Plus, the Cobalt does not attempt to control everything through a single LCD touchscreen. (It seems cool, but it ends up being far more distracting and annoying when you have to switch screen modes just to adjust the temperature or see what radio station is playing — which might be why the 2010 model Prius went back to discrete radio and climate control panels.)

The car cost me just about the exact price of my late Prius, but after figuring in the loss on trade-in, taxes, and two dealer delivery charges, I estimate I lost somewhere in the ballpark of $6000 on the deal. But it was a huge weight off of my mind to be able to pull that money together, write a single check, and buy the car outright without any financing whatsoever.

The cost all comes down to a simple mistake. When I went to get a replacement car, I focused on replacing my old car with a near-equal match. If I had instead focused on what I need instead of what I want, I could have avoided the extra cost — or taken that extra money and considered more expensive but more economical or featured cars.

Do I miss my old Prius? Absolutely. It was my fun car, and I enjoyed it for the nearly seven years I was privileged to drive it. I'm glad I was able to get my fun car. But what I didn't initially accept was, it was time to move on. Now that I've accepted that, I feel much better about my old car's replacement, and I can move ahead.

2011-07-11

The Day Comcast's Data Cap Policy Killed My Internet for 1 Year

I've long complained about internet data caps. While I haven't yet exceeded Comcast's 250GB cap, I noticed a blog post retweeted across Twitter with a real-life anecdote of one person's experience getting cut off from Comcast internet service for doing just that. link

In his case, service was likely* due to an increase in uploading large files to cloud services that are becoming more and more popular. My own usage is still primarily downloading data (above 95% of my monthly use is downloading); but as we have new Windows 7 smartphones that automatically upload pictures to the Skydrive service, and the upcoming Mango update promises to do the same with HD videos as well, I can see uploading rates increasing for me as well.

*"Likely", because Comcast does not provide details about data usage, even to show how much is up- vs. downloading.

I do find it odd that, instead of charging for overages and milking more money out of their customers, they are throwing customers away. I imagine there are users who would much rather pay extra than being cut off completely. And yet, they are effectively reducing their customer base, which will only shrink more as more people go over the cap by daring to use all these internet services other companies are so keen in innovating, which will only happen more often when Comcast refuses to increase the cap proportionally to how many services are available, the increase in bandwidth existing services use (i.e. more HD video available for streaming), and the increasing speed Comcast itself is providing to get to their arbitrary cap faster.

2011-06-24

You have failed me for the last time, Firefox

In my last post, I mentioned that Firefox was causing issues with my custom on/off control. I solved that problem, but now I have a new one.

When the on/off control renders, it renders with an onclick attribute that calls the function that moves the slider and sets the value of the control in a hidden field. If I want to add any more actions to the control (a common one is to change its color when the value is changed), I use the jQuery .click() function to attach a JavaScript function to its click event.

On a page with several on/off controls, I have bound click events to change their color and enable a save button on change. It's worked every other time I've done this, and it works in this case as well — except for Firefox. For some reason, the last group of controls (which happen to be rendered in an ASP Repeater) do not fire the jQuery click event. What's worse, even though clicking on them does in fact slide the button from one value to the other, it apparently is not setting the hidden form field to change the value — and all that code is being run from JavaScript called in the onclick attribute.

I have found numerous references to jQuery click events not being fired in Firefox, but none of the solutions will help me here. I can't move my code into the onclick event, since I need to register the click handlers from different places; and nothing is apparently wrong with the code as it works as-is not only in other browsers, but in the same browser elsewhere on the same page.

I have spent the better part of a day trying to find where this click event is being "swallowed", and why this code that works perfectly on IE, Opera, and Chrome is not functioning in Firefox. I'm done. It's an internal tool, and we have the luxury to mandate our users' browser choice to some degree.

Firefox, I don't know what your problem is, but I am tired of wasting days of development time trying to find solutions for problems that only exist in Firefox. You are the weakest link. Goodbye.

2011-06-17

Firefox, jQuery, and RegisterStartupScript

I have created a control for the web project I'm working on at work. It's an On/Off slider control, very similar in appearance to the one used by iOS, that uses jQuery to animate the sliding switch on click. Over time, I've added more features and support to it as requirements have come in — its message text is configurable, it can raise its own postback events, and it even works in AJAX postbacks. Someday, I might have to publish the code (maybe when I get rid of its dependence on images and make it size-adjustable as well).

When the control is first rendered, the slider switch is centered halfway between "On" and "Off", and I call Page.ClientScript.RegisterClientScriptBlock that calls that control's "set" function to slide the switch to the correct position. (The control's client click event sets the control's value property and calls this same function to slide the switch back and forth on demand.) It works great on IE, Opera, Chrome… but not Firefox. It would render the first few correctly, but somewhere halfway down the page (depending on how many switches were involved — my particular example page had 10), the slider switches would remain in their centered, "unset" state.

This is getting to be a theme.

I found that, if I added an alert() call before every SetSlider call, then every switch would be set, except the last one. If I reversed the calls so the alert() came second, all the switches would be set.

I was able to solve the problem by wrapping each SetSlider call in a jQuery ready function (i.e., $(function(){ … });). Because the control is self-contained and has no knowledge of other sliders on the page, that's a lot of ready functions; but jQuery seems to handle it without incident. The only other thing I had to deal with was to ensure any startup functions I had to alter the switches' states must come after those SetSlider functions — in my case, moving the code to the page's PreRenderComplete event (because, according to MSDN, the controls' PreRender events, where I registered the SetSlider methods, get called after the page's).

It works, but it still took a couple hours out of my day to find it and then fix it. Thanks again, Firefox.

2011-05-26

When it rains, it pours

You know, it would be nice if manure didn't hit the fan all at one time… for once.

A week ago today, my car was hit in an accident, which the cop blamed me for (still building my case against this for my court date in 2 months). Sunday, I tried helping my wife cook by slicing carrots on the mandoline, when my thumb must've slipped, and I cut about a quarter inch into the end of my thumb. Tuesday, I got a call from insurance telling me they're totaling the car, putting me in the difficult decision of fixing it and never expecting to resell it, or shelling out around ten grand on top of my car's value to replace it (since, with the earthquake in Japan and rising fuel costs, Priuses are getting hard to find). Wednesday, my wife called me to tell me she got a ticket for making a right turn on red where allegedly there is a sign saying not to do that. That night, at some point between picking my mother up from her house and going to a Toyota dealership to look for used Priuses before picking her truck up from the shop, my stereo bluetooth headset disappeared (a search of every place I had been since I last remember having it turned up nothing).

At least, as before, God gave me an umbrella. I was uninjured in the accident. I seem to be getting all the documentation I need to argue my case. We actually have money in savings (barely) to replace the car. The amount they offered me for the car is actually quite fair. The cut on my thumb was clean and somewhere between a quarter and a third through, shallow enough that it did not require any "reattachment". My wife's traffic ticket, if paid promptly, will only result in a single point against her and not affect insurance. I "get" to upgrade my car, not to mention change its color (I always hated the color of the one I've been driving for the past 6½ years), and I'm getting more for my car than the trade-in value the last dealer offered me.

It still would be nice if all the bad stuff would stop now.

2011-05-19

Maybe treating it as a four-way stop is best

Long ago, I wrote about my annoyance at people who get the rules about malfunctioning lights backwards. I rather wish I had one of those "ignorant" people on the road today.

At the intersection leading into the train station, the lights were completely out. Four-way stop. I was going straight. As I stopped, the car next to me turning left started to go, so I did as well. Someone coming from the cross street in the far lane (on the other side of a full lane of traffic at a stop) plowed through the intersection and hit me.

As I sat in my car (the door was jammed, so I couldn't get out right away), I looked up to verify the lights were in fact dark. They were — in my direction only. The lights in the opposite direction, however, were flashing red, and the lights on the cross street, the one the other driver "plowed through", were flashing yellow.

We both acted on information we had; the street light just gave two completely different sets of information.

I made sure to point this fact out to the officer on the scene, who noted it. I do have to appear in court in a couple months to answer a charge of "careless driving" because I failed to yield to her yellow light, so I can only hope the judge will acknowledge the screwed up lights and realize I acted appropriately.

Of course, it wasn't until I was on the train in to work that I realized I should have taken pictures and video, especially of the lights in question.

2011-05-15

Want to fly? Change your plans.

So, my mother was supposed to fly out on business today. We called to see if she had made it and if there was anything she needed. What did she say?

They downsized her plane and bumped her because she did not check in the day before the flight.

The next flight available? Tomorrow, 4pm.

So any and all plans she had for today and tomorrow, including business meetings, have to be canceled or rescheduled.

Add this to other horror stories we've heard first-hand — including friends of ours who were bumped at the last minute and forced to delay their return home for a whole weekend with their two young children (did I mention that the airline had already put their luggage on the flight, so this family of four had no clothes for that weekend?) — and is it any wonder why I'd rather spend hours in a car driving to far away destinations than giving any money to this industry?

And this is before factoring things in like insane surcharges for every little thing, and your choice of rape or pornography to get through security.…

2011-05-11

My Jury Service

A month or so ago, I received a summons in the mail to report for jury duty. I let my employer know well ahead of time, and on the designated day (Friday), I reported to the county courthouse.

I show up at 8am Friday morning. I went through a security checkpoint that reminded me of the good old days of airport security, when it didn't include taking off your shoes and submitting to a physical search that would only be appropriate in an after-school special titled "Bad Touch". In the jury room (a very large room with hundreds of chairs laid out in even rows), I picked up a questionnaire and started filling it out, while Fox News displayed on two TVs in the front.

The questionnaire included a lot of personal questions, including things like "Have you or anyone in your family had an experience with a law enforcement officer recently? Was it positive or negative?" They also included the name of the person on trial and a long list of names of potential witnesses, asking if you knew or recognized anyone. It also asked if there would be any difficulty serving the length of the trial, which was expected to last eight days.

When I was last summoned, I was very upset that, as a contractor, I was only guaranteed the low legal limit of $50/day. Now, as a full-time employee, I'd get my full pay, but only for the first three days, and then I'd be at that below-minimum-wage rate. (Colorado minimum wage is currently $7.36/hour, working out to not quite $60 per day.) I'm not much happier about this.

Time passed as more jurors reported in and started filling out their questionnaires. After about an hour, the clerk addressed us, along with a judge, to thank us for our service and tell us how important jury service is. We then watched a short video about jury service, in which people shared their thoughts about service. I noticed that the testimonials included valid concerns (like "I had small children, and I worried about what I was going to do with them", "I was really busy at work and didn't know how I'd fit this in"), but then they said how good they felt doing their civic duty — without addressing any of the concerns they initially expressed. (So, what did you do with your kids, ma'am? How did you support your family making less than minimum wage, sir?)

Our questionnaires were then gathered, at which point we were given a new randomized juror number. We were then sent home, with instructions to call a certain number after 6pm to see if we were selected to return on Monday.

This seemed like an unfair inconvenience. I was unable to tell my employer if I would be at work on Monday or not until after office hours were closed. I suppose my employer wouldn't know how long I would be out anyway, and the judge and attorneys need time to go through the 150-some questionnaires, but still, it doesn't seem like the needs of the citizens are taken into account at all.

I called, and sure enough, I was selected to return on Monday. I sent an email to my employer to give them what notice I could.

On Monday, I reported at the designated 9am time (which at least gave me plenty of time to drop my kids off at school, as usual). Reporting in were the hundred or so jurors from Friday selected to return, plus another group asked to report for the first time on Monday. The Monday jurors were processed first. The clerk announced that their trial was expected to take five days. They filled out their own questionnaires, and again we watched the video, temporarily interrupting the CNN discussion of Osama Bin Laden that was playing on the TVs today. I noticed that the video stated the average trial lasts 1-3 days, and I couldn't help but wonder how many trials must last less than a day to get that average down, considering our trial was 8 and theirs was 5.

Finally, around 10:30am, we were sent up to the courtroom. There was probably at least 20 minutes spent getting everyone seated, as we were supposed to sit in order of our juror numbers in a particular configuration around the courtroom. (The judge and attorneys had seating charts, and this would ensure they knew to whom they were speaking.) Some additional jurors had been dismissed, so there were some holes in the jury box. The first of us on the benches were called up to fill in the holes. As luck would have it, I was the first in line and ended up in the jury box to start. When I was in jury selection 6 years ago, I noticed that those people in the jury box at the beginning were among the first to be dismissed, and those called to replace them rarely were; so I had good feelings about being dismissed before hitting a substantial drop in income for a few days.

Questioning began (what is known in the court as voir dire — I guess I did learn something from that jury service video). The judge started with basic questions, such as whether or not any of us knew or recognized anyone else in the courtroom — including the defendant, whom I was honestly surprised to see present. I don't remember the defendant being present the last time I went through this, and I have to wonder if any of the potential jurors felt uncomfortable answering questions in front of him.

One of the questions the judge asked every juror was if there was any hardship in serving. I mentioned that the drop in pay would make it very difficult to support my family. He did say that, if it meant falling behind in bills, he would not keep anyone there. I answered honestly that it would be difficult, but I would at least survive. (It would take dipping into savings, but it would have been possible. I could've lied and said it would've been worse, but I didn't think that would be prudent, especially since we had a lesson in church the day before that just happened to be all about honesty.)

After the judge got through everyone, the prosecuting attorney began asking questions, probing for any biases that may make judging this particular case difficult. I was asked one question directly, but then I noticed that he didn't seem that interested in me thereafter. So, after our lunch break (during which I went to Walgreens to get some Excedrin for the headache that was building up all morning), I decided to remedy this situation. Whenever the attorney asked a general question ("Does anyone else feel like this?"), I raised my hand. Well, any time I could come up with something to say, anyway. I answered honestly, but I tried to answer a lot, so when it came time for the attorneys to dismiss jurors, I was on their mind.

When it came time for the dismissals (peremptory challenges — something I don't think was in the video but was explained at length by the judge), I ended up being dismissed by the defense attorney. I think about five people were dismissed before me, sent downstairs to collect their certificates of service (among other things, used as proof to employers of time served). They must have been discussing who they thought would remain on the jury, because when I showed up, there was a collective look of astonishment on their faces as one said, "You? No way, I thought you were a shoe-in!"

I'm not sure if I said anything in particular that got me dismissed. There was a question asked by the defense attorney along the lines of, "Could someone have a legitimate reason to lie to the police? If they do, does that mean they must be guilty of something?" I answered (honestly) that I wouldn't think they were "guilty", but it would color my perception of their testimony — if they lied to the police about one thing, what else might they lie about? While I can't know the specifics of the case, he must've had a reason for asking; I would guess that either the defendant or one of his witnesses might've lied to the police during the course of the crime/investigation, and my opinion might lead me to discount their integrity. Or maybe it was just my visibility in questioning, or a combination of both. Whatever the case, I wasn't too upset to not have to worry about supporting my family for the next week and a half.

In a way, I'm kind of disappointed I didn't get to hear the case. The charges were read to us, so I know it had to do with domestic violence and second degree murder. I would've been much more willing to serve in this very important process, too, if they didn't make it so blasted difficult to take care of your regular life in order to do this service.

2011-04-28

4096 bytes is more than enough for everybody

Ever try to make an AJAX call from JavaScript, only to find out that your data is truncated at around the 4k mark? If so, you must be using Firefox 3. Although there is a workaround described here, it means you have to write extra, special code to check for a custom property to really get all the data.

You can test this problem using this QuirksMode page. The page notes other limits on Opera and the Macintosh version of IE, but on the current (v11) version of Opera, I was unable to duplicate it. I also don't have a Mac, so I couldn't verify it there, either. Only Firefox fails to copy the whole text block.

Apparently, this has been fixed in Firefox 4, but that's small consolation when you're tasked with supporting what people are actually using.

2011-04-21

Let me url that for you

Today's programming annoyance is brought to you by the .Net Framework.

If you add a style to an HtmlControl in code — for example, the list-style-image to a list item element — you might use something like the following:

control.Style.Add("list-style-image","none");

You might expect that the style element would contain "list-style-image: none;".

Apparently, you'd be wrong. The tag generated looks like this:

<li style="list-style-image: url(none);">

There is a workaround, but it depends on you being able to specify all list-style properties at once. Using the shortcut, this code:

control.Style.Add("list-style","none none");

will generate the expected HTML, unmangled (and set both the list-style-type and list-style-image properties).

Having list-style-image: url(none) may not make your page look broken, but it will result in a browser request for the file "none" and result in some excessive 404 logs on your server.

If you had an actual image and set it with control.Style.Add("list-style-image","url(imageName.jpg)"); the style would not suddenly get "double-wrapped" with the url() function. By wrapping your value with url() "just in case" you forgot it, Microsoft tries to protect you from yourself, and ultimately causes more headaches by preventing you from setting the style to a perfectly valid value.

2011-04-01

Hollywood's War on Christianity Now Using Aliens

I recently saw the movie Paul. It's a comedy about two young adult male British nerds who are realizing a longtime dream of coming to America to visit Comic-Con, followed by taking a tour of famous UFO sites in the US (like Roswell and Area 51). As they're traveling, they witness a car suddenly veer off the desert highway and crash. When they stop to investigate, they meet Paul, a rather foul-mouthed alien who has escaped government capture and is trying to get home.

The movie is pretty funny, with lots of nerd references — from Star Wars (the cantina theme being played in a trucker bar, a guy shooting out his CB radio as he murmurs "Boring conversation anyway") to Close Encounters (a spaceship landing at Devil's Tower, a large firework that plays the five-note theme) and Aliens (a character quotes "Get away from her, you b---", a line spoken by Sigourney Weaver in Aliens, to Sigourney Weaver's character in Paul). It is also full of bathroom and locker room humor that's so popular with the kids these days.

The part where it starts to dig at religion comes when, soon after meeting Paul, the Brits decide to pull their RV into an RV park. They are greeted by a young blonde girl, Ruth, who comments on how she'd like to travel someday but has never gone anywhere in her life yet. The conversation is interrupted by a gruff voice calling her back to the office/house for "PRAYERS!"

The next day, Ruth visits the Brits' RV, and she starts to reveal herself as what I like to call a "Strict Creationist" — someone who believes in the literal word of the Bible, that the Earth was created 4,000 years ago in a process that spanned six days, and that there is no possible way there could be "alien life" elsewhere, as we were all created in God's image. Paul, somewhat put out by this, emerges from his hiding place in the bathroom. After fainting (something of a running gag in the film), she awakens and tries to convince herself it was her imagination, until she sees Paul again. She then goes into a fit of hysterics.

Up to this point, it's not so bad. Hollywood loves its stereotypes, especially taken to extremes. An openly gay character will be extremely flamboyant; a character born in the Lone Star State will almost invariably be wearing a cowboy hat and calling every female "Darlin'". It's almost a foregone conclusion that an openly Christian character will end up being extreme fundamentalist.

To stop her fit and from denying his very existence, Paul does this "alien thing" where he gives Ruth all of his knowledge and experience, including memories of his galactic travels.

Here's where it starts to turn south.

Filled with this knowledge, Ruth decides that all of what she believed is wrong, decides there is no God, and she is free to swear and fornicate. She then spends the rest of the movie trying to swear (in a manner not completely unlike Captain Kirk trying to "fit in" to contemporary Earth in Star Trek IV). Paul does make a token effort at trying to settle her down and say his experience doesn't necessarily preclude the existence of God, but his comment is ignored.

Going from one extreme to another isn't completely out of place in a low-brow Hollywood comedy. But the telling scene comes at the end, when, in a very sober moment, Paul says he's sorry for destroying Ruth's faith. Her reply? "You didn't destroy me; you freed me."

That actually made me a little angry. This was not a comedic scene; it was said with all seriousness, like it was one of the morals of the story. Faith is confining, and a foul mouth and spread legs is freedom. The disdain for religion is reinforced when Ruth's father wishes him well by saying "God be with you", and Paul scoffs, "Yeah, whatever."

I know it's just a story, and I should really just relax. And, when it comes down to it, I do see fundamentalism to be rather confining. I believe God has created this whole universe and there are many wonders and possibilities we have yet to even discover; and refusing to acknowledge wonders God has created because you cling to your narrow interpretation of what you know of Him today is akin to wearing blinders. I just object to this assertion that immorality and atheism is automatically superior to religion. These things are never "free", whether you believe in God or not — not believing does not release you from the consequences. And I'm not just talking about "fire and damnation". Promiscuity can lead to unwanted pregnancies, diseases, lack of trust in relationships; foul language can lead to loss of respect.

But, I guess, if you really believe your existence is over and done in 80 years, even these "little" consequences don't mean much, either.…

2011-03-06

Bandwidth for February

We're getting closer. February's data usage clocked in at 213.98GB (196GB according to Comcast's meter). In addition to more and more shows on Netflix being delivered in HD, I did rebuild my laptop because of issues related to attempting to install the Internet Explorer 9 beta. Since I rebuilt and tried the IE9 beta again (to determine if my issues were in fact related to the new browser — they were), I ended up rebuilding twice. This meant downloading drivers twice. In addition to the software I downloaded for installation, I also had to download the games I had purchased on Steam, Games for Windows Live, and Impulse. (They were on a good enough sale for me to purchase them this way, but one of the reasons I dislike digital downloads is I am stuck with a long download process instead of just inserting a disc.)

February's usage may have been a little high due to an unusual circumstance (rebuilding a laptop and re-downloading software), but according to the online meter, I've already used 50GB for the first six days of March. (vnstat on my server is projecting a monthly usage of 244.46GB based on use so far.)

So I burned through a lot of monthly bandwidth. And I still haven't reinstalled everything.

On Comcast's data usage page is the following text:

Your Comcast High-Speed Internet service has a monthly data usage allowance of 250 gigabytes (GB). If you are wondering whether you are at risk of exceeding this 250GB threshold, you should know that the vast majority - around 99% - of Comcast customers use significantly less than 250GB per month.

I have to wonder if that is still true (since this was implemented back in 2008), and how long it will hold. I also wonder how long it'll be before I hit that cap myself. At least I know what to expect if and when that happens, from their FAQ:

What will happen if I exceed 250 GB of data usage in a month?

The vast majority - more than 99% - of our customers will not be impacted by a 250 GB monthly data usage threshold. If you exceed more than 250 GB, you may receive a call from the Customer Security Assurance ("CSA") team to notify you of excessive use. At that time, we will tell you exactly how much data you used. When we call you, we try to help you identify the source of excessive use and ask you to moderate your usage, which the vast majority of our customers do voluntarily. If you exceed 250GB again within six months of the first contact, your service will be subject to termination and you will not be eligible for either residential or commercial internet service for twelve (12) months. We know from experience that most customers curb their usage after our first call. If your account is terminated, after the twelve (12) month period expires, you may resume service by subscribing to a service plan appropriate to your needs.

Our practice for the past several years has been to call only our heaviest data users, and this practice remains the same now that the 250GB data usage threshold is in effect. We may change our practice but will, of course, provide notice to you of any change.

Will Comcast change? Well, there is this noncommittal statement in the FAQ:

Will Comcast ever revisit the 250 GB threshold and raise it in the future as bandwidth intensive activities become more and more popular?

We recognize that the Internet is constantly changing and we are committed to continuous improvement. We will continue to evaluate our policies to ensure we provide the best online experience possible. It seems reasonable to assume that this will change over time, as the Internet and our service offerings evolve, though we have not committed to doing so.

Considering Comcast's actions against Level 3 that are suspiciously harmful to Netflix, I would be surprised if they adjust their policy when most of my data usage does happen to be Netflix.

As much as I am loathe to suggest it, it may be time to look at Qwest's offerings.…

2011-01-18

Holding back features on the web

If I were to say there's a CSS 3 feature that all major browsers support except one, which browser would you guess is lacking?

The answer for today is Mozilla Firefox.

It has come up several times on my current project where we've needed to take a variable amount of information and stuff it into a limited space, where aesthetics demand we truncate the data instead of allowing an overflow or a word wrap. The typical way to do this is with an ellipsis, but at what point one should truncate the message is usually the result of guesswork. Checking to see if a string is over, say, 35 characters and cutting it off if it is may work in most cases; but because in a proportional font, the same number of characters can be different sizes depending on which actual characters are used, any fixed number will result in some data elements appearing too short, and a few appearing too long and wrapping or overflowing anyway.

Enter the text-overflow style. In a fixed div or span, setting style="text-overflow: ellipsis;" will cause the browser to truncate the contents with an ellipsis if, when, and where it is needed.

Except for Firefox. Since CSS 3 is still technically in "draft", the coders behind Firefox have decided not to implement text-overflow, despite it being on the bug list since 2005. Mozilla's own developer forum shows that Firefox is the only browser to not implement this to date.

Oddly enough, this is the second time Firefox has failed me recently (the first being a misbehaving feature that plays havoc with AJAX queries).

I found two solutions on the web. One is to use something called XUL binding. The procedure (described here) involves creating an XML document that describes the requested behavior, and then using a Mozilla-specific CSS directive to bind it to the element. Unfortunately, not only does this require another document, but it may conflict with the text-overflow style such that only one or the other will work, but not both. Also, following the comments in the bug, XUL appears to be going away with Firefox 4, and with text-overflow still not implemented, this workaround will work no longer.

The second solution uses the JavaScript library jQuery. The function (which I found at Devon Govett's blog), when applied to a web element, takes the text, recreates it in a clone of the element, starts truncating text as necessary until it finds text that fits in the element, and replaces the text in that element. It's not terribly efficient as it iteratively tests the text on each element, and if the element can change size you either have to update it manually or tell the script to constantly check the element and recompute; but it does do the job that Mozilla won't. Fortunately, we're already using jQuery, so adding an extension was a trivial task.

I don't know if it's some higher ground they're trying to take by not implementing "draft" features, but the fact remains, as an end user of browsers, to me, they appear to be stubbornly behind the curve.

2011-01-14

ASP.Net, Dynamic Controls, and ViewState, revisited

At my current job, we are encouraged to share tips and ideas with other developers. I thought it could be useful to demonstrate the problem of dynamic controls and ViewState and my solution (posted three years ago here), since it not only is a problem that could come up in our web development, but it provides a useful opportunity to review the page life cycle.

So I grabbed my sample code and opened it in Visual Studio 2010. The good news is, it still works as advertised. However, I wanted to demonstrate the problem along with the solution; so I removed all my "extra" code. I was rather startled to find that the old problem didn't manifest itself. When I typed in data to one control and clicked a button to add another, the first control retained all its data.

It seems that the .Net Framework got some improvements over the years. The first improvement is that it seems ASP.Net is far more consistent in naming controls that are added to the page at run-time. (Part of the original problem was, when a control was loaded on page load vs. later in an event handler, the dynamically-assigned ID would be different.) The second is, if a control is loaded later in the life cycle, it does actually go back to the ViewState and re-load any applicable data. (It used to be very unreliable in this regard.)

I did find that things were not all roses. If you add a bunch of controls and start removing controls from the middle of the list, control data would get lost. Also, if you delete controls in the middle of your list and re-add controls, the controls may get added in the middle of the list instead of the end.

The solution is much easier than it used to be:

  • Create a member variable to hold the list of IDs (or whatever data is required to recreate the control and its ID) — in this example, I'm using private List<string> _childControlIds to just store the IDs, since the control type and location is always the same constant.
  • Create a Page Load event handler that looks like this:
    private void Page_Load(object sender, EventArgs e) {
     if (!IsPostBack) {
      _childControlIds = new List<string>();
      addAField(null).InitializeNewControl(); //Optional - create a new control, and initialize its data
     } else {
      if (ViewState["ControlCount"] as string[] != null) {
       _childControlIds.AddRange((ViewState["ControlCount"]) as string[]);
      }
      foreach (string controlId in _childControlIds) {
       addAField(controlId); //Create an existing control with its already-established ID
      }
     }
    }
  • The addAField method looks like this:
    private CustomChildControl addAField(string fieldId) {
     CustomChildControl cc = (CustomChildControl)LoadControl("CustomChildControl.ascx");
     if (String.IsNullOrEmpty(fieldId)) {
      cc.ID = String.Format("CUST{0}", DateTime.Now.Ticks); //new control; create a unique ID
      _childControlIds.Add(cc.ID);
     } else {
      cc.ID = fieldId; //existing control; reuse ID
     } 
     this.CustomControlsPlaceHolder.Controls.Add(cc);
     cc.DeleteControlClick += new EventHandler(DeleteCustomControl);
     return cc;
    }
    Notes:
    1. It no longer appears to be necessary to add the control before setting its ID — the ViewState manager seems to pick it up just fine either way.
    2. The custom control in my example has its own delete control and fires an event, that this page subscribes to. Your implementation may vary.
  • The DeleteCustomControl method looks like this:
    private void DeleteCustomControl(object sender, EventArgs e) {
     CustomChildControl cc = sender as CustomChildControl;
     if (cc != null) {
      _childControlIds.Remove(cc.ID);
      this.CustomControlsPlaceHolder.Controls.Remove(cc);
     }
    }
  • The method to add a control (in my case, a button on the page) is simply:
    private void AddButton_Click(object sender, EventArgs e) {
     addAField(null).InitializeNewControl(); //Create a new control, and initialize its data
    }
  • And finally, a Page PreRenderComplete event handler (because it's late enough in the page lifecycle; PreRender itself may be sufficient for your needs) that sticks the control ID list in ViewState:
    private void Page_PreRenderComplete(object sender, EventArgs e) {
     ViewState["ControlCount"] = _childControlIds.ToArray();
    }

And that's it. Surprisingly simple.

I don't know at what point this changed (or if I even over-architected the original solution — a distinct possibility). This could be an improvement in .Net 3.5, or it could be something "fixed" in a service pack along the way. The only thing I can say for certain is this much simpler method works quite well in my admittedly simple example.

2011-01-01

2010 Bandwidth

I haven't been posting monthly bandwidth numbers, mostly to distract from the fact that the majority of my posts lately were the monthly bandwidth numbers, and that's just boring. But I haven't stopped keeping track.

2010 proved out what I expected. Since we got rid of paid TV, we have been relying on Netflix for the majority of our video entertainment. The use of this has increased over the year, as we've not only become more comfortable using the service, but the number of offerings of the service has increased as well. Add to this the fact that more videos are available in HD, and it's no wonder that my monthly data usage has only been going up.

There are also other items that account for the increase. A large number of file transfers to support our website design business accounts for some of this. Also, we bought a Blu-ray player that has the capability to stream YouTube videos, of which the kids have taken advantage as a substitute for more traditional Saturday morning cartoons.

The year-over-year view is rather dramatic:

The largest-use month in 2009 was surpassed by 75% of the months in 2010, and the second-highest month of 2009 was exceeded by all of them. Comcast's measurement was consistently lower than mine, although they were only 8% off in December. It was November when, finally, we reached the halfway point of a monthly cap.

The numbers are likely to only go further up. I don't see any change in this trend. Content providers are continuing to innovate and use the bandwidth we have. Netflix's increase in HD offerings is one example. Microsoft recently updated the Xbox to use a higher quality encoding for voice communication, which, although only provides a modest increase in bandwidth, is just another example.

All this still leaves me wondering, when will general use and content innovation use up this arbitrary data cap, and turn the number of "excessive" users from what was once claimed to be "a single percent" into the majority? I also wonder if Comcast's policy of punishing those who go over their monthly number will change before or after that happens — or, more cynically, how much revenue they'll collect from fines before they consider changing their policy.