0

I am working on an iPad specific website, which uses a lot of number fields in a form. I need to be able to create a dynamic preview of what the user is entering, and decided to use magicpreview.

(which is located here)

However, the code doesnt seem set up to work with number fields. It works as required for everything else. Can anyone help me edit it so that it does work?

(function ($) {
    $.fn.magicpreview = function (str, options) {

        if (typeof str === "object" && typeof options === "undefined") // If function(options)
        {
            options = str;
            str = '';
        }

        str = str || '';
        options = $.extend({}, $.fn.magicpreview.options, options);

        var ev = $.fn.magicpreview.events, len = ev.length;

        function change(e, n, o, i, onload)
        {
            if (options.onBefore() && (options.onLoad || !onload))
            {
                var st = ev[i].f(e), orig_st = st;

                if (st !== false) 
                {
                    st = st.replace(/\r|\n/mg, '<br />');
                    st = options.formatValue(st);
                }
                else
                {
                    st = o;
                }

                if (options.change === 'html') 
                {
                    n.html(st);
                }
                else if (options.change === 'text') 
                {
                    n.text(st);
                }
                else
                {
                    n.attr(options.change, st);
                }

                options.onAfter(orig_st);
            }
            return;
        }

        return this.filter(':text, :radio, :checkbox, select, textarea').each(function () {
            var e = this, n, o, i;

            if (options.child !== false)
            {
                n = $('#' + str + $(e).attr('name')).find(options.child);
            }
            else
            {
                n = $('#' + str + $(e).attr('name'));
            }

            if (options.change === 'html') 
            {
                o = n.html();
            }
            else if (options.change === 'text') 
            {
                o = n.text();
            }
            else
            {
                o = n.attr(options.change);
            }

            for (i = 0; i < len; i++)
            {
                if ($(e).is(ev[i].on)) 
                {
                    e.i = i; // Hack!

                    if (typeof ev[i].e !== 'undefined')
                    {
                        for (j in ev[i].e)
                        {
                            if (ev[i].e[j] === 'load')
                            {
                                change(e, n, o, e.i, true);
                            }
                            else if (typeof ev[i].e[j] === 'string')
                            {
                                $(e).bind(ev[i].e[j], function () {
                                    change(this, n, o, e.i, false);
                                });
                            }
                        }
                    }
                }
            }
        });
    };

    $.fn.magicpreview.events = [{
            'on': ':text, textarea',
            'e': ['keyup', 'load'],
            'f': function (e) {
                return ($(e).val().replace(/\n|\r/mg, '') !== '') ? $(e).val() : false;
            }
        }, {
            'on': ':checkbox, :radio',
            'e': ['click', 'load'],
            'f': function (e) {
                return ($(e).is(':checked')) ? $(e).val() : false;
            }
        }, {
            'on': 'select',
            'e': ['change', 'load'],
            'f': function (e) {
                return ($(e).attr('value') !== '' || $(e).attr('value') !== 'undefined') ? $(e).attr('value') : false;
            }
        }];

    $.fn.magicpreview.options = {
        'child': false,
        'change': 'html',
        'onLoad': true,
        'onBefore': function () { 
            return true;
        },
        'onAfter': function (val) { 
            return true; 
        },
        'formatValue': function (val) { 
            return val; 
        }
    };
})(jQuery);
Rafay
  • 30,950
  • 5
  • 68
  • 101
Terry
  • 13
  • 2
  • "the code doesnt seem set up to work with number fields" What is the symptom? Can you set up your code in jsfiddle.net so other people can help you easily? – Tae-Sung Shin Aug 23 '11 at 15:13
  • Im not sure, Im new to this. I just noticed that in the plug in code I posted above, nothing mentions number fields yet :text and :checkbox ect are mentioned. I cannot share my actual code, but I have simplified it here http://jsfiddle.net/jzP7D/2/ – Terry Aug 23 '11 at 15:31
  • Are you using HTML5? Otherwise you can't use input with type=number – Tae-Sung Shin Aug 23 '11 at 15:57
  • I am, yes. I need to use type=number to force the ipad keyboard to default to the numeric one when a user clicks on a telephone no field, for example. – Terry Aug 23 '11 at 16:02

