Skip to content

Recently I needed to style the input[type=checkbox] element for a project at work. It used to be notoriously difficult to get default input elements looking the same across multiple browsers. Checking the web showed a utility at csscheckbox.com which helps to generate some code using CSS only, but in using the following HTML structure, it requires the use of id attribute tags in every input element.

<input type="checkbox" id="chk1" /><label for="chk1">Input label</label></code>

The CSS for this is pretty simple because it hides the input box completely and relies on the label to display the state. The “for” attribute is required so the useragent will trigger the state change for the referenced input. As such, you MUST have an “id” tag in your input and the corresponding “for” in your labels. This is ok for a few input checkboxes, but if you have a large list of options, tries the following approach instead.

<label class="chk"><input type="checkbox" />Input label</label>

By wrapping the <input> inside the <label>, you no longer need to specify the “id” and “for” attributes because the <label> always corresponds to the contained <input>. The CSS gets a little bit more complicated though because CSS does not allow you to specify rules for a parent that has a child.

label > input.chk {
// can't specify CSS rule for parent label.
}

Having the label precede the input makes the CSS slightly convoluted. Here is a jsfiddle sample that demonstrates the idea:

label > input[type=checkbox] {
width:20px;
height:20px;
margin:0px;
padding:0px;
vertical-align:middle
}
label.ck > input[type=checkbox]:before {
content:'';
display:inline-block;
width:20px;
height:20px;
background-color:green;
vertical-align:middle;
}

label.ck > input[type=checkbox]:checked:before {
content:'';
display:inline-block;
width:20px;
height:20px;
background-color:black;
vertical-align:middle;
}
label.ck > input:checked {
display:inline-block;
appearance:none;
-webkit-appearance:none;
-moz-appearance:none;
background-color:red;
}

I’ve recently started playing with the Parse.com JS api for building apps. It’s a pretty simple API and I love how easy it is to create and add new data to each object. The one thing I kept running into was having to check if an object already existed on the server. The save() function in the API simply creates the object unless you’ve already retrieved it. Seeing as often times I don’t want to remember to check, and the objects will pretty much always have the unique column, I wrote a little class to allow me to forget the unique constraint.

The code is sitting on github as a single .js file

Basically, if an object has a column that needs to be unique, just specify it when the class is declared.

var myUniqueClass = Parse.UniqueObject("uniqueClass", {uniqueKey:"keyColumnName"});
var obj = new myUniqueClass();
obj.keyColumnName = 'uniqueValue';
obj.saveUnique();

The saveUnique function does much of the heavy lifting and checks prior to calling the Parse.Object.save. Of course this isn’t always the easiest way, if there was an array of objects, it’s possible to use the saveAllUnique function to save all in one go. It checks each type of objects for their unique column and queries each before saving.

Of course the best laid plans can go astray. The above simply checks before attempting to save, but that means if there are multiple processes trying to save, a few requests may get thru. Having a Parse.Cloud.beforeSave function in place means any that get thru to the server will get one last check before it gets saved as a duplicate.

Go ahead, give it a try.

It’s not often that we get to have a nice dinner out, and it’s so easy to forget how nice it is to relax and enjoy a quiet evening with just your significant other. This week, we took advantage of a great deal at the Grand Sierra Resort in Reno, NV to have a wonderful dinner. After a day at Northstar-at-Tahoe getting our snow legs back, we sat down at the back in a large booth. The lighting was very low and the the ceilings vanished overhead. Along the back and sides of the booth, tall curtains hung down and gave the impression we were sitting on a large stage. As the food was brought out, it felt like a well choreographed dance of flavor in our mouths. Even better was starting off with a very nice Graff Riesling.

Since we are both seafood fanatics, we wanted to sample the iced seafood sampler. But I wanted a better variety and we ended up ordering some different appetizers instead. Rays was never much of a scallop fan, but the pan seared scallops with pork belly changed her mind. The scallops were well seared on both sides but retained their juicy and tender middle. The pork belly was well seasoned and crispy on all sides. They sat on a small bed of arugula leaves. We also decided to be a little adventurous (and perhaps controversial). Since we had never had foie gras before, and due to its being banned in California, we decide to try it and see what the fuss was about. Well, the dish was absolutely heavenly. It tasted light, buttery and went very well paired with the baked apple and cinnamon cake. While it was an experience that we will both treasure, we probably won’t be seeking out this sinful dish soon. Our last appetizer was a simple prawn cocktail and it came with four large tiger prawns served on a dish with a splash of sauce on the side.

