Dynamically Adding Fields with jQuery

Posted on Thu 27 January 2022 in Programming

The jQuery JavaScript library provides elegant solutions to various programming challenges. While browsing a jQuery email list, I came across a simple problem that even a novice JavaScript coder like me could tackle. I'll simplify it here for the sake of clarity. Essentially, the original poster wanted to add form fields to a table while incrementing a field counter in both the HTML and the ID and name tags. To add a bit more complexity, the field numbers needed to be padded with leading zeros. Adding table rows with jQuery is straightforward, and it turns out that adding leading zeros is quite simple too. I appreciate JavaScript's "everything is an object" approach, which even extends to built-in objects like the String object. Let's start with that.

 

The String object lacks a built-in method for repeating characters. After a quick internet search, I found an efficient solution. To pad leading zeros, we first need a method to repeat a character. Although this explanation may skip the details of how the prototype works, you might want to research it further.

```javascript

// Add a repeat method to the String object

String.prototype.repeat = function(n)

    return new Array(n + 1).join(this);

;

```

Now we can use `'0'.repeat(3)` to generate a string of three zeros ("000").

 

Next, let's create a short padding routine. When writing code, it's wise to think ahead and consider whether you'll need similar functionality in the future. Can you make it dynamic? Here's the padding function I came up with:

```javascript

// Add a leading_zeros function

var leading_zeros = function(n, total_digits)

    n = n.toString();

    return '0'.repeat(total_digits - n.length) + n;

;

```

To make this work with jQuery, I prefer to create a jQuery plugin. This allows us to add a method to the jQuery object, making it easy to use for padding. While this approach is not strictly necessary, I believe it results in cleaner and more usable code.

 

According to the jQuery Plugin Manual, we should start a new plugin with the following code block:

```javascript

(function())();

```

It's not immediately obvious that this function will run automatically, and this wasn't readily apparent in many online JavaScript references. Additionally, it may confuse some readers that the `$` character is not a legal character for a JavaScript variable name. However, after some investigation, I found an EcmaScript specification stating that `$` is valid as the first character in a variable name. As JavaScript variables can consist of just one character, `$` is indeed a valid variable name. This is also the name the library author chose for the jQuery object.

```javascript

(function($) )(jQuery);

```

With this in mind, we can continue with the code block.

 

Now, let's create a counter that utilizes a static variable. A static variable retains its value between function calls. In JavaScript, you simply declare the variable outside the function, and it behaves as a static variable.

```javascript

// Initialize the counter

var counter = 0;

 

var count = function()

    return ++counter;

;

```

Due to how scope works in JavaScript, the value of the variable `counter` is preserved between calls to the `count()` function, resulting in incrementing values in the alerts.

 

Finally, let's integrate this into the document-ready portion of our jQuery application.

```javascript

$(document).ready(function()

 

    // Initialize the counter

    var counter = 0;

 

    $('#fields-button').click(function()

 

        // Increment and pad the counter

        var padded_counter = $.leading_zeros(++counter, 3);

 

        // Create the new field

        var extrafield = '<tr><td>List Item ' + padded_counter + '</td><td>';

        extrafield += '<input type="text" name="' + padded_counter + '"'

        extrafield += ' id="' + padded_counter + '"></td></tr>'

 

        // Add the new field to the table

        $('#fields').append(extrafield);

    );

);

```

Bringing it all together results in the following:

```html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.dfwrein.com/html4-embed.dtd">

<html>

<head>

    <title>Dynamic Fields</title>

    <script type="text/javascript" src="/site/code/jquery-1.2.2.pack.js"></script>

    <script type="text/javascript">

 

        (function($)

 

            // Add repeat method to String object

            String.prototype.repeat = function(n)

                return new Array(n + 1).join(this);

            ;

 

            // Add leading_zeros method to jQuery

            $.leading_zeros = function(n, total_digits)

                n = n.toString();

                return '0'.repeat(total_digits - n.length) + n;

            ;

 

        )(jQuery);

 

        $(document).ready(function()

 

            // Initialize the counter

            var counter = 0;

 

            $('#fields-button').click(function()

 

                // Increment and pad the counter

                var padded_counter = $.leading_zeros(++counter, 3);

 

                // Create the new field

                var extrafield = '<tr><td>List Item ' + padded_counter + '</td><td>';

                extrafield += '<input type="text" name="' + padded_counter + '"></td></tr>';

 

                // Add the new field to the table

                $('#fields').append(extrafield);

            );

        );

 

    </script>

</head>

<body>

    <button id="fields-button">Add Field</button>

    <form action="some_script.pl" method="get">

    <table id="fields"></table>

</form>

</body>

</html>

```

This code allows you to dynamically add fields to a table, incrementing the counter and padding the numbers with leading zeros.