2 Answers2

0

As I said in the comment, only HTML5 supports 'input' with 'type="number"' So I doubt the plugin works with <input type="number"> But I would just treat it as type="text" with special care. For more details, please see HTML Text Input allow only Numeric input

If you want to change the plugin, I would do like this.

(function ($) {
    $.fn.magicpreview = function (str, options) {

        if (typeof str === "object" && typeof options === "undefined") // If function(options)
        {
            options = str;
            str = '';
        }

        str = str || '';
        options = $.extend({}, $.fn.magicpreview.options, options);

        var ev = $.fn.magicpreview.events, len = ev.length;

        function change(e, n, o, i, onload)
        {
            if (options.onBefore() && (options.onLoad || !onload))
            {
                var st = ev[i].f(e), orig_st = st;

                if (st !== false) 
                {
                    st = st.replace(/\r|\n/mg, '<br />');
                    st = options.formatValue(st);
                }
                else
                {
                    st = o;
                }

                if (options.change === 'html') 
                {
                    n.html(st);
                }
                else if (options.change === 'text') 
                {
                    n.text(st);
                }
                else
                {
                    n.attr(options.change, st);
                }

                options.onAfter(orig_st);
            }
            return;
        }

        return this.filter(':text, [type=number], :radio, :checkbox, select, textarea').each(function () {
            var e = this, n, o, i;

            if (options.child !== false)
            {
                n = $('#' + str + $(e).attr('name')).find(options.child);
            }
            else
            {
                n = $('#' + str + $(e).attr('name'));
            }

            if (options.change === 'html') 
            {
                o = n.html();
            }
            else if (options.change === 'text') 
            {
                o = n.text();
            }
            else
            {
                o = n.attr(options.change);
            }

            for (i = 0; i < len; i++)
            {
                if ($(e).is(ev[i].on)) 
                {
                    e.i = i; // Hack!

                    if (typeof ev[i].e !== 'undefined')
                    {
                        for (j in ev[i].e)
                        {
                            if (ev[i].e[j] === 'load')
                            {
                                change(e, n, o, e.i, true);
                            }
                            else if (typeof ev[i].e[j] === 'string')
                            {
                                $(e).bind(ev[i].e[j], function () {
                                    change(this, n, o, e.i, false);
                                });
                            }
                        }
                    }
                }
            }
        });
    };

    $.fn.magicpreview.events = [{
            'on': ':text, textarea',
            'e': ['keyup', 'load'],
            'f': function (e) {
                return ($(e).val().replace(/\n|\r/mg, '') !== '') ? $(e).val() : false;
            }
        }, {
            'on': '[type=number]',
            'e': ['keyup', 'load'],
            'f': function (e) {
                return ($(e).val().replace(/\n|\r/mg, '') !== '') ? $(e).val() : false;
            }
        }, {
            'on': ':checkbox, :radio',
            'e': ['click', 'load'],
            'f': function (e) {
                return ($(e).is(':checked')) ? $(e).val() : false;
            }
        }, {
            'on': 'select',
            'e': ['change', 'load'],
            'f': function (e) {
                return ($(e).attr('value') !== '' || $(e).attr('value') !== 'undefined') ? $(e).attr('value') : false;
            }
        }];

    $.fn.magicpreview.options = {
        'child': false,
        'change': 'html',
        'onLoad': true,
        'onBefore': function () { 
            return true;
        },
        'onAfter': function (val) { 
            return true; 
        },
        'formatValue': function (val) { 
            return val; 
        }
    };
})(jQuery);

The key to my change is that since jquery does not know about number type, it seems that ":number" can't be used so I replace the selector "[type=number]" instead. Accordingly, you have to replace your selector in html in that way:

        $('form.textexample input:text').magicpreview('mp_');
        $('form.numberexample input[type=number]').magicpreview('mp_');

Please note that this modified plugin may alter the native behavior of <input type=number>. If this becomes your problem, you might have to implement the behavior manually into the plugin that I may not help.

Community
  • 1
  • 1
