Wednesday, September 3, 2025

New Series: Unveiling the Power and Pitfalls of AI

 

Unveiling the Power and Pitfalls of AI

New Series Announcement

Over the coming weeks/months, I’ll be sharing a series of posts aimed at helping you get successful, consistent results when working with AI—whether you’re a developer, IT professional, or just curious about how to make these tools work for you instead of against you.

This series, Unveiling the Power and Pitfalls of AI, will explore the practical realities of working with AI in real-world, high-stakes environments. I’ll cover not just the “wow” moments, but also the subtle traps, edge cases, and workflow quirks that can make or break your results.

We have seen all the recent articles condemning in most cases, how the non-technical housewife (or househusband) have used AI to guide their life direction or even as substitute therapist. That's all well and good as long as you keep in mind


Where These Insights Come From

I’m not just theorizing—I’m actively designing and building an enterprise-level AI-assisted IT Manager. This system is being developed with a unique twist: I’m using AI to help design itself.

I don't have a team that I am a part of anymore, I am just a geek with a passion to solve problems and a thirst for knowledge. Most development begins with many whiteboard sessions tossing around ideas, retirement limits these valuable resources. So I am using AI as my team.

That means:

  • AI refining AI – I feed architectural concepts, code, and operational logic into multiple AI platforms, comparing and refining outputs until I get the most reliable, audit-friendly results.
  • Cross-platform intelligence – I’m drawing on the strengths of several AI ecosystems, including:
    • Windows Copilot – for OS-level integration and contextual assistance.
    • Microsoft Edge Copilot – for rapid research, contextual web insights, and in-browser refinement.
    • GitHub Copilot (paid) – for deep code generation, pattern recognition, and iterative development.
    • JetBrains Coding Agent in ReSharper (paid) – for precision refactoring, code quality enforcement, and architectural consistency.

By combining these tools, I’m able to triangulate the truth—cross-checking outputs, identifying inconsistencies, and pushing each AI to perform at its best. No two AI models are alike. The differences can be vast or very minor.


What You Can Expect

In this series, I’ll share:

  • Prompting strategies that consistently yield accurate, actionable results.
  • Verification techniques to catch AI drift, hallucinations, or subtle logic errors before they cause problems.
  • Workflow patterns for integrating AI into development, IT operations, and decision-making without losing control of the process.
  • Pitfall alerts—real examples of where AI can mislead you, and how to spot the warning signs early.
  • Cross-AI synergy tips—how to make different AI tools complement each other instead of competing.

Why This Matters

AI is powerful, but it’s not magic. Without the right approach, it can waste time, introduce errors, or lead you down unproductive paths. My goal is to help you harness AI’s strengths while staying in control, so you can build systems that are not only smart, but also reliable, auditable, and future-proof.

The first post in the series will drop soon—stay tuned. If you’ve ever wondered how to get repeatable, trustworthy results from AI, you won’t want to miss it.


First secret, AI generated this post based on conversational history

Sunday, September 30, 2012

Simple JQuery image button mouse over (hover) effect

Simple JQuery Image Button Hover Effect

Overview:

   Here is just a quick down and dirty JQuery function to handle the MouseEnter and MouseLeave events of the target control labeled with the class "button" in this case it's an image control. As you can see below hover accepts two arguments, these arguments are then MouseEnter and Mouseleave events.

By changing these arguments you can control many other elements properties and add other effects. Thats really all there is too it

JQuery function:

     Just drop this in your page head section and set your appropriate image paths.

<script type="text/javascript">
 
        $(document).ready(function () {
          
            $(".button").hover(function () {
                $(this).attr("src""./app_themes/default/images/submit_btn_hvr.png");
            }, function () {
                $(this).attr("src""./app_themes/default/images/submit_btn.png");
            });
                                   
        });
 
    </script>

Markup:

Make sure that you set your initial ImageURl to the same path as the second argument in the hover method, otherwise you won't have an image on page load
 <asp:ImageButton ID="Imagebutton1" class="button" ImageUrl="~/app_themes/default/images/submit_btn.png"
        runat="server" />

Saturday, September 29, 2012