For our entree, we picked the filet and braised shallot. It was cooked medium rare and came with a selection of three sauces. With the waiter telling me what each sauce was made from, I didn’t realize that the cabernet reduction sauce was on the plate until the steak was mostly gone. I still had enough left to decide that the reduction sauce was the best of the bunch. Though the butter sauce was definitely a favorite as well.

I guess it wouldn’t do to describe how wonderful it was without a nice salivation inspiring photo.

I almost forgot, we finished off our meal with a divine strawberry and mint cheesecake!

I ran into a “There was a problem with reindexing process” with my recently upgraded Magento Community installation. This went from 1.6 to 1.7 and after digging in the command being run, “MAGE_ROOT/shell/indexer.php –reindex catalog_product_price”, I get some nice PDOException errors with a “Base table or view not found” message. It’s informative because it tells me that my catalog_product_index_group_price doesn’t exist.

Further digging resulted in finding this gem: http://www.magereverse.com/. Here you can find all the SQL structure commands used to create the different versions of the software.

So then it is just a matter of running the indexer, looking at the error, and fixing the table in question. These were the tables I had to recreate:

catalog_product_index_price_idx
catalog_product_index_price_opt_idx
catalog_product_index_price_opt_agr_idx
catalog_product_index_price_cfg_opt_agr_idx
catalog_product_index_price_cfg_opt_idx

At this point I took the hint and recreated all the tables that started with catalog_product_index_price_. That fixed the issue for me so hopefully it will for you.

If you’re using NetBeans as your IDE of choice, you’ve probably run into a situation where it scans your project folders for changes and consumes an absolute ridiculous amount of CPU/Memory. The problem I found after much annoyance is that infinitely looped symlinks will cause NetBeans to scan very very hard for essentially nothing.

I had a folder which contained a symlink to itself. It’s hard to find, but here’s a quick script to do it in your project directories:

find . -type l -print -ls

That’s it! if you see any suspicious links that seem to go back on itself, try removing them or adding them to your ignore list.

If you’re thinking about buying anything on eBay, you might want to do a little research first. Checking their closed item search will give you a pretty good idea of what you should (or should not) be paying for the item you want. That is assuming you’re not looking for a one of a kind item.

Most items like iPods or macbook pro laptops are commodities and the pricing is therefore somewhat uniform. But scrolling thru that long list of (up to) 200 items with sold/unsold items makes it hard for you to get an idea of what you should be paying. Sure, you could try to remember the cheapest item you saw, or the 2 or three that seemed more reasonable. What if there was a better way to get some research on those items? Now there is! Just add the bookmarklet on this page to your toolbar and you can easily see what the run down on those listings are.

When you search for your item, try to get as specific as possible using negative keywords (-notThisKeyWord), category filtering, price range, and product specifications. This will help to make removing trash items much easier. Don’t make it too specific either because then you may leave out an item where someone listed it wrong (which usually results in a bargain buy). Once you’re happy with the closed item results, just click the bookmarklet in your toolbar and it will take you to the research tool page. Here is a screenshot of what it looks like: Tool screenshot

There are a few things you can do now. The three top boxes show you summary information. The first box shows the breakdown of number of sold vs unsold items and how many items were found. Currently the tool only takes the first page of data from your search, but I am planning to add a feature to allow multi-pages. The second box shows the average, minimum, and maximum sale price for sold items along with the standard deviation in the sample set. The third box is the same as the second except for unsold items. The minimum and maximum values are clickable and will filter the data table by that value. So if the minimum is $9.99, clicking it will filter out any prices not containing 9.99. You can sort on the price column to see the lowest/highest prices. Clicking on a row will select that row and you can remove it from the data set by then clicking “Delete Selected Row”. You can also select multiple rows by holding down the SHIFT key for your second click.

