jQuery-Filling an Input Box in WordPress Admin

Though I have somehow managed to produce some relatively complex scripts, I am still at the stage with jQuery that, when I manage to achieve some elementary thing, I throw a little celebration in my trusty old Aeron.

I also tend to forget what I’ve figured out until the next time I have to achieve the same effect. So, here are some notes for future reference, or for the sake of other jQuery hackers, on how I think a textbox should be filled in WordPress Admin… from simple anchor links… and when the content – in this instance long image links –  is too long to be nicely contained.

The Specific Problem

In WP-RUBI, there’s a point where I want to give the user the option to employ some alternative versions of a default image.

Before I decided to spruce things up, the part of the draft version of the “Set Replacement” section in which we’re interested looked something like this:

wp-rubi-settings-3

(Just as a probably at this late date unnecessary reminder: All of the images in this post can be “embiggened,” as we used to say, with a click…)

Now, I could add these default images to the sequence of radio buttons (partially shown) which provide still more options for “Replacement Mode,” but the additional default images are more like “sub-alternatives” than major alternatives, and the options page is already long enough.

A reasonably sophisticated user probably knows to highlight the text, in this case a filename beginning http://localhost…, to be copied, then paste it into the box, but that’s kind of a lame, painstaking process even if you know to do it. Other users will try typing out the characters one by one. Either way, the work will be made more difficult or uncertain by the fact that the text box is too short for a long URL: Users will want check the link, and few users will also suspect that they can produce a look at the textbox contents – or, formally, the “type ‘url’ input box” – just by double-clicking on them.

double_click_text_box_to_sh

I don’t think I was aware I could (sometimes!) double-click to show full textbox contents until today, and I’ve been doing this since before there were computers almost.

I could style the input text to a smaller font-size, but doing so might cause eyestrain, and, anyway, we’re having fun with jQuery: So, let’s do it differently.

Basic Solution

Looking ahead, first we’ll add the elements we’re going to be acting on in the PHP/HTML mark-up, in the form of CSS selectors for jQuery to find. Since I already had an ID for input box (`upload_image`), the only things I needed to add specific to this objective were the `def_image_link` classes in the highlighted lines, which add two new image-link choices:

<th scope="row"><?php _e( '1. Select Replacement Image', 'cks_rui' ) ; ?></th>
<td>
    <label for="upload_image">

        <input id="upload_image" type="url" name="cks_rui_options[image_url]" value="<?php echo $options['image_url']; ?>" />

        <input id="upload_image_button" type="button" value="Upload Image" />

        <p>
            <?php _e( 'Enter a URL or upload an image to be used for image replacement. (Remember to Save Changes!)', 'cks_rui' ) ; ?>

        </p>

        <p><small><i>

            <?php printf( __( 'The default image is "<b><code>%s</code></b>." <br><br>With dark-colored themes try (click to add): <b><code>%s</code></b> or <b><code>%s</code></b>.', 'cks_rui' ), 
'<a href="' . plugins_url( 'images/image_removed.svg', __FILE__ ) . '" class="def_image_link">' . plugins_url( 'images/image_removed.svg', __FILE__ ) . '</a>', 
'<a href="' . plugins_url( 'images/image_removed_white.svg', __FILE__ ) . '" class="def_image_link">' . plugins_url( 'images/image_removed_white.svg', __FILE__ ) . '</a>', 
'<a href="' . plugins_url( 'images/image_removed_background.svg', __FILE__ )  . '" class="def_image_link">' . plugins_url( 'images/image_removed_background.svg', __FILE__ )  . '</a>'
             ) ; ?>

        </i></small></p>

    </label>
</td>

…which is going to output like this:

text-to-textbox-links-new_output

I won’t go into all the whats and whys of the PHP/HTML or the general approach I’m taking here, except to say that it’s all for use in a plug-in options page, this specific plug-in options page, and that, in case it isn’t obvious, plugins_url( 'REST OF LINK', __FILE__ ) converts the whole part of the link prior to REST OF LINK and adds them together: As already noted, the resultant image-links are already long, like, what?, 75 characters? I’m not going to count them, and don’t you do it either! Life’s too short.

Our jQuery script is going to make it so that all that the user has to do is click on any one of those links to transfer it instantly to the textbox.