Handling backspace/delete with AJAX MaskedEditExtender in chrome

      Another one of these annoying behaviours with AJAX controls is with the Masked Edit Extender and Chrome browsers. As designed (according to Microsoft) the AJAX MaskedEditExtender does not handle the backspace or delete key strokes. I have not tested this with all mask types, but one in particular is the date mask type.

      I wanted to add just a touch of control to my birthdate text control. Nothing real fancy just format "99/99/9999" to restrict the user gobbly gook. All works as advertised except that you can't use the backspace key if you make a mistake. I don't know about you all, but that key has been my friend since day one, so not being able to use it got me Goggling.  With some searching I came across this javascript that handles the key presses and enables delete in the MaskedEditExtender.

   
Here's the markup. Just need to add the key handlers to the textbox and put the extenders id as function arguments.



  <asp:TextBox ID="ctl_birthday"  runat="server" 
                    onkeydown='KeyDownHandler("MaskedEditExtender1");' ></asp:TextBox>
                    <AJAX:RoundedCornersExtender TargetControlID="ctl_birthday" ID="RoundedCornersExtender1" 
                    runat="server" Corners="All" Radius="8">
                    </AJAX:RoundedCornersExtender>
                    <AJAX:MaskedEditExtender MaskType="Date" Mask="99/99/9999" ID="MaskedEditExtender1" 
                    TargetControlID="ctl_birthday" runat="server">
                    </AJAX:MaskedEditExtender>


Here is the javascript for the handler:


function KeyUpHandler(sender) { }
 
function KeyDownHandler(maskExtenderId) {
 
    if (navigator.appName != "Microsoft Internet Explorer") {
 
 
 
        if (event.keyCode == 35 || event.keyCode == 36) { // Home and End buttons functionality
 
 
 
            var txtElement = $get(event.srcElement.id);
 
            var txtElementText = GetTextElementValue(event.srcElement.id);
 
 
 
            if (event.keyCode == 36) {//Home button
 
                setCaretPosition(txtElement, 0);
 
            }
 
            if (event.keyCode == 35) {//End button
 
                setCaretPosition(txtElement, txtElementText.length);
 
            }
 
        }
 
 
        if (event.keyCode == 8 || event.keyCode == 46) {
 
 
 
            var txtElement = $get(event.srcElement.id);
 
            var txtElementText = GetTextElementValue(event.srcElement.id);
 
            var txtElementCursorPosition = doGetCaretPosition(txtElement);
 
            var maskExtender = $find(maskExtenderId);
 
 
            var start = txtElement.selectionStart;
 
            var end = txtElement.selectionEnd;
 
            var selectedSymbols = end - start;
 
 
 
            if (event.keyCode == 8) //BackSpace
            {
 
                if (selectedSymbols > 0) {//if there is selection(more then 1 symbol)
 
 
                    var str1 = txtElementText.substr(0, start);
 
                    var str2 = txtElementText.substr(end);
 
                    var str = str1 + str2;
 
                    if (str.length < txtElementText.length) str = appendStrWithChar(str, txtElementText, "_");
 
                    SetTextElementValue(event.srcElement.id, str);
 
                    //txtElement.value = str;
 
                    maskExtender._LogicTextMask = deletePromptChars(str, "_");
 
                    setCaretPosition(txtElement, start);
 
                }
 
                else {
 
                    if ((txtElementCursorPosition - 1) >= 0) {
 
                        var symbol_to_delete = txtElementText[txtElementCursorPosition - 1];
 
                        if (symbol_to_delete == "_") {
 
                            setCaretPosition(txtElement, txtElementCursorPosition - 1);
 
                        }
 
                        else {
 
                            var str1 = txtElementText.substr(0, txtElementCursorPosition - 1);
 
                            var str2 = txtElementText.substr(txtElementCursorPosition);
 
                            var str = str1 + str2;
 
                            if (str.length < txtElementText.length) str = appendStrWithChar(str, txtElementText, "_");
 
                            SetTextElementValue(event.srcElement.id, str);
 
                            //txtElement.value = str;
 
                            maskExtender._LogicTextMask = deletePromptChars(str, "_");
 
                            setCaretPosition(txtElement, txtElementCursorPosition - 1);
 
                            //var real_text = deletePromptChars(str, "_");
 
                        }
 
                    }
 
                }
 
 
 
            }
 
            if (event.keyCode == 46) //Delete
            {
 
                if (txtElementCursorPosition >= 0 && txtElementCursorPosition < txtElementText.length
 
                        && ((selectedSymbols <= 1 && txtElementText[txtElementCursorPosition] != "_") || selectedSymbols > 1)) {
 
 
                    if (selectedSymbols > 1) {//if there is selection(more then 1 symbol)
 
                        var str1 = txtElementText.substr(0, start);
 
                        var str2 = txtElementText.substr(end);
 
                        var str = str1 + str2;
 
                        if (str.length < txtElementText.length) str = appendStrWithChar(str, txtElementText, "_");
 
                        SetTextElementValue(event.srcElement.id, str);
 
                        //txtElement.value = str;
 
                        maskExtender._LogicTextMask = deletePromptChars(str, "_");
 
                        setCaretPosition(txtElement, start);
 
                    }
 
                    else {//no selection or 1 symbol selected
 
                        var symbol_to_delete = txtElementText[txtElementCursorPosition];
 
 
                        if (symbol_to_delete != "_") {
 
                            var str1 = txtElementText.substr(0, txtElementCursorPosition);
 
                            var str2 = txtElementText.substr(txtElementCursorPosition + 1);
 
                            var str = str1 + str2;
 
                            if (str.length < txtElementText.length) str = appendStrWithChar(str, txtElementText, "_");
 
                            SetTextElementValue(event.srcElement.id, str);
 
                            //txtElement.value = str;
 
                            maskExtender._LogicTextMask = deletePromptChars(str, "_");
 
                            setCaretPosition(txtElement, txtElementCursorPosition);
 
                        }
 
                    }
 
                }
 
 
 
            }
 
        }
 
 
    }
 
 
}
 