Using the standard normal distribution table, we can remove any prices outside of 1.645 standard deviations away. That removes the 10% of samples that are outliers both low and high. You can do this in one step by clicking the “90% Sold Range” or “90% Unsold Range”.

There are plenty of secure deletion software out there, but yesterday I had a need to securely erase my id_rsa file copied to a thumb drive. I didn’t want to have to download some software because I was on a non-personal Mac. A quick search turned up the ‘dd’ command. This simple command on unix which has been around forever to copy data from/to block devices in theory should be able to write over my data multiple times and erase the contents.

dd if=/dev/urandom of=/Volume/NO\ NAME/id_rsa conv=notrunc count=1024 bs=1024

That command writes out 1 MiB of random data to the specified id_rsa file. You can alternate the above command with

dd if=/dev/zero of=/Volume/NO\ NAME/id_rsa conv=notrunc count=1024 bs=1024

to overwrite with zeros and then with random data again.

Now, that in theory should overwrite the contents of the file and a simple unlink or rm should delete the file entry. If anyone reading this sees a flaw in my logic/implementation, or has improvements please leave me a comment.

Create your own server certificate request:
openssl genrsa -des3 -out server.key 1024

Remove the passphrase (optional, but makes your apache startup much faster)
openssl rsa -in server.key -out server.key.unsecure

Create the signature request
openssl req -new -key server.key -out server.csr

Create your own Certificate Authority

openssl genrsa -des3 -out ca.key 1024
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Create this script to /tmp/sign.sh (Use this faq source)
#!/bin/sh
##
## sign.sh -- Sign a SSL Certificate Request (CSR)
## Copyright (c) 1998-1999 Ralf S. Engelschall, All Rights Reserved.
##

# argument line handling
CSR=$1
if [ $# -ne 1 ]; then
echo "Usage: sign.sign .csr"; exit 1
fi
if [ ! -f $CSR ]; then
echo "CSR not found: $CSR"; exit 1
fi
case $CSR in
*.csr ) CERT="`echo $CSR | sed -e 's/\.csr/.crt/'`" ;;
* ) CERT="$CSR.crt" ;;
esac

# make sure environment exists
if [ ! -d ca.db.certs ]; then
mkdir ca.db.certs
fi
if [ ! -f ca.db.serial ]; then
echo '01' >ca.db.serial
fi
if [ ! -f ca.db.index ]; then
cp /dev/null ca.db.index
fi

# create an own SSLeay config
cat >ca.config <<EOT
[ ca ]
default_ca = CA_own
[ CA_own ]
dir = /etc/apache2
certs = /etc/apache2/certs
new_certs_dir = /etc/apache2/ca.db.certs
database = /etc/apache2/ca.db.index
serial = /etc/apache2/ca.db.serial
RANDFILE = /etc/apache2/ca.db.rand
certificate = /etc/apache2/certs/ca.crt
private_key = /etc/apache2/private/ca.key
default_days = 365
default_crl_days = 30
default_md = md5
preserve = no
policy = policy_anything
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
EOT

# sign the certificate
echo "CA signing: $CSR -> $CERT:"
openssl ca -config ca.config -out $CERT -infiles $CSR
echo "CA verifying: $CERT <-> CA cert"
openssl verify -CAfile /etc/apache2/certs/ca.crt $CERT

# cleanup after SSLeay
rm -f ca.config
rm -f ca.db.serial.old
rm -f ca.db.index.old

# die gracefully
exit 0

Sign your server certificate
/tmp/sign.sh server.csr

Move the Certificates to /etc/apache2/certs and the keys to /etc/apache2/keys
Edit your httpd.conf to include httpd-ssl.conf
And edit your httpd-ssl.conf to set the following directives correctly

SSLCertificateFile “/private/etc/apache2/certs/server.crt”
SSLCertificateKeyFile “/private/etc/apache2/keys/server.key”

Need a list of currency codes based on country? Try this:

http://www.panalpina.com/www/global/en/tools_resources/unit_converter/currency_codes.html

or Google Search for country code to currency codes

Then using your javascript console:

var tb = document.getElementById('table_par');
data = tb.getElementsByTagName('TR');
data = Array.prototype.slice.call(data, 2);
var output = {}; var country = null;

