This was my second organised audax. The first was a disaster: in freezing temperatures I didn’t take my overshoes, got freezing feet and ditched.
The Stonehenge 200 (incomplete route as the GPS ran out of battery) , run in beautiful sunshine. A very different experience from a solo audax as I was with a group the whole time and as a consequence spent far less time on the time-trial bars / drops than usual.
I felt pretty good during the ride, it was only when I tried to push up a hill on the way home from the registration that I found my legs didn’t work!
Yellow ball in the sky, no ice on the road, only wearing two layers.. Maybe spring is starting, at last.
Flatter run than last time across Norfolk. This part of Norfolk isn’t flat though, there was still just shy of 700m climb, but nothing steep. I would finally have done a 100km Audax under 4hrs, if the ride hadn’t actually come to 107km!
Lovely route, which was actually the 2nd half of an organised Audax that I bailed out of in 2010.
Because of sunlight and fingerprints on the screen, I couldn’t always see where I was meant to go on the map. If you zoom in, you can find about 5 places I did u-turns!
My second Audax of 2013. I’m still on course for one an month (not including January), just.
This route took in two big hills out of the “Another 100 Greatest Cycling Climbs” book. Both were rated as 5/10. I’d agree with the second (Frocester Hill), which was long, but not so steep. The first (Haresfield Beacon) I struggled with. I stopped 3 times. Once for possible ice on the road, once when I spotted an absurdly steep section ahead and was already exhausted and once at the top of the absurdly steep section when the road continued at just under 20%, but I was about to explode. When I say absurdly steep, this seemed steeper than Winterfold / Barhatch Lane, which I know is 25% and is rated 9/10 in the book. If I stood to go up, my rear wheel slipped and if I sat down I couldn’t move the bike. Maybe my hillclimb legs just aren’t in for this year yet…
I met a nice cyclist from the Gloucester Cycling Club and we chatted as we rode around near Frampton on Severn.
My route again took in a long section of the A38, which is still a great cycling road in my opinion. Wide, smooth and not alot of traffic (they’re all on the M5).
Next 100k will hopefully be in Norfolk and 10% of the climbing
.
Three months into the year and I’ve hit 1000 miles!
Here’s the daily moving average.
I’m not an Excel guru or I’d make the points different colours depending which bike I was on and just have the range from 13-20mph. You see the dent made by riding the “Khatmandu” mountain bike with ice tyres through the endless winter. The first 3 days were also just after Christmas before everyone went back to work so were pretty much traffic free, giving an initial spike.
I think the trend’s upwards ever so slightly. How much of that is fitness and how much is me learning every inch of the route I can’t say.
My new office is about a mile from the town centre. My colleague and I were getting annoyed by having to take our whole lunch break to take a trip into town. I missed being able to just pop out and get little bits and pieces that I needed. I do cycle to work, but my “real” bike looks a little flash and I’d be paranoid locking it up in town.
So, I decided to trawl EBay with a budget of £10 and the result is “the office bike” (innuendo included as it’s a lady):
Unfortunately, on the first ride, an inner tube blew and had to be replaced, increasing the value of the bike by 50%!
Now that’s fixed, it goes surprisingly well. The gears work and I think the brakes are ok (though my colleague disagrees). Now it takes 5 minutes to get into town and it’s less effort. Question is, why doesn’t everyone do this for £10?
(That was a good point to end it, but I think the answer is that re-cycling £10 bikes doesn’t make anyone any real money, so there’s no interest in it from those that could make it more popular.)
For a while now I’ve been using a JQuery extension that takes selected inputs (and dropdowns and textareas) or inputs contained in the selection and converts them into a javascript object ready for submission with an Ajax post as JSON.
The need for something like this came about when we found that the data that needed to be submitted didn’t neatly fit on a form. An example is where the data was across multiple tabs and the “submit” button needed to be on the first tab.
Now, we have the ability to use the following JQuery:
var newObj = $('#tab1,#tab2',#tab3).obj();
to grab all the inputs into an object, which can then be manipulated before submission. Inputs of type “button” and anything you mark with the class “ignore” won’t be pulled into the object.
The construction of the object is based on the names of the inputs, and follows the dot and bracket notation used in naming .Net MVC, so the following inputs:
<input name="m1.Sub1.Name" value="Anne" /> <input name="m1.Sub1.Age" value="22" /> <input name="m1.Sub1.Numbers[0]" value="1" /> <input name="m1.Sub1.Numbers[1]" value="2" />
will get converted to:
{ m1: { Sub1: { Name: "Anne", Age: "22", Numbers: [ "1", "2" ] } } }
unless of course the “preserveNaming” option is passed in and set to true. In which case the object will be flat, and you’ll get names like “m1.Sub1.Numbers[0]“. Using something like json2, you can stringify this and submit it in an ajax call. It plays very nicely with .Net MVC.
It’s worth pointing out that the JQuery selector can incorporate controls and containers, so you can do something like this:
var newObj = $('#myForm1,#myForm2,#aDropdown').obj({ preserveNaming: true });
and the “newObj” will incorporate all the bits.
So, onto the code, enjoy!:
// Use this jquery extension to convert the inputs, dropdowns & textareas on the selected node(s) into a javascript object
/// options:
/// preserveNaming: default = false - whether the function preserves the names of controls, or splits on .s an []s
(function ($) {
var _options;
$.fn.obj = function (options) {
_options = options || {};
var obj = {};
// List of control names that have been seen.
var namesSeen = [];
this.each(function (index) {
var selector = $(this);
var jqSelector;
if (selector.is('input') || selector.is('select') || selector.is('textarea')) {
// This is a control with no inner html
jqSelector = selector;
} else {
//This is a container
jqSelector = $('input,select,textarea', selector);
}
// inputs
jqSelector.each(function (index) {
var nodeToCopy = $(this);
// do not process controls with the ignore class
// do not process buttons
if (nodeToCopy.hasClass('ignore') || nodeToCopy.attr('type') == 'button') {
return;
}
var name = nodeToCopy.attr('name');
if (!name || name.length == 0) return; // Don't bother with inputs with no names
// Only deal with inputs we haven't seen yet
if (!namesSeen[name]) {
var value;
if (nodeToCopy.attr('type') == 'checkbox') {
if (nodeToCopy.is(':checked')) {
value = true;
} else {
value = false;
}
} else if (nodeToCopy.attr('type') == 'radio') {
if (nodeToCopy.is(':checked')) {
value = nodeToCopy.val();
} else {
// pretend we haven't seen un-selected radio buttons so we end up with the selected one
return;
}
} else {
value = nodeToCopy.val();
}
namesSeen[name] = true;
addValue(obj, name, value);
}
});
}); // each selector
return obj;
};
var addValue = function (obj, name, value) {
if (_options.preserveNaming) {
obj[name] = value;
} else {
var parts = name.split('.');
parts.reverse(); // must reverse to use the pop() as we will be going root to leaf.
add(obj, parts, value); // recursevely add name parts to existing object
}
}
var add = function (curObj, remainingNames, value) {
var curName = remainingNames.pop();
if (!curName || curName.length == 0) return; // Don't bother with blank name
var arrayData = null;
// see if the name is a list in the form of AAA[NNN]
var match = new RegExp("(.+)\\[([0-9]*)\\]").exec(curName);
if ((match !== null) && (match.length == 3)) {
var arrayData = { arrName: match[1], arrIndex: match[2] };
// Make the current object and name be the array and the index of the array respectively
// Equivalent to calling curObj[arrayData.arrName][arrIndex] in the section below
if (curObj[arrayData.arrName] === undefined) curObj[arrayData.arrName] = [];
curObj = curObj[arrayData.arrName];
curName = arrayData.arrIndex;
}
if (remainingNames.length == 0) {
// This is the leaf node
// If not an array value, just place it on the leaf object.
curObj[curName] = value;
} else {
// Not the leaf, have to extend existing object
if (curObj[curName] === undefined) curObj[curName] = {};
add(curObj[curName], remainingNames, value);
}
}
})(jQuery);