function GetTextElementValue(elementId) {
 
    var textBox = $get(elementId), text;
 
    if (textBox.AjaxControlToolkitTextBoxWrapper) {
 
        text = textBox.AjaxControlToolkitTextBoxWrapper.get_Value();
 
    }
 
    else {
 
        text = textBox.value;
 
    }
 
 
    return text;
 
}
 
 
function SetTextElementValue(elementId, someText) {
 
    var textBox = $get(elementId);
 
    if (textBox.AjaxControlToolkitTextBoxWrapper) {
 
        textBox.AjaxControlToolkitTextBoxWrapper.set_Value(someText);
 
    }
 
    else {
 
        textBox.value = someText;
 
    }
 
}
 
 
function appendStrWithChar(str, templateStr, appChar) {
 
    var newStr = str;
 
    var difference = templateStr.length - newStr.length;
 
 
    if (difference > 0) {
 
        for (i = 0; i < difference; i++) { newStr = newStr + "_"; }
 
    }
 
    return newStr;
 
}
 
 
function deletePromptChars(str, promptChar) {
 
    var newStr = str;
 
    for (i = 0; i < newStr.length; i++) {
 
        if (str[i] == promptChar) {
 
            newStr = newStr.substr(0, i);
 
            return newStr;
 
        }
 
    }
 
}
 
 
function doGetCaretPosition(ctrl) {
 
    var CaretPos = 0; // IE Support
 
    if (document.selection) {
 
        ctrl.focus();
 
        var Sel = document.selection.createRange();
 
        Sel.moveStart('character', -ctrl.value.length);
 
        CaretPos = Sel.text.length;
 
    }
 
    // Firefox support
 
    else if (ctrl.selectionStart || ctrl.selectionStart == '0')
 
        CaretPos = ctrl.selectionStart;
 
    return (CaretPos);
 
}
 
 
function setCaretPosition(ctrl, pos) {
 
    if (ctrl.setSelectionRange) {
 
        ctrl.focus();
 
        ctrl.setSelectionRange(pos, pos);
 
    }
 
    else if (ctrl.createTextRange) {
 
        var range = ctrl.createTextRange();
 
        range.collapse(true);
 
        range.moveEnd('character', pos);
 
        range.moveStart('character', pos);
 
        range.select();
 
    }
 
}


Happy Coding...

Merlin

Friday, September 28, 2012

Randomizing LINQ to SQL Query Results

Another stumper solved today.. Something as simple as randomizing LINQ results

It's not something built-in. There is no Random query operator provided by Microsoft. In addition, it can't be done simply by using the System.Random class, because everything in a LINQ to SQL query must be translatable to SQL. That being the case...Let's detail the solution that uses a SQL user-defined function. The most common way to sort records randomly is to use the NEWID SQL Server function. This is what this solution uses.
First, create the following view:

