Contents tagged with JQuery

  • Code Builder for jQuery AJAX (Calling Web Services)

    Getting stuck in the cycle of code-build-test, code-build-test… can drain you physically, mentally, emotionally and spiritually. In the back of your mind you know the clock is ticking and you are not making headway. Of course the boss keeps sticking his sweaty head into your tiny cube and asking, "Any progress?" What a jerk. The intern who is supposed to be helping you keeps asking stupid questions he could find on Google: the lazy meathead. The department secretary just told you they lost your time sheet so you'll have to fill out another one: Too bad you didn't make a copy. Your waist is getting thicker and your hair is getting thinner.

  • Elegance, thy Name is jQuery

    So, I'm browsing though some questions over on the Stack Overflow website and I found a good jQuery question just a few minutes old. Here is a link to it. It was a tough question; I knew that by answering it, I could learn new stuff and reinforce what I already knew: Reading is good, doing is better. Maybe I could help someone in the process too.

  • HTML 5 and jQuery – A Match Made in Heaven

    I recently attended an ASP.NET MVC seminar hosted by the Twin Cities .Net User Group. The speaker was K. Scott Allen. Scott is a charismatic, gifted speaker and did a great job. You can always pick up useful items when watching an expert write a program from scratch.

  • jQuery Selector Tester and Cheat Sheet

    I've always appreciated these tools: Expresso and XPath Builder. They make designing regular expressions and XPath selectors almost fun! Did I say fun? I meant less painful. Being able to paste/load text and then interactively play with the search criteria is infinitely better than the code/compile/run/test cycle. It's faster and you get a much better feel for how the expressions work.

  • Finding Controls in a Master Page with jQuery

    This question popped up on the Asp.Net forums where I moderate:

    "How do I find an HTML element on a Master Page, from a child page, using jQuery?"

    I licked my chops. I like questions like this because when I don't know the answer, it gives me an excuse to explore and learn.

    The problem is that element ids on Master Pages get mangled, or decorated, to prevent duplicate ids on the final rendered HTML.

    For instance a textbox with an id like this: MasterPageTextBox

    Ends up with an id like this: ctl00$MasterPageTextBox

    Solution 1:

    We could hard code the mangled id into the jQuery search criteria and it would work. But what a maintenance nightmare, in the future, the mangled id might change: Not acceptable. When people pay you money to write code, you should write good code.

    Solution 2:

    If you are using Asp.Net 4, you have control over the generated ids and can make them predictable. Then you can hard code the generated id into the CSS selector. However, that isn't the case for most sites at this time.

    Solution 3:

    After Googling and Binging around a bit, I came up with this approach to use in the Master Page:

        protected void Page_Load(object sender, EventArgs e)
        {
            Page.ClientScript.RegisterHiddenField("HiddenFieldClientID", this.MasterPageTextBox.ClientID); 
        }

    The code above takes the generated ClientID and puts it in a HiddenField that gets sent to the browser. The jQuery code in the child page can then get the value in the HiddenField and use it to search for the element. I thought this was pretty cool but…the jQuery code wouldn't compile because the HiddenField wasn't on its page. So an empty HiddenField control has to be placed on the page. It's messy but it works! Here is how the jQuery on the child page accesses the hidden field and then accesses the textbox on the Master Page:   

        // ---- SetMasterPageTextBox ---------------------------
        // write hello in a textbox field on the master page
     
        function SetMasterPageTextBox()
        {
            // Get the hidden field         
            var HidField = $("#HiddenFieldClientID");
            if (HidField.length == 1)
            {
                // get the contents of the hidden field
                var ClientID = HidField[0].value;
                // use it as the ID of the TextBox control
                $("#" + ClientID).val("Hello");
            }
        }

    I went to post my 'brilliant' answer, but in the meantime another forum member posted an answer which was far superior to mine.

    Frank Hong suggested wrapping the element with a span tag.

    Solution 4:

    Two things make this next solution work.

    1. Span tag ID's are NOT mangled or decorated.
    2. CSS selectors are cool, really cool…quick review:

    div, p

    The comma (,) operator means AND. All divs and paragraphs on the page will be selected.

    div > p

    The greater than (>) operator means direct parent of. Any paragraphs directly inside of any divs are selected

    div p

    The space ( ) operator means ancestor of. Any paragraphs inside a div are selected, even if they are inside of other elements within the div.

    In the Master Page wrap the textbox with a span element:

         <%-- Span is to allow child page to jQuery select textbox--%>
         <span id="SpanMyTextBox">
             <asp:TextBox ID="MyTextBox" runat="server"></asp:TextBox>
         </span>

    Here's what it looks like rendered, note the TextBox id got mangled but the span id remains unscathed: 

        <span id="SpanMyTextBox">
            <input name="ctl00$MyTextBox" type="text" id="ctl00_MyTextBox" />
        </span>      	

    In the Child Page we can use the greater than or the space operator. The greater than operator is more explicit as to our intent. We use 'input' because textboxes render as HTML input elements.

    So the CSS selector is:   #SpanMyTextBox > input 

        // ---- SetMasterPageTextBox ---------------------------
        // write hello in a textbox field on the master page        
     
        function SetMasterPageTextBox()
        {
            //Textbox is wrapped in span element
            $("#SpanMyTextBox > input").val("Hello");
        }
     

    Now, isn't that better? Of course, it's up to the developer to ensure duplicate span ids are not used.

    [Update:]

    Solution 5: (from the comments)

    You can also use a wild card CSS selector.

       input[id$=MyTextBox]

    The above line matches all HTML input elements with an id attribute that ends with "MyTextBox".  

    It will match:

       <asp:TextBox ID="ctl00$MyTextBox" runat="server"...
       <asp:TextBox ID="LaLaLaMyTextBox" runat="server"...
       <asp:TextBox ID="abc123MyTextBox" runat="server"...

    I hope someone finds this useful.

    Steve Wellens

  • Goodbye Ajax Toolkit, Hello jQuery UI

    Like most developers, I love finding tools that do my work for me and make me look good. And, like most developers, I am extremely wary of adding too much outside crap to a project which can make maintaining it a nightmare. You may end up not only maintaining your own code but someone else's code, or worse, not being able to update the project because a third-party control won't let you.

    The Ajax Toolkit has some great stuff that is very easy to use. It's from Microsoft so you can be pretty comfortable adding it to a project. Drag and Drop and off you go. But often things don't work out exactly as you would like. Deploying and debugging are not always easy.

    A viable alternative to the Ajax Toolkit is the jQuery UI.

    I was happy to see on the jQuery web site they have their own UI controls…very happy. If you are already using jQuery, you don't feel as if you are adding a third party component. And, it seems, Microsoft has 'adopted' jQuery.

    Here's their website: http://jqueryui.com/. It's also reachable from http://jquery.com/

    I decided to try out the DatePicker control, since picking a date is one of the most useful and common tasks a control can do.

    Downloading and installing the jQuery UI was no more difficult than downloading and installing jQuery itself. The download is customizable; you pick which components you want and which visual theme you want.

    In the download you get:

    • A CSS file and images
    • Minimized versions of the jQuery UI and jQuery code
    • "Development bundle"
      • Documentation
      • Demos
      • Separate code files
      • Misc.

    I added the CSS file, image directory and jQuery code file to my project. I already had the jQuery library. When you drag and drop the files onto the page, you get entries like these:

        <script src="Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
        <script src="Scripts/jquery-ui-1.8.4.custom.min.js" type="text/javascript"></script>
        <link type="text/css" href="css/smoothness/jquery-ui-1.8.4.custom.css" rel="stylesheet" />

    Note: Other versions of the source code are available: non-minimized and documented versions.

    Now, let's create a TextBox and hookup the DatePicker control to it:

       <script type="text/javascript" language="javascript">
     
            $(document).ready(DocReady);
     
            function DocReady()
            {
                $('#DatePicker_TextBox').datepicker();
            }
       
        <asp:TextBox ID="DatePicker_TextBox" runat="server" ></asp:TextBox>

    Note: jQuery code is usually so ugly its own mother would slap it. I strive for legibility and maintainability by NOT nesting and chaining functions and using a more 'traditional' C# style of coding.

    Here's what happens when you click on, or tab into, the text box:

    Dang, that wasn't hard, it works well and looks pretty. When you select a date, it fills in the textbox:

    You can edit the text in the box by hand and the DatePicker control reads it. If the text isn't a valid date, the DatePicker control ignores it. Nice. It has a good solid feel. I know engineers shouldn't talk like that but…it has a good solid feel.

    Let's change the date format. Sadly, the date formatting codes are different than the .Net DateTime formatting codes (more on this later). I added a few more options just for fun. For numberOfMonths, you supply a two dimensional array: 3 by 4 would show an entire year.

            $(document).ready(DocReady);
     
            function DocReady()
            {
                var DatePicker = $('#DatePicker_TextBox').datepicker();
     
                DatePicker.datepicker('option',
                        {
                            dateFormat: 'DD, d MM, yy',
                            numberOfMonths: [1, 2],
                            showWeek: 'true' 
                        }); 
            }

    Why didn't I just chain the formatting code to the creation code? Why did I create a separate variable?

    Debugging: If something goes wrong, I can tell if the problem is in the creation of the DatePicker or in the formatting of the DatePicker. Until you have to debug code, you don't know how valuable and useful this is. The local variable avoids a duplicate search operation.

    Why the weird code formatting when setting the options?

    I tried to make it as readable as possible. When there is more than one option, it is easier to read if each option is on a separate line. It's also easier to tell when the braces and parenthesis match up.

    Here's what it looks like with the options set:

    Note: In the above image you can see a bug: The fifth day of both months is selected. I checked the website and it was already reported here: http://dev.jqueryui.com/ticket/5984. The posted workaround corrected the problem.

    It's pretty cool. But, the textbox is going to be sent back to the server and will need to be converted to a DateTime object. As mentioned earlier: .NET and jQuery use different formatting codes.

    So the code to convert the string to a DateTime is:

            String DateText = DatePicker_TextBox.Text;
     
            DateTime TheDate;
     
            // jquery format: DD, d MM, yy
            // .Net format:   dddd, d MMMM, yyyy
            // Sample:        Friday, 3 September, 2010
            if (DateTime.TryParseExact(DateText, 
                                      "dddd, d MMMM, yyyy", 
                                      null, 
                                      DateTimeStyles.None, 
                                      out TheDate) == false)
            {
                TheDate = DateTime.Now.Date;  // default value on error
            }

    In a real application, you'd want to centralize the format strings in one place so they are easy to maintain (by using constants or utility functions).    

    Once you start playing with and using the jQuery UI components, you'll be hooked.

    By the way, I still use and appreciate the Ajax UpdatePanel in the Ajax Extensions toolbox. Although some treat it disdainfully, what you get, for what you pay, is a great bargain.

    I hope someone finds this useful.

    Steve Wellens.