for (var i=0;i var tds = data[i].getElementsByTagName('TD');
if (tds.item(2) && tds.item(8)) {
if (tds.item(2).innerHTML != ' ') {
country = tds.item(2).innerHTML;
}
if (tds.item(8).innerHTML != ' ') {
if (output[country]) {
output[country].push(tds.item(8).innerHTML);
} else {
output[country] = [ tds.item(8).innerHTML ];
}
}
}
}
JSON.stringify(output);

Here is the output:
"{"AF":["AFA"],"AL":["ALL"],"DZ":["DZD"],"AS":["EUR"],"AD":["EUR"],"AO":["AOK","AON"],"AI":["XCD"],"AG":["XCD"],"AR":["ARP"],"AM":["AMD"],"AW":["ANG"],"AU":["AUD"],"AT":["EUR"],"AZ":["AZM"],"BS":["BSD"],"BH":["BHD"],"BD":["BDT"],"BB":["BBD"],"BY":["BYR"],"BE":["EUR"],"BZ":["BZD"],"BJ":["XOF"],"BM":["BMD"],"BT":["INR","BTR"],"BO":["BOB"],"BA":["BAK"],"BW":["BWP"],"BV":["NOK"],"BR":["BRR","BRL"],"IO":["USD"],"BN":["BND"],"BG":["BGL"],"BF":["XOF"],"BI":["BIF"],"KH":["KHR"],"CM":["XAF"],"CA":["CAD"],"CV":["CVE"],"KY":["KYD"],"CF":["XAF"],"TD":["XAF"],"CL":["CLP"],"CN":["CNY"],"CX":["AUD"],"CC":["AUD"],"CO":["COP"],"KM":["KMF"],"CG":["XAF"],"CD":["CDF"],"CK":["NZD"],"CR":["CRC"],"HR":["HRK"],"CU":["CUP"],"CY":["CYP"],"CZ":["CSK"],"DK":["DKK"],"DJ":["DJF"],"DM":["XCD"],"DO":["DOP"],"TP":["IDR"],"EC":["ECS"],"EG":["EGP"],"SV":["SVC"],"GQ":["XAF"],"ER":["ETB","ERN"],"EE":["EEK"],"ET":["ETB"],"FK":["FKP"],"FO":["DKK"],"FJ":["FJD"],"FI":["EUR"],"FR":["EUR"],"GF":["EUR"],"PF":["XPF"],"TF":["EUR"],"GA":["XAF"],"GM":["GMD"],"GE":["GEL"],"DE":["EUR"],"GH":["GHC"],"GI":["GIP"],"GR":["EUR"],"GL":["DKK"],"GD":["XCD"],"GP":["EUR"],"GU":["USD"],"GT":["GTQ"],"GN":["GNF"],"GW":["XOF"],"GY":["GYD"],"HT":["HTG","USD"],"HM":["AUD"],"HN":["HNL"],"HK":["HKD"],"HU":["HUF"],"IS":["ISK"],"IN":["INR"],"ID":["IDR"],"IR":["IRR"],"IQ":["IQD"],"IE":["EUR"],"IL":["ILS"],"IT":["EUR"],"CI":["XOF"],"JM":["JMD"],"JP":["JPY"],"JO":["JOD"],"KZ":["KZT"],"KE":["KES"],"KI":["AUD"],"KP":["KPW"],"KR":["KRW"],"KW":["KWD"],"KG":["KGS"],"LA":["LAK"],"LV":["LVL"],"LB":["LBP"],"LS":["LSL","ZAR","ZAL"],"LR":["LRD"],"LY":["LYD"],"LI":["CHF"],"LT":["LTL"],"LU":["EUR"],"MO":["MOP"],"MK":["MKD"],"MG":["MGF"],"MW":["MWK"],"MY":["MYR"],"MV":["MVR"],"ML":["XOF"],"MT":["MTL"],"MH":["USD"],"MQ":["EUR"],"MR":["MRO"],"MU":["MUR"],"YT":["EUR"],"MX":["MXP"],"FM":["USD"],"MD":["MDL"],"MC":["EUR"],"MN":["MNT"],"MS":["XCD"],"MA":["MAD"],"MZ":["MZM"],"MM":["MMK"],"NA":["NAD","ZAR"],"NR":["AUD"],"NP":["NPR"],"NL":["EUR"],"AN":["ANG"],"NC":["XPF"],"NZ":["NZD"],"NI":["NIO"],"NE":["XOF"],"NG":["NGN"],"NU":["NZD"],"NF":["AUD"],"MP":["USD"],"NO":["NOK"],"OM":["OMR"],"PK":["PKR"],"PW":["USD"],"PA":["PAB","USD"],"PG":["PGK"],"PY":["PYG"],"PE":["PEN"],"PH":["PHP"],"PN":["NZD"],"PL":["PLZ"],"PT":["EUR"],"PR":["USD"],"QA":["QAR"],"RE":["EUR"],"RO":["ROL"],"RU":["RUR"],"RW":["RWF"],"KN":["XCD"],"LC":["XCD"],"VC":["XCD"],"WS":["EUR","USD","WST"],"SM":["EUR"],"ST":["STD"],"SA":["SAR"],"SN":["XOF"],"SC":["SCR"],"SL":["SLL"],"SG":["SGD"],"SK":["SKK"],"SI":["EUR"],"SB":["SBD"],"SO":["SOS"],"ZA":["ZAR"],"GS":["GBP"],"ES":["EUR"],"LK":["LKR"],"SD":["SDD","SDP"],"SR":["SRG"],"SJ":["NOK"],"SZ":["SZL"],"SE":["SEK"],"CH":["CHF"],"SY":["SYP"],"TW":["TWD"],"TJ":["TJR","RUR"],"TZ":["TZS"],"TH":["THB"],"TG":["XOF"],"TK":["NZD"],"TO":["TOP"],"TT":["TTD"],"TN":["TND"],"TR":["TRL"],"TM":["TMM"],"TC":["USD"],"TV":["AUD"],"UG":["UGX"],"UA":["UAH"],"AE":["AED"],"GB":["GBP"],"US":["USD"],"UM":["USD"],"UY":["UYU"],"UZ":["UZS"],"VU":["VUV"],"VA":["EUR"],"VE":["VEB"],"VN":["VND"],"VG":["USD"],"VI":["USD"],"WF":["XPF"],"EH":["MAD"],"YE":["YER"],"YU":["YUN"],"ZM":["ZMK"],"ZW":["ZWD"]}"

