DESC Container.ItemIndex

Recently had a need to reverse the count for an Repeater for one of my pages.

My google searches: DESC Container.ItemIndex, reverse repeater count, ItemIndex(), etc.

Much of the code I found either didn’t fit into my code or required behind code rework that I wasn’t willing to do until necessary.

My last search: start with last Container.ItemIndex, landed me here:

Again I had to modify the code a little, but this worked for me…

< %# (-1 * (Container.ItemIndex - DirectCast(DirectCast(Container.Parent, Repeater).DataSource, IList).Count)) %>

I hope someone else can use it!

GoDaddy Prices Up!

It’s been a while since I have had to think about renewing my hosting. GoDaddy was the first place I checked for prices. That’s where the deals used to be. That doesn’t seem the case anymore! Having to move hosting companies can be a headache, so before you commit yourself like I did to their introductory low prices… shop around!

There is a plethora of hosts out there (none posted here, I am not a promoter), many with similar packages with cheaper prices.

*Additionally, you will not have to worry about the “when you renew price.” GoDaddy used to have renewal coupons, but it’s been years now since they stopped offering them.

Answering a call via the Phone vs the Headset

Dear Samsung (and other phone makers),

I recently bought myself a Samsung Galaxy S6. Let me tell you it’s a very nice phone. I am quite happy with it. But with bluetooth now up to revision #4, I would think one thing would be worked out. Here’s my problem. When using a bluetooth headset, there should be options to allow us to pick up from the phone.

For example, when I pick up a call via the phone and the bluetooth device still connected… the call goes to the headset. Seems right? Yes and no. If the headset was on my ear I would answer it using the buttons on the headset. Unfortunately, having the headset on the ear all the time can be annoying, uncomfortable, and uncool. So, with the headset in the pocket or in the draw, I will often answer the call with the phone. Bam, I am then struggling to find the headset, switch over to the phone, wondering how could I forget.

Please give us the option to allows pick up the call (calls received only) with the phone, until we hit a headset button.

Not everyone will agree with me, but some will. Giving us that option will help us moderate headset users greatly.

Yours Truly,
The Augmenter

Tablets with Physical Home Buttons

DearĀ  Amazon,

I see that you have released a new Fire Tablet. Again, it’s pretty much the same thing. I have been waiting for Amazon to come out with a Tablet that has a home button for the longest time. Quite frankly, I don’t mind the soft home button because I have always been an “Android” user. Unfortunately my children, parents and +50% of the world are more “simplistic”. They need that “panic go to home button” in plain sight.

Apple has this down, Samsung is catching on, and you with all your consumer-centricness can’t see this? Please just try it!

Yours truly,
The Augmenter

United States Centralized Return Center

Dear Alibaba,

I recently bought a few things from AliExpress that didn’t come as described. It turns out it would cost me more to ship it back to the seller than the cost of the items. Because of this I buy a lot less, carefully buying things I only need. There goes your sales!

My suggestion to help you help me feed my impulse buying is to open up a return center here in the US. A place to take back all returns for your sellers, then ship back to China ever so often. There will be challenges and obstacles to overcome but PLEASE MAKE IT SO I CAN SHOP UNTIL I DROP!

Yours truly,
The Augmenter

Javascript, Query, & Dotnetnuke Postback

Work started getting slow a few months back, so I started programming again. My sites needed updating. I also had a few upgrades in mind. One in particular was highlighting all desired text on a certain page. I found nice JavaScript snippet here:

