29 February 2008
Cheating with Web.SiteMap - Two links in one sitemap
This was for ALL the Main menu items.
In addition she wanted some pages to be in two places, so e-news would be under products, but a link would exist in the "about us" main menu too.
This problem was solved with some creative naming in web.sitemap and a few other tricks.
Say you have a typical sitemap like so:
<sitemap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
<sitemapnode url="~/default.aspx" title="HiddenRoot">
<sitemapnode url="~/contact/"></sitemapnode>
<sitemapnode url="~/contact/default.aspx">
<sitemapnode url="~/products/enews/"></sitemapnode></span>
</sitemapnode>
<sitemapnode url="~/products/list/" title="Our Products"></sitemapnode>
<sitemapnode url="~/products/list/default.aspx">
<sitemapnode url="~/products/where/default.aspx">
<sitemapnode url="~/products/item/default.aspx">
<sitemapnode url="~/products/enews/default.aspx">
</sitemapnode>
<sitemapnode>url="~/about/"></sitemapnode>
<sitemapnode url="~/about/default.aspx">
<sitemapnode url="~/about/qa/default.aspx">
<sitemapnode url="~/about/research/default.aspx">
</sitemapnode>
</sitemapnode>
</sitemap>
You'll notice above (in bold) that the parent nodes omit "default.aspx" IIS will take the default page when it navigates to these directories and you will actually end up at the Child Node with that actual page.
When I return Sitemap.CurrentNode() it returns the child... even though I clicked the parent. This allows me to highlight both with a CssClass dynamically (I'm using CSS friendly adapters from CodePlex for the Rendering of a MEnu Control)
Clicking : ~/about/
will take you to : ~/about/default.aspx
You'll notice that I do the same in the contact menu. The link reads /products/enews/
but the actual link in the products menu is /products/enews/default.aspx
In addition... I strip "default.aspx" off the end of ANY link in the main menu just to keep the url clean... with this code which also makes sure the Parent Node is selected :
protected void mnuNav_MenuItemDataBound(object sender, MenuEventArgs e) {
//strips default.aspx (not necessary... just for clean urls.
e.Item.NavigateUrl = e.Item.NavigateUrl.Replace("default.aspx", "");
if (SiteMap.CurrentNode != null && SiteMap.CurrentNode != SiteMap.RootNode) {
if (e.Item.Text == SiteMap.CurrentNode.ParentNode.Title)
e.Item.Selected = true;
}
}
27 February 2008
Enabling Script Debugging in IE7 and JINQ
20 December 2007
Calculating a Checkdigit using Math.Ceiling
Calculating Checkdigits
So, something I've been wanting to do is calculate a checkdigit for a UPC-A code in Code. In case you didn't know, the check digit is the final digit on a Standard 12 digits or 14 digit UPC and can be calculated from the preceding digits
The reasoning behind this is if a barcode reader scans a barcode wrong it will internally do a calculation and see if the result matches the checkdigit. If it matches all is good. The UPC is made up of a manufacturer code and a product code. So, for example: 0-12345-67890-5 :
- 0-12345 marks the manufacturer
- 67890 identifies the product
- 5 is the check digit
Anyway, we want to enable people to enter 67890 as a check-digit, and then have the program automatically calculate the UPC to be entered in to the database.
To Calculate the Checkdigit “5” is fairly straight forward to do for human calculators (the brain) but presents some challenges for computers.
The calculation goes as follows,
- Add up all the odd position digits
- multiply that by 3
- add the even position digits
- Take the total and whatever you need to get to the nearest 10 is the checkdigit.
- To illustrate:
- 0-12345-67899-?
- (0 + 2 + 4 +6 + 8 + 9) * 3 = 87
- 87 + (1 + 3 + 5 + 7 + 9) = 112
- 112 + x = 120 (next multiple of 10)
- x = 8
Simple Right? It's basic addition and subtraction.
However, the computer doesn't know how to get 120 from.
MODULUS to the rescue!!!
Modulus is basically an operator that lets you calculate the remainder. If you remember back in Grade school, before you learned fractions or decimals, 10 / 3 = 3 Remainder 1, 3R1
In C# the Modulus Operator is %
Well, If we take the total (112) and do (112 % 10) we end up with a remainder of 2... so All we need to do is this: 10 - (total % 10) = 8 DONE! Right?
But not so fast...
There is a problem. If we end up with a total which IS a multiple of 10, our remainder = 0 (110 % 10) = 0 Rem. And since 10 - 0 = 10, this won't work (the checkdigit should be 0, not 10)
So, just write an IF statement, right? If it's 10, set it to 0, if not, subtract from 10.
The if statement could be written like so:
int checkdigit = (total % 10 == 0)? 0 : 10 - (total % 10);
However, I prefer a purely mathematical approach if I can. The first approach we came up with used the Math.Ceiling function. What this function does is basically returns the next whole number. So, Math.Ceiling(11.2) would return 12.0. How can we use this?
Well, our total 112 / 10 actually = 11.2, If we take the Ceiling of that number, we end up with 12. and 12 x 10 = 120. And 120 - 112 = 8! This also works if we end up with a total that is a multiple of 10. Since Math.Ceiling(11.0) returns 11, 11 x 10 = 110. 110 - 110 = 0!
So, here's the code to do that:
int checkdigit = (int)Math.Ceiling(total / 10.0d) * 10 - total;
Where total = 112
- 112 / 10.0d = 11.2
- Ceiling of 11.2 = 12.0
- 12 * 10 = 120
- 120 - 112 = 8
- 110 / 10.0d = 11.0
- Ceiling of 11.0 = 11.0
- 11 * 10 = 110
- 110 - 110 = 0
It Works!
Note, Ceiling returns a decimal, but since we will always have a whole number, we can safely cast this as an int.
But yes... there is a 3rd way.... if you're satisfied with this method so far, that's fine. This was our first solution, and it's kind of cool. BUT after looking at the mod function again, we came up with another solution. It doesn't need any casting as int either, is shorter and perhaps faster, I'm not sure.... here's the formula:
int checkdigit = (10 – total % 10) % 10;
What's going on here? Well
- 112 % 10 = 2 (remainder)
- 10 - 2 = 8
- 8 % 10 = 8
- 110 % 10 = 0
- 10 - 0 = 10
- 10 % 10 = 0
Short, concise, easy to read, and I'd imagine... fast.
Here's the enture C# Code for your perusal:
public static int CheckDigit(string strUpc)
{
// strip all non-numeric characters
string upc = System.Text.RegularExpressions.Regex.Replace(strUpc, @"\D", string.Empty);
int total = 0;
//add the odd position digits
for (int x = 0; x < (upc.Length); x += 2) { total += Convert.ToInt32(upc[x].ToString()); } total = total * 3; //add the even position digits for (int x = 1; x < (upc.Length); x += 2) { total += Convert.ToInt32(upc[x].ToString()); } //calculate the checkdigit return (int)Math.Ceiling(total / 10.0d) * 10 - total; /************************ // could also be written: //AS A condensed IF STATEMENT return (total % 10 == 10) ? 0 : 10 - (total % 10); //That is... if total mod 10 = 10 return 0, else 10 - (total mod 10) //or... using MOD the MOD return (10 – total % 10) % 10 *************************/ }
Just stick this into your utility class or anywhere else in your application, and you're good to go.
13 December 2007
16 August 2007
29 December 2006
19 December 2006
Beware, the Sushi Police are coming.
I highly recommend the article, but here's the synopsis:
What this means is that a team of Japanese could come to Vancouver, and having gone into a restaurant where !gasp! BC Rolls, California Rolls and Dynamite Rolls are being served, they could decide that since these are not Japanese foods, that this restaurant is not an official Japan sanctioned restaurant. Of course, this is really only meant for Japanese nationals, who are travelling. I suppose they want to create a list of certified authentic Japanese food around the world that Japanese tourists around the world will feel comfortable going to.
I admit there are some bad sushi restaurants, but there are also some very good combinations that even many in Japan would like. I know my wife seems to like rolls with Cream Cheese in them... even though they're definitely NOT Japanese.
I think fusion foods can really bring out the best in a cuisine and if you want my advice, check out "Wild Rice" close to tinseltown downtown for some of the best fusion Chinese you'll ever have.
Sidenote: I wonder if the Japanese Ministry of Agriculture realize that tempura comes from Europe?