├── README.markdown ├── jquery.inputs.js └── tests.html /README.markdown: -------------------------------------------------------------------------------- 1 | # jquery-inputs plugin 2 | 3 | jquery-inputs is a jQuery plugin that allows set/get on form inputs using hierarchical JSON structures 4 | 5 | ## Form Element Names 6 | 7 | Supports various naming conventions, e.g., demo_field_key, demo.field[key], and demo[field].key 8 | will all be treated as synonymous references to the same value. 9 | 10 | Empty brackets will automatically generate a 0-based index. 11 | 12 | ## Usage 13 | 14 | Include jQuery and the plugin: 15 | 16 | 17 | 18 | Create a demo form: 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | Set/get values via javascript: 40 | 41 | 58 | 59 | See [QUnit tests](https://github.com/dshimkoski/jquery-inputs/blob/master/tests.html) for further examples. 60 | 61 | ## Author 62 | 63 | [Denny Shimkoski](http://twitter.com/dennyshim) 64 | 65 | ## Other 66 | 67 | [MIT License](http://www.opensource.org/licenses/mit-license.php) 68 | 69 | Copyright (c) 2011, Denny Shimkoski (denny.webdev -[at]- gmail -[dot]- com) -------------------------------------------------------------------------------- /jquery.inputs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery-inputs is a jQuery plugin that allows set/get on form inputs using hierarchical JSON structures 3 | * 4 | * For usage and examples, visit: http://github.com/dshimkoski/jquery-inputs/ 5 | * 6 | * MIT license: http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright (c) 2011, Denny Shimkoski (denny.webdev -[at]- gmail -[dot]- com ) 9 | */ 10 | (function($, undefined){ 11 | 12 | var methods = { 13 | set: function(values) { 14 | 15 | // jquery form (technically could be any element with nested inputs) 16 | var $form = $(this); 17 | 18 | // scope for processInput() writes 19 | var scope = {}; 20 | 21 | // loop through form inputs 22 | $form.find(':input[name]').each(function(){ 23 | 24 | // jquery input 25 | var $input = $(this); 26 | 27 | // reference value structure 28 | var lookup = values; 29 | 30 | // set update flag to true 31 | var update = true; 32 | 33 | // clear input 34 | clearInput( $input ); 35 | 36 | // array of keys representing fully qualified value in json tree 37 | var keys = processInput( $input.attr('name'), null, scope ); 38 | 39 | // use keys for hierarchical lookup 40 | for( var i = 0, len = keys.length; i < len; i++ ) { 41 | var key = keys[i]; 42 | // no need to hunt further 43 | if( !lookup[key] ) { 44 | // set update to false to indicate failed lookup 45 | update = false; 46 | break; 47 | } 48 | // drill down into value structure 49 | lookup = lookup[key]; 50 | } 51 | 52 | // lookup succeeded 53 | if( update ) { 54 | 55 | //console.log('setting value', keys.slice(0, i + 1).join('_'), lookup); 56 | 57 | if( $input.is(':checkbox, :radio') ) { 58 | if( $.isArray(lookup) ) { 59 | for( var i = 0, len = lookup.length; i < len; i++ ) { 60 | $input.filter('[value='+lookup[i]+']').attr('checked', true); 61 | } 62 | } else { 63 | $input.filter('[value='+lookup+']').attr('checked', true); 64 | } 65 | } else { 66 | $input.val(lookup); 67 | } 68 | 69 | } 70 | 71 | }); 72 | 73 | }, 74 | get: function() { 75 | 76 | // scope for processInput() writes 77 | var scope = {}; 78 | 79 | // serialize form values 80 | $.each($(this).serializeArray(), function(){ 81 | // expands values in scope 82 | processInput( this.name, this.value, scope ); 83 | }); 84 | 85 | // scope will return value structure 86 | return scope; 87 | 88 | } 89 | }; 90 | 91 | function clearInput($input) { 92 | 93 | if( $input.is(':checkbox, :radio') ) { 94 | $input.attr('checked', false); 95 | } else { 96 | $input.val(''); 97 | } 98 | 99 | } 100 | 101 | function processInput(name, value, scope) { 102 | 103 | // keys used to build normalized name 104 | var keys = []; 105 | 106 | // index into name 107 | var p = 0; 108 | 109 | // current char 110 | var c; 111 | 112 | // key accumulator 113 | var key = ''; 114 | 115 | // last scope 116 | var last; 117 | 118 | // loop over chars in var name 119 | while( c = name[p++] ) { 120 | 121 | switch( c ) { 122 | 123 | case ' ': 124 | case '_': 125 | case '.': 126 | case '[': 127 | case ']': 128 | 129 | // empty brackets 130 | if( c === ']' && !key.length ) { 131 | // generate key... 132 | key = 0; 133 | // find largest int index 134 | for( var j in scope ) { 135 | if( scope.hasOwnProperty(j) && j % 1 === 0 ) { 136 | key = Math.max( parseInt(j, 10) + 1, key ); 137 | } 138 | } 139 | } 140 | 141 | // 0 index or key 142 | if( key === 0 || key ) { 143 | // save last scope 144 | last = {scope: scope, key: key}; 145 | // push new scope if necessary 146 | if( scope[key] === undefined ) { 147 | scope[key] = {}; 148 | } 149 | // descend into scope 150 | scope = scope[key]; 151 | // push key 152 | keys.push(key); 153 | } 154 | 155 | // clear key 156 | key = ''; 157 | 158 | break; 159 | 160 | default: 161 | 162 | // add char to key 163 | key += c; 164 | 165 | } 166 | 167 | } 168 | 169 | // leftover key from parse, e.g., key in form_key, form.key, and form[field].key 170 | if( key.length ) { 171 | // push key 172 | keys.push(key); 173 | } else { 174 | // form[key] requires us to backup since ] pushes new scope 175 | scope = last.scope; 176 | key = last.key; 177 | } 178 | 179 | // set value 180 | if( !scope[key] || $.isEmptyObject(scope[key]) ) { 181 | scope[key] = value; 182 | } else { 183 | if( !$.isArray(scope[key]) ) { 184 | scope[key] = [scope[key]]; 185 | } 186 | scope[key].push(value); 187 | } 188 | 189 | return keys; 190 | 191 | } 192 | 193 | $.fn.inputs = function(method) { 194 | 195 | if ( methods[method] ) { 196 | return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); 197 | } else { 198 | $.error( 'Method ' + method + ' does not exist on jQuery.inputs' ); 199 | } 200 | 201 | }; 202 | 203 | })(jQuery); 204 | -------------------------------------------------------------------------------- /tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 126 | 127 | 128 | 129 | 130 | 131 |

jquery-inputs plugin tests

132 |

133 |
134 |

135 |
    136 |
    137 |
    138 | 139 | 140 | 141 | 142 | 143 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 |
    158 |
    159 | 160 | 161 | 162 |
    163 |
    164 | 165 | 166 | 167 | 168 | --------------------------------------------------------------------------------