Simple, right? Too simple for anyone much to bother to document it… until right here!

Actually, I think the problem is more that it’s so simple it was already primitive when jQuery was new, and that was 9 years and 11 months ago.

Our new script (which we’ll register and enqueue separately in its own file, since that seems to work better across installations in initial testing) gets the value of the selected link item def_image_link and puts it into the input textbox id’d as `upload_image` in the mark-up. Except for those class and id names, the following has hardly been modified from a ready example among many I ran across:

jQuery(function(){
    jQuery('.def_image_link').live('click',function() {
        jQuery('#upload_image').val(jQuery(this).html());
    });
});

The main difference otherwise between the above and the most basic references you’ll find in jQuery documentation is the use of the “this” keyword on the third line. Otherwise, code doesn’t get much simpler, although non-WordPressers stumbling onto this post might be wondering why I’m typing “jQuery” over and over again, and might also be wondering why the script is being written out instead of attached as it were in situ to the click function. (Short answers: 1) You can’t use the $ sign, or, if you want to, you have to tell WP you’re going to, and, 2), in WordPress it’s preferred and often necessary and actually works out nicely to enqueue even the simplest scripts in separate .js files.)

So, it works, but it’s not very good. Specifically, the results will be sub-optimal in two ways:

  1. When you click on the link, the page “jumps” – or jumps or reloads or travels, etc. – depending on what kind of link you use after “href.” Even if you pointed it directly to upload_image (<a href="#upload_image"…), it would still jump distractingly. Since I want the links actually to link to the image files, but not take the user to them, the action would be even more problematic.
  2. When the textbox is filled, the only part of the image filename that’s actually changing as a result of the operation (_background or _white) is hidden – meaning you can’t tell immediately that the desired exchange of the new filename for the old one was in fact achieved. As already discussed above, users are going to end up looking at the textbox and clicking on it or side-scrolling to be sure it’s what they wanted.

So: Slightly more sophisticated solution

Solving these two problems was almost as simple as creating them was, although one involved using a CSS argument – direction - that I’d never used before.

To solve the first problem, we just need to stop the default click action from occurring. For this purpose, jQuery provides the aptly method event.preventDefault().

To solve the second problem, we just need to add a CSS class and style it.

Putting them together:

jQuery(function(){
    
    jQuery('.def_image_link').live('click',function(event) {
        
        event.preventDefault();

        jQuery('#upload_image').val(jQuery(this).html()).addClass('url-rtl');
        
    });
    
});

To style the addClass added class “url-rtl” in my plug-in admin css file:

input[type=url].url-rtl {
    
    direction: rtl;
    
}

So, now, when the user clicks on one of the links, the textbox gets filled with the live-clicked link’s html, formatted right to left (rtl) instead of left to right (ltr), which latter is the style previously set for all input[type=url]s… And now also, thanks to preventDefault, there isn’t any jumping around.

text-to-textbox-links-for-j

Just after clicking…

Close-up on the rtl part:

text-to-textbox-links-cu

That’s about all there is to it…

…except for one thing: When you thereafter want to work with the url/textbox (#upload_image), dealing with an “rtl”-formatted box in a “ltr” language will be confusing – for instance, if I change my mind and try a shorter URL, it’ll look like it has a bunch of spaces at the beginning…

text-to-textbox-links-rtl-confusion

…and the text itself will behave unexpectedly when and if I try to change it manually. Don’t ask. You just don’t want to deal with it. Luckily, it’s easy to remove the just-added class as soon as anyone clicks on the box – and this time let’s recuperate the familiar “$” sign, since now the re-typing of “jQuery” is getting distracting, at least to me – heck, and while we’re at it let’s add extra readability spaces just because we can:

(function( $ ) {
    
    $( '.def_image_link' ).live( 'click', function( event ) {
        
        event.preventDefault();
        
        $( '#upload_image' ).val($( this ).html()).addClass( 'url-rtl' );
        
    });
    
    $( '#upload_image' ).live( 'click', function() {
        
                $( this ).removeClass( 'url-rtl' );
    });
    
})( jQuery );

That works.

(updated 17 July 2016)

Commenter Ignore Button by CK's Plug-Ins

Leave a Reply

Your email address will not be published. Required fields are marked *

*