OK, the idea I had right after the post ended up being what I used, which is what shoebox639 suggested as well. I put the code to pull out the required clientID into a helper method:
//****************************************************************************************
//* Find a requested control's clientID as the first parm passed in from a string
//* passed in as the second parm.
//****************************************************************************************
function locateClientID(requestedClientID, HTML_StringToSearch) {
var returnValue = "";
//If we have something to search for and something to search in, do so. Null or "" will fail this check.
if (requestedClientID && HTML_StringToSearch) {
//Find the starting point of the string starting with "id=", then any number of other letters, numbers,
// or underscores, then ending in the specified "requestedClientID" parm value. We add three to offset
// the "id+" part of the search string, which we don't want in the results, but include to locate value.
var startingPoint = HTML_StringToSearch.search("id=[a-z0-9A-Z_]*" + requestedClientID) + 3;
//If we found a valid starting point, i.e. NOT -1, then continue processing the string.
if (startingPoint > -1) {
//Now that we know where our clientID for the requested control starts in the passed in string,
// find the ending " " so we know how much to substr off to pull out the requested client id.
var endingPoint = HTML_StringToSearch.indexOf(" ", startingPoint);
//The endingPoint could be -1 if there is no space after the "id" property, but all the examples
// I have seen have more attributes after.
//substr out the clientID and return it to the caller.
returnValue = HTML_StringToSearch.substr(startingPoint, (endingPoint - startingPoint));
}
}
return returnValue;
}
//*****************************************************************************************
So in my case I would pass in the rcb123 as the first parm, and the innerHTML string blob as the second value, and the function would return the clientID value. After getting the clientID back, I just do another jQuery method call using that:
function cv123_Validate(sender, eventArgs) {
//Get a ref to the radGrid's collection of rows.
var gvRadGridNameRows = $find("<%= gvRadGridName.ClientID %>").MasterTableView.get_dataItems();
var innerHTML;
var foundClientID;
var errorImage;
var rcb123;
//Process every row in the radGrid.
for (var row = 0; row < gvRadGridNameRows.length; row++){
//Get the cell in question's innerHTML value.
innerHTML = gvRadGridNameRows.get_cell("uniqueCellName").innerHTML;
//Get ref to the 'error image'.
errorImage = $("#" + locateClientID("imgHUDError", innerHTML));
//locate the unique clientID of the rcb123 in this row.
foundClientID = locateClientID("rcb123", innerHTML);
//Use the found unique clientID with jQuery to get a ref to the dropdown list.
rcb123 = $("#" + foundClientID)[0];
//If the dropdown list's selected index is 0 or less AND the control is NOT
// disabled, active the single error message tied to this custom validator
// and show the 'error image' next to the control.
if (rcb123.selectedIndex < 1 && rcb123.isDisabled != true) {
errorImage.css("height", 12);
eventArgs.IsValid = false;
}
else //Otherwise, hide the error image.
{
errorImage.css("height", 0);
}
}
}
I'm still testing various examples, and looking for any holes other than those noted, but for my purposes this works well. I created the helper routine because I also manipulate the image in the innerHTML blob as well.
The idea was to put an 'error image' next to each control in the grid for a visual ref to where the error was, but only add ONE error message to the errorSummary control, instead of X repeated error messages which I got when simply embedding a required field validator along side the dropdown list. (my BA group didn't like that...)
Hope this helps somebody out.