Zero padding in BASH shell:
There are a couple of ways to pad integers with leading zeros in BASH. One way is to add a larger number and truncate the leading digit:
foo=100000
smallNumber=25
largeNumber=$(( $foo + $smallNumber ))
zeroPaddedNumber=${largeNumber:1}
echo $zeroPaddedNumber

This displays: “00025″ the ${largeNumber:1} chops off the first character from 100025.

Another way is to use printf, but this creates another process and is more expensive in larger loops.
zeroPaddedNumber=`printf "%05d" $smallNumber`

Same results, but in larger loops will have slight performance penalty

Enforcing decimal for integers with leading zeros
Doing calculations with zero padded integers may provide inaccurate results. Specifically “00025″ is counted as octal in bash. To force bash to recognize it as a decimal number:

smallNumber='00025'
decimalNumber="10#"$smallNumber
hexNumber="0x"$smallNumber
echo $(( $smallNumber + 1))
echo $(( $decimalNumber + 1))
echo $(( $hexNumber + 1))

The above prints “22″, “26″, and “38″. The “$(( ))” construct does arithmetic calculation and returns the value in base 10.

String substitution or substring search in bash variables
Sometimes you assign the output of a command to a variable, expecting it to hold some information. If the command failed or did return the expected values, you must check the values returned.

mylongstring="This is a really long string I want to check"
searchstring="I want"
if [[ ${mylongstring#*$searchstring*} != $mylongstring ]]; then
echo "'$searchstring' was found in '$mylongstring'"
fi
searchstring="I have"
if [[ ${mylongstring#*$searchstring*} == $mylongstring ]]; then
echo "'$searchstring' was not found in '$mylongstring'"
fi