最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Block characters from input text field, mirror input into span or div - Stack Overflow

programmeradmin5浏览0评论

I have some html

<input type="text" name="name" value="" id="name">
<div id="preview"></div>

The rules for entry into the field:

  • Letters A-Z a-z 0-9 space and dash, no other characters allowed
  • Entry of forbidden characters should do nothing

The rules for the div:

  • Show each characters as it is entered into the input field
  • Do not show characters that are forbidden
  • When a space is encountered, show it as a dash

I have had various potions working, not working, or misbehaving. This version seems to work in all cases I can test other than backspace/delete is non functional. Only tested in Safari so far.

There are other "gotcha" areas, like entering in text in-between already entered text, select all, using the arrow keys, all these play a role in this problem.

 $(document).ready(function(){
  $('#name').keypress(function(e) {
   // get key pressed
   var c = String.fromCharCode(e.which);
   // var d = e.keyCode? e.keyCode : e.charCode; // this seems to catch arrow and delete better than jQuery's way (e.which)
   // match against allowed set and fail if no match
   var allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ';
   if (e.which != 8 && allowed.indexOf(c) < 0) return false; // d !== 37 && d != 39 && d != 46 && 
   // just replace spaces in the preview
   window.setTimeout(function() {$('#preview').text($('#name').val().replace(/ /g, '-'));}, 1);
  });
 });

If there is a way to put a monetary bounty on this post, let me know. Yes, that is where I am at with this one :)

I have some html

<input type="text" name="name" value="" id="name">
<div id="preview"></div>

The rules for entry into the field:

  • Letters A-Z a-z 0-9 space and dash, no other characters allowed
  • Entry of forbidden characters should do nothing

The rules for the div:

  • Show each characters as it is entered into the input field
  • Do not show characters that are forbidden
  • When a space is encountered, show it as a dash

I have had various potions working, not working, or misbehaving. This version seems to work in all cases I can test other than backspace/delete is non functional. Only tested in Safari so far.

There are other "gotcha" areas, like entering in text in-between already entered text, select all, using the arrow keys, all these play a role in this problem.

 $(document).ready(function(){
  $('#name').keypress(function(e) {
   // get key pressed
   var c = String.fromCharCode(e.which);
   // var d = e.keyCode? e.keyCode : e.charCode; // this seems to catch arrow and delete better than jQuery's way (e.which)
   // match against allowed set and fail if no match
   var allowed = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ';
   if (e.which != 8 && allowed.indexOf(c) < 0) return false; // d !== 37 && d != 39 && d != 46 && 
   // just replace spaces in the preview
   window.setTimeout(function() {$('#preview').text($('#name').val().replace(/ /g, '-'));}, 1);
  });
 });

If there is a way to put a monetary bounty on this post, let me know. Yes, that is where I am at with this one :)

Share Improve this question edited Jul 21, 2011 at 17:41 Joel Coehoorn 417k114 gold badges578 silver badges814 bronze badges asked Sep 9, 2009 at 4:34 user170579user170579 8,5506 gold badges26 silver badges21 bronze badges 2
  • What is the question exactly? Also, your javascript might be better in a code block and formatted so it's readable. – Odd Commented Sep 9, 2009 at 4:37
  • I think with your current reputation you can't put a bounty on this. – rahul Commented Sep 9, 2009 at 4:45
Add a ment  | 

4 Answers 4

Reset to default 3

I tested the following in Firefox, Safari and Internet Explorer. Unless I didn't fully understand your objective, I believe this should solve your problem.