Tae-Sung Shin
  • 20,215
  • 33
  • 138
  • 240
  • Apologies, but it isnt enough to just allow only numeric input in a text field; I need to use type=number in order to default the keyboard on the ipad to the numeric one. – Terry Aug 23 '11 at 16:06
  • Yeah, in that case changing the plugin seems to be the only way. – Tae-Sung Shin Aug 23 '11 at 16:10
  • Thank you Sheen. Unfortunately, the changes you made didnt work, and stopped the rest of the plug in working as well. I am having difficulty spotting what else needs to be edited. – Terry Aug 24 '11 at 09:58
  • Indeed it was not working. I just looked at it. And I did some tweak that will be updated shortly. – Tae-Sung Shin Aug 24 '11 at 15:09
  • Just saw your answer as my browser didn't update my page for some reason. I will keep my change anyway. – Tae-Sung Shin Aug 24 '11 at 15:25
0

Used Sheen's changes, but added input[type="number"] instead of :number - :number jquery selector doesnt exist at the moment.

(function ($) {
    $.fn.magicpreview = function (str, options) {

        if (typeof str === "object" && typeof options === "undefined") // If function(options)
        {
            options = str;
            str = '';
        }

        str = str || '';
        options = $.extend({}, $.fn.magicpreview.options, options);

        var ev = $.fn.magicpreview.events, len = ev.length;

        function change(e, n, o, i, onload)
        {
            if (options.onBefore() && (options.onLoad || !onload))
            {
                var st = ev[i].f(e), orig_st = st;

                if (st !== false) 
                {
                    st = st.replace(/\r|\n/mg, '<br />');
                    st = options.formatValue(st);
                }
                else
                {
                    st = o;
                }

                if (options.change === 'html') 
                {
                    n.html(st);
                }
                else if (options.change === 'text') 
                {
                    n.text(st);
                }
                else
                {
                    n.attr(options.change, st);
                }

                options.onAfter(orig_st);
            }
            return;
        }

        return this.filter('input[type="number"], :text, :radio, :checkbox, select, textarea').each(function () {
            var e = this, n, o, i;

            if (options.child !== false)
            {
                n = $('#' + str + $(e).attr('name')).find(options.child);
            }
            else
            {
                n = $('#' + str + $(e).attr('name'));
            }

            if (options.change === 'html') 
            {
                o = n.html();
            }
            else if (options.change === 'text') 
            {
                o = n.text();
            }
            else
            {
                o = n.attr(options.change);
            }

            for (i = 0; i < len; i++)
            {
                if ($(e).is(ev[i].on)) 
                {
                    e.i = i; // Hack!

                    if (typeof ev[i].e !== 'undefined')
                    {
                        for (j in ev[i].e)
                        {
                            if (ev[i].e[j] === 'load')
                            {
                                change(e, n, o, e.i, true);
                            }
                            else if (typeof ev[i].e[j] === 'string')
                            {
                                $(e).bind(ev[i].e[j], function () {
                                    change(this, n, o, e.i, false);
                                });
                            }
                        }
                    }
                }
            }
        });
    };

    $.fn.magicpreview.events = [{
            'on': 'input[type="number"], :text, textarea',
            'e': ['keyup'],
            'f': function (e) {
                return ($(e).val().replace(/\n|\r/mg, '') !== '') ? $(e).val() : false;
            }
        }, {
            'on': ':checkbox, :radio',
            'e': ['click'],
            'f': function (e) {
                return ($(e).is(':checked')) ? $(e).val() : false;
            }
        }, {
            'on': 'select',
            'e': ['change'],
            'f': function (e) {
                return ($(e).attr('value') !== '' || $(e).attr('value') !== 'undefined') ? $(e).attr('value') : false;
            }
        }];

    $.fn.magicpreview.options = {
        'child': false,
        'change': 'html',
        'onLoad': true,
        'onBefore': function () { 
            return true;
        },
        'onAfter': function (val) { 
            return true; 
        },
        'formatValue': function (val) { 
            return val; 
        }
    };
})(jQuery);
Terry
  • 13
  • 2