CREATE VIEW RandomView
AS
SELECT NEWID() As ID
Then create the following function that uses the view:CREATE FUNCTION GetNewId
(
)
RETURNS uniqueidentifier
AS
BEGIN
RETURN (SELECT ID FROM RandomView)
END
The view is required because it's not possible to directly use NEWID in a scalar function.

And now we can use this in any LINQ to SQL query to retrieve truly random records.



 Dim p = (From u In db.DBUserPhotos
                Join t2 In db.DBUsers On u.UserID Equals t2.ID
        Where (u.IsMain = True)
        Where (t2.IsActive = True)
        Where (u.IsFlagged = False)
        Where (t2.IsFlagged = False)
        Where (u.IsPublic = True)
        Where (u.IsEnabled = True)
        Order By db.GetNewId
                Select New MainPhotoInfo With { _
                    .ID = t2.ID, _
                    .Username = t2.Username, _
                    .PhotoLocation = u.PhotoLocation, _
                    .Email = t2.Email}).Take(10)


Happy Coding



Tuesday, September 25, 2012

Using ResolveUrl to correct paths in html controls

Just a quick post. When i'm working on my development server and debug locally I run into issues on html controls and paths.  Such as: http://localhost:9999/YourVirtualDirectory/

The directory does not really exist so when the dom objects access paths like this, they won't work

<script type="text/javascript" src="~/Scripts/jquery.lavalamp.js"></script>

Neither will this

<script type="text/javascript" src="../Scripts/jquery.lavalamp.js"></script>

But this will

<script type="text/javascript" src='<%= ResolveUrl("~/Scripts/jquery.lavalamp.js") %>'></script>


So there ya have it. Use the ResolveUrl method to fix those pesky paths once and for all and not have to change it prior to moving to production.

Happy Coding..
Merlin

Centering content in a DIV element

Centering contents of a DIV element

No this isn't exactly brain surgery but it did stump me for a spell. I laid out a div with a width of 100% and a text-align:center, then I dropped in a table with 2 columns and a fixed width.

The desired results was a table centered in the page. Unfortunately that was not the case. I'm not sure why this didn't work, hopefully someone can shed some light on it for me.

Here's the code I tried:


<div style="text-align:centerwidth:400px;">
        <table border="0" cellpadding="0" cellspacing="0" width="400">
            <tr>
                <td>fdsdf
                </td>
            </tr>
        </table>
    </div>

By simply adding the margin: auto; attribute to the table, it magically moves to the center of the div as desired.


 <table border="0" cellpadding="0" cellspacing="0" width="400" style="margin:auto;">


If anyone has a reason behind this I would like to hear it. Just one of those weird quirks that makes me go hmmm... Could be by design, just seems wonky. I also dropped some controls in the DIV and it didn't center them either.  Hmmm.

Happy Coding...
Merlin

Sunday, September 23, 2012

Ajax AutoCompleteExtender Page Method Magic

Using Page Methods with AJAX Auto Complete Extenders

    Using AJAX AutocompleteExtender Page Methods can be a tricky proposal, as I have discovered recently while working on a project. There seems to be a few key settings that seem to be elusive. Countless searches later I have put it all together and though I would share it with with you.
 
      Why use page methods instead of a Webservice file ASMX?? If you only have one extender and/or you want to keep everything in one file, using page methods is a quick way to do it.

Here's the quick checklist:


  • Script Manager must have it's EnablePageMethods property set to true
  • Page method must be marked Public and Shared
  • Method must be in the aspx file and not in a user control
  • Method must be marked with   <webmethod> and <Scriptmethod attribute>
  • Method must be declared specifically as outlined below

<WebMethod()> _
    <Script.Services.ScriptMethod()> _
    Public Shared Function GetCompletionList(ByVal prefixText As StringByVal count As IntegerAs System.String()
        Return {""""}
    End Function

The part that stumped me for so long is the fact you can't use the Auto Complete Extender AND use the page methods in a User Control. Dino Esposito touches on this in this MSDN Magazine Article

"A callable page method is a public static (or Shared in Visual Basic® .NET) method defined in the codebehind class and decorated with the same WebMethod attribute used for Web service methods. At present, this is limited to ASPX pages-both inline and codebehind code-but might be extended in the future to user controls and custom controls."

Mr. Esposito's article goes in depth on the usage and options available

Hope this helps someone...  Happy Coding