I ended up writing a jQuery plugin to handle the input caret position. The plugin source is included below, or available on the jQuery plugin site (http://plugins.jquery./project/caret-range).

$(document).ready(function () {
    var InvalidPattern = /[^a-z0-9\- ]+/gi;
    var SpacePattern = / /g;

    var name = $("#name");
    var preview = $("#preview");

    var callback = function (e) {
        setTimeout(function () {
            // Get range and length to restore caret position
            var range = name.caret();
            var len = name.val().length;

            // Blur element to minimize visibility of caret jumping
            name.get(0).blur();

            // Remove invalid characters, and update preview
            name.val(name.val().replace(InvalidPattern, ""));
            preview.text(name.val().replace(SpacePattern, "-"));

            // Restore caret position
            var diff = len - name.val().length;
            name.caret(range.start - diff, range.end - diff);
        }, 0);
    };

    name.keypress(callback);
    name.keydown(callback); // Needed by IE to update preview for Delete and Backspace
});

/*
 * jQuery Caret Range plugin
 * Copyright (c) 2009 Matt Zabriskie
 * Released under the MIT and GPL licenses.
 */
(function($) {
    $.extend($.fn, {
        caret: function (start, end) {
            var elem = this[0];

            if (elem) {                         
                // get caret range
                if (typeof start == "undefined") {
                    if (elem.selectionStart) {
                        start = elem.selectionStart;
                        end = elem.selectionEnd;
                    }
                    else if (document.selection) {
                        var val = this.val();
                        var range = document.selection.createRange().duplicate();
                        range.moveEnd("character", val.length)
                        start = (range.text == "" ? val.length : val.lastIndexOf(range.text));

                        range = document.selection.createRange().duplicate();
                        range.moveStart("character", -val.length);
                        end = range.text.length;
                    }
                }
                // set caret range
                else {
                    var val = this.val();

                    if (typeof start != "number") start = -1;
                    if (typeof end != "number") end = -1;
                    if (start < 0) start = 0;
                    if (end > val.length) end = val.length;
                    if (end < start) end = start;
                    if (start > end) start = end;

                    elem.focus();

                    if (elem.selectionStart) {
                        elem.selectionStart = start;
                        elem.selectionEnd = end;
                    }
                    else if (document.selection) {
                        var range = elem.createTextRange();
                        range.collapse(true);
                        range.moveStart("character", start);
                        range.moveEnd("character", end - start);
                        range.select();
                    }
                }

                return {start:start, end:end};
            }
        }
    });
})(jQuery);

After tinkering around I have refactored my previous solution. This version should behave identical to Twitter. I am keeping my old answer alive simply b/c it is technically valid, and this allows paring the different approaches.

$(document).ready(function () {
    var SpacePattern = / /g;

    var name = $("#name");
    var preview = $("#preview");

    var updatePreview = function () {
        preview.text(name.val().replace(SpacePattern, "-"));
    };

    name.keypress(function (e) {
        if (e.which > 0 && // check that key code exists
            e.which != 8 && // allow backspace
            e.which != 32 && e.which != 45 && // allow space and dash
            !(e.which >= 48 && e.which <= 57) && // allow 0-9
            !(e.which >= 65 && e.which <= 90) && // allow A-Z
            !(e.which >= 97 && e.which <= 122)   // allow a-z
            ) {
            e.preventDefault();
        }
        else {
            setTimeout(updatePreview, 0);
        }
    });

    name.keyup(updatePreview); // Needed by IE for Delete and Backspace keys
});

Try this: 1. When key down, copy the previous TextField value. 2. When key up, use RegEx to validate the text (something like /^[a-zA-Z0-9 -]*$/), if unmatch, replace the value with the old one.

Here is the code:

var ValidPattern = /^[a-zA-Z0-9\- ]*$/;
$(document).ready(function(){
    $('#name').keydown(function(e) {
        var aValue = $('#name').val();
        $('#name').attr("oldValue", aValue);

        return true;
    });
    $('#name').keyup(function(e) {
        var aValue   = $('#name').val();
        var aIsMatch = aValue.search(ValidPattern) != -1;
        if(aIsMatch) {
            $('#preview').text(aValue);
        } else {
            var aOldValue = $('#name').attr("oldValue");
            $('#name')   .val (aOldValue);
            $('#preview').text(aOldValue);
        }
    });
});

Try it.

I think the best method will be to keep a button and after entering the text inside the text box and clicking on the button show it in the div. It will be much more easier and user friendly.

It would be better not to try hindering the default actions of a user with the keyboard.

发布评论

评论列表(0)

  1. 暂无评论