//<script language=”JavaScript”>
function doHighlight(spanText, searchTerm, highlightStartTag, highlightEndTag) {
// the highlightStartTag and highlightEndTag parameters are optional
if ((!highlightStartTag) || (!highlightEndTag)) {
highlightStartTag = “<font style=’background-color:yellow;’>”;
highlightEndTag = “</font>”;
var newText = “”;
var i = -1;
var lcSearchTerm = searchTerm.toLowerCase();
var lcSpanText = spanText.toLowerCase();
while (spanText.length > 0) {
i = lcSpanText.indexOf(lcSearchTerm, i + 1);
if (i < 0) {
newText += spanText;
spanText = “”;
} else {
// skip anything inside an HTML tag
if (spanText.lastIndexOf(“>”, i) >= spanText.lastIndexOf(“<“, i)) {
// skip anything inside a <script> block
if (lcSpanText.lastIndexOf(“/script>”, i) >= lcSpanText.lastIndexOf(“<script”, i)) {
// skip anything inside a <HyperLink> block
if (lcSpanText.lastIndexOf(“/asp:HyperLink>”, i) >= lcSpanText.lastIndexOf(“<asp:HyperLink”, i)) {
// skip anything inside a <linkbutton> block
if (lcSpanText.lastIndexOf(“/asp:linkbutton>”, i) >= lcSpanText.lastIndexOf(“<asp:linkbutton”, i)) {
// skip anything inside a <Checkbox> block
if (lcSpanText.lastIndexOf(“/asp:Checkbox>”, i) >= lcSpanText.lastIndexOf(“<asp:Checkbox”, i)) {
// skip anything inside a <panel> block
if (lcSpanText.lastIndexOf(“/asp:panel>”, i) >= lcSpanText.lastIndexOf(“<asp:panel”, i)) {
// skip anything inside a <legend> block
if (lcSpanText.lastIndexOf(“legend>”, i) >= lcSpanText.lastIndexOf(“<legend”, i)) {
newText += spanText.substring(0, i) + highlightStartTag + spanText.substr(i, searchTerm.length) + highlightEndTag;
spanText = spanText.substr(i + searchTerm.length);
lcSpanText = spanText.toLowerCase();
i = -1;
return newText;
return false;
function highlightSearchTerms(searchText, treatAsPhrase, warnOnFailure, highlightStartTag, highlightEndTag) {
if (treatAsPhrase) {
searchArray = [searchText];
} else {
searchArray = searchText.split(” “);
if (!document.getElementById(“spanText”) || typeof (document.getElementById(“spanText”).innerHTML) == “undefined”) {
if (warnOnFailure) {
Sorry, for some reason the text of this page is unavailable. Searching will not work.”);
return false;
var spanText = document.getElementById(“spanText”).innerHTML;
for (var i = 0; i < searchArray.length; i++) {
spanText = doHighlight(spanText, searchArray[i], highlightStartTag, highlightEndTag);
document.getElementById(“spanText”).innerHTML = spanText;
return false;
function badphrases(){
highlightSearchTerms(‘die kill’);

The code worked beautifully when I tested it’s search then highlight functions. BUT when I tested it against the rest of the page I realized that my buttons weren’t working anymore. Something was going wrong and after playing with how the script loaded, what to block it from replacing, and where it highlighted I gave up.

Another solution had to be found. Knowing that Dotnetnuke had jQuery integrated into it I tried this jQuery plugin:

Ostensibly, it looked like a winner like the last one. NO!, something was still wrong. Further inspection told me that the JavaScript was messing with DNN’s method of posting back. After some more trial and error I went to the DNN forums:

javascript and postbacks are somewhat at odds with each other under certain circumstances.
This is especially the case if there are any async / partial update panels on the page
– something that is more and more common these days.

That’s what I got, though it didn’t help much. I told me that I shouldn’t give up and after a little more searching I found my code:

<style>.highlight { background-color: yellow; }</style>

<script language=”javascript” type=”text/javascript”>

jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos =;
if (pos >= 0) {
var spannode = document.createElement(‘span’);
spannode.className = ‘highlight’;
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
return skip;
return this.length && pat && pat.length ? this.each(function() {
innerHighlight(this, pat.toUpperCase());
}) : this;



Thank you Bartaz and Johann for the nice code. Bartaz’s updated code did the trick. I hope this helps someone else working with Dotnetnuke. Happy Coding to all!


What happen to Newegg?

I recently bought a bad drive from them. Sent it back and now very angry because Newegg said there is a scratch on it?!?! I shipped it back to them with care and it was well packaged.

Their lack of customer service reminded me why I stop shopping with them and moved to Amazon. I only forgot because they cleverly sold me a lemon.

Be careful of Newegg, and there “please send it to the manufacture” scam. I doesn’t matter if you bought it and sent it back immediately. It doesn’t matter if the product has a high failure rate. I took the risk because the product (a WD HD) was bundled with a NAS I wanted.

Anyways, my credit card company helped me get my money back. Boo to you Newegg.

Working with Cron Jobs

For a while now, I have been using my shared hosting to backup/store numerous image files. Retrieving those files over the internet has always been a pain. Especially when there are hundreds of files in a given folder. The end goal is to be able to download the archived folder to my computer for easy viewing.

So, I took the time to code something up. Here’s the psuedo code:

  1. zip folder
  2. rename zip to include date stamp
  3. move zip to another destination
  4. delete contents of folder for future backups
  5. give myself a high five

Of course, I Google’d and looked for an easy way out… to see if some has posted the exact code I was looking for. No such luck but here are the links that were handy:

What I learned:

  • Cron Jobs on shared web hosting gives us the ability to run automated shell level scripts.
  • Cron Jobs coding was essentially Unix, nice I can code Unix!

Once I got started, I did run into a few Cron Jobs specifics:

  1. you have to escape the ‘%’ sign with a ‘\’ in a cron job,
  2. bonus: && operator, helped me reduce my script to one line,

Nevertheless, here’s the script that will hopefully help someone else looking to compress and backup a whole directory then delete its contents:

zip /destination/of/directory/with/date/label/$(date +\%Y\%m\%d).zip /directory/to/be/zipped/* && rm /directory/to/be/zipped/cleared/*

Happy Coding!