├── .gitignore ├── snapshot ├── snapshot01.png ├── snapshot02.png ├── snapshot03.png ├── snapshot04.png ├── snapshot05.png ├── snapshot06.png └── snapshot07.png ├── icon_font ├── font │ ├── iconfont.eot │ ├── iconfont.ttf │ ├── iconfont.woff │ └── iconfont.svg └── css │ └── icon_font.css ├── README.md ├── index.html ├── css └── jquery.transfer.css └── js └── jquery.transfer.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml -------------------------------------------------------------------------------- /snapshot/snapshot01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot01.png -------------------------------------------------------------------------------- /snapshot/snapshot02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot02.png -------------------------------------------------------------------------------- /snapshot/snapshot03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot03.png -------------------------------------------------------------------------------- /snapshot/snapshot04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot04.png -------------------------------------------------------------------------------- /snapshot/snapshot05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot05.png -------------------------------------------------------------------------------- /snapshot/snapshot06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot06.png -------------------------------------------------------------------------------- /snapshot/snapshot07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/snapshot/snapshot07.png -------------------------------------------------------------------------------- /icon_font/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/icon_font/font/iconfont.eot -------------------------------------------------------------------------------- /icon_font/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/icon_font/font/iconfont.ttf -------------------------------------------------------------------------------- /icon_font/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nekolr/jquery-transfer/HEAD/icon_font/font/iconfont.woff -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | A jQuery plugin that is a shuttle box. 3 | 4 | # Preview 5 | ![snapshot01](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot01.png) 6 | 7 | ![snapshot02](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot02.png) 8 | 9 | ![snapshot03](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot03.png) 10 | 11 | ![snapshot04](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot04.png) 12 | 13 | ![snapshot05](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot05.png) 14 | 15 | ![snapshot06](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot06.png) 16 | 17 | ![snapshot07](https://github.com/nekolr/jquery-transfer/blob/master/snapshot/snapshot07.png) 18 | 19 | # options 20 | | option | description | type | default | 21 | | ------------ | ------------ | ------------ | ------------ | 22 | | itemName | The name of each item in the data | string | item | 23 | | groupItemName | The name of each group in the data | string | groupItem | 24 | | groupArrayName | The name of the data array for each group | string | groupArray | 25 | | valueName | The value name of each item in the data | string | value | 26 | | tabNameText | The left tab text | string | items | 27 | | rightTabNameText | The right tab text | string | selected items | 28 | | searchPlaceholderText | The searcher's placeholder text | string | search | 29 | | dataArray | items data array | array | | 30 | | groupDataArray | grouping item data array | array | | 31 | 32 | # Usage 33 | 34 | ## grouping 35 | ```js 36 | var groupDataArray = [ 37 | { 38 | groupItem: "China", 39 | groupArray: [ 40 | { 41 | item: "Beijing", 42 | value: 1 43 | }, 44 | { 45 | item: "Shanghai", 46 | value: 2 47 | } 48 | ] 49 | }, 50 | { 51 | groupItem: "Japan", 52 | groupArray: [ 53 | { 54 | item: "Tokyo", 55 | value: 6 56 | } 57 | ] 58 | } 59 | ]; 60 | var settings = { 61 | groupDataArray: groupDataArray, 62 | callable: function (items) { 63 | // your code 64 | } 65 | }; 66 | 67 | var transfer = $(".transfer").transfer(settings); 68 | // get selected items 69 | transfer.getSelectedItems(); 70 | ``` 71 | 72 | ## no grouping 73 | ```js 74 | var dataArray = [ 75 | { 76 | item: "Beijing", 77 | value: 1 78 | }, 79 | { 80 | item: "Shanghai", 81 | value: 2 82 | }, 83 | { 84 | item: "Tokyo", 85 | value: 6 86 | } 87 | ]; 88 | var settings = { 89 | dataArray: dataArray, 90 | callable: function (items) { 91 | // your code 92 | } 93 | }; 94 | 95 | var transfer = $(".transfer").transfer(settings); 96 | // get selected items 97 | transfer.getSelectedItems(); 98 | ``` 99 | 100 | ## selected data 101 | 102 | ```js 103 | var dataArray = [ 104 | { 105 | item: "Beijing", 106 | value: 1, 107 | selected: true 108 | }, 109 | { 110 | item: "Shanghai", 111 | value: 2 112 | }, 113 | { 114 | item: "Tokyo", 115 | value: 6 116 | } 117 | ]; 118 | ``` 119 | 120 | ## disabled data 121 | ```js 122 | var dataArray = [ 123 | { 124 | item: "Beijing", 125 | value: 1, 126 | disabled: true 127 | }, 128 | { 129 | item: "Shanghai", 130 | value: 2 131 | }, 132 | { 133 | item: "Tokyo", 134 | value: 6 135 | } 136 | ]; 137 | ``` -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQuery transfer 7 | 8 | 9 | 16 | 17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 71 | 72 | 120 | 121 | 176 | 177 | 240 | 241 | -------------------------------------------------------------------------------- /css/jquery.transfer.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | body { 7 | font-family: "Microsoft YaHei", "SimSun"; 8 | border: none; 9 | font-size: 14px; 10 | color: #333; 11 | background: #f5f6fa; 12 | padding: 15px 0; 13 | line-height: 22px; 14 | } 15 | 16 | *, 17 | *::before, 18 | *::after { 19 | box-sizing: border-box; 20 | } 21 | 22 | .selected-hidden { 23 | display: none; 24 | } 25 | 26 | .checkbox-group .checkbox-normal { 27 | display: none; 28 | } 29 | 30 | .checkbox-group { 31 | display: inline-block; 32 | position: relative; 33 | } 34 | 35 | .checkbox-group label { 36 | display: inline-block; 37 | position: relative; 38 | padding-left: 25px; 39 | cursor: pointer; 40 | } 41 | 42 | .checkbox-group + .checkbox-group label { 43 | margin-left: 15px; 44 | } 45 | 46 | .clearfix:before, .clearfix:after { 47 | content: ""; 48 | display: table; 49 | } 50 | 51 | .radio-group label:before { 52 | content: ""; 53 | display: inline-block; 54 | width: 16px; 55 | height: 16px; 56 | position: absolute; 57 | top: 3px; 58 | left: 0px; 59 | background: #fcfcfc; 60 | border: 1px solid #bbb; 61 | } 62 | 63 | .radio-group .radio-normal + label:before { 64 | -webkit-border-radius: 10px; 65 | -moz-border-radius: 10px; 66 | border-radius: 10px; 67 | } 68 | 69 | .radio-group .radio-normal:hover + label:before { 70 | border-color: #197DD5; 71 | } 72 | 73 | .radio-group .radio-normal:checked + label:before { 74 | content: "\e6bf"; 75 | font-family: "iconfont"; 76 | color: #fff; 77 | font-size: 14px; 78 | line-height: 15px; 79 | border-color: #197DD5; 80 | text-align: center; 81 | background: #197DD5; 82 | } 83 | 84 | .radio-group .radio-normal:disabled + label:before { 85 | color: #fff; 86 | border: 1px solid #ccc; 87 | background: #ddd; 88 | cursor: not-allowed; 89 | } 90 | 91 | .checkbox-group label:before { 92 | content: ""; 93 | display: inline-block; 94 | width: 16px; 95 | height: 16px; 96 | position: absolute; 97 | top: 3px; 98 | left: 0; 99 | background: #fcfcfc; 100 | border: 1px solid #bbb; 101 | } 102 | 103 | /* 设置选中的 radio 的样式 + 是兄弟选择器,获取选中后的 label 元素 */ 104 | .checkbox-group .checkbox-normal + label:before { 105 | -webkit-border-radius: 3px; 106 | -moz-border-radius: 3px; 107 | border-radius: 3px; 108 | } 109 | 110 | .checkbox-group .checkbox-normal:hover + label:before { 111 | border-color: #197DD5; 112 | } 113 | 114 | .checkbox-group .checkbox-normal:checked + label:before { 115 | content: "\e93e"; 116 | font-family: "iconfont"; 117 | color: #fff; 118 | font-size: 12px; 119 | text-align: center; 120 | line-height: 13px; 121 | border-color: #197DD5; 122 | font-weight: bold; 123 | background: #197DD5; 124 | } 125 | 126 | .checkbox-group .checkbox-normal:disabled + label:before { 127 | color: #fff; 128 | border: 1px solid #ccc; 129 | background-color: #ddd; 130 | cursor: not-allowed; 131 | } 132 | 133 | .checkbox-group .checkbox-indeterminate + label:before { 134 | content: "\e95f"; 135 | font-family: "iconfont"; 136 | font-size: 14px; 137 | text-align: center; 138 | line-height: 15px; 139 | color: #fff; 140 | border-color: #197DD5; 141 | font-weight: bold; 142 | background: #197DD5; 143 | -webkit-border-radius: 3px; 144 | -moz-border-radius: 3px; 145 | border-radius: 3px; 146 | } 147 | 148 | .multi-select-active:after { 149 | content: "\e93e"; 150 | font-family: "iconfont"; 151 | margin-left: 64%; 152 | font-weight: bold; 153 | } 154 | 155 | .icon-single-add { 156 | font-size: 22px; 157 | position: absolute; 158 | margin-left: -30px; 159 | margin-top: 7px; 160 | } 161 | 162 | .icon-double-add { 163 | font-size: 22px; 164 | position: absolute; 165 | margin-left: -30px; 166 | margin-top: 7px; 167 | } 168 | 169 | .transfer-double { 170 | width: 640px; 171 | height: 390px; 172 | background-color: #fff; 173 | border: 1px solid #ddd; 174 | z-index: 1000; 175 | border-radius: 2px; 176 | box-shadow: 0 2px 5px rgba(0, 0, 0, .2); 177 | /* for firefox */ 178 | -moz-box-shadow: 0 2px 5px rgba(0, 0, 0, .2); 179 | /* for safari or chrome */ 180 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .2); 181 | } 182 | 183 | .transfer-double-header { 184 | padding: 10px 185 | } 186 | 187 | .transfer-double-content { 188 | padding: 10px 14px 30px 30px; 189 | } 190 | 191 | .transfer-double-content-left { 192 | display: inline-block; 193 | width: 258px; 194 | height: 320px; 195 | border: 1px solid #eee; 196 | border-radius: 2px; 197 | float: left; 198 | } 199 | 200 | .transfer-double-content-middle { 201 | display: inline-block; 202 | width: 35px; 203 | float: left; 204 | margin: 20% 15px 0 15px; 205 | text-align: center; 206 | } 207 | 208 | .transfer-double-content-right { 209 | display: inline-block; 210 | width: 258px; 211 | height: 320px; 212 | border: 1px solid #eee; 213 | border-radius: 2px; 214 | } 215 | 216 | .transfer-double-content-param { 217 | display: inline-block; 218 | width: 100%; 219 | height: 36px; 220 | line-height: 36px; 221 | border-bottom: 1px solid #eee; 222 | text-align: center; 223 | } 224 | 225 | .transfer-double-content-param .param-item { 226 | display: inline-block; 227 | height: 36px; 228 | line-height: 36px; 229 | } 230 | 231 | .vertical-separation-line { 232 | color: #eee; 233 | margin: 0 10px; 234 | } 235 | 236 | .transfer-double-list-header { 237 | padding: 8px 8px 6px 8px; 238 | text-align: center; 239 | } 240 | 241 | .transfer-double-list-search-input { 242 | width: 232px; 243 | height: 24px; 244 | line-height: 24px; 245 | border: 1px solid #ddd; 246 | padding: 5px 0 4px 8px; 247 | border-radius: 2px; 248 | } 249 | 250 | .transfer-double-list-content { 251 | padding: 3px 3px; 252 | } 253 | 254 | .transfer-double-list-main { 255 | height: 210px; 256 | overflow-y: auto; 257 | } 258 | 259 | .transfer-double-list-main .transfer-double-list-ul { 260 | list-style: none; 261 | padding-left: 25px; 262 | margin: 0; 263 | } 264 | 265 | .transfer-double-list-main .transfer-double-list-ul .transfer-double-list-li { 266 | margin-top: 5px; 267 | } 268 | 269 | .transfer-double-list-main .transfer-double-list-ul .transfer-double-list-li input { 270 | margin-right: 10px; 271 | } 272 | 273 | .transfer-double-list-main .transfer-double-group-list-ul { 274 | list-style: none; 275 | padding-left: 25px; 276 | margin: 0; 277 | } 278 | 279 | .transfer-double-list-main .transfer-double-group-list-ul .transfer-double-group-list-li { 280 | margin-top: 5px; 281 | } 282 | 283 | .transfer-double-list-main .transfer-double-group-list-ul .transfer-double-group-list-li .transfer-double-group-list-li-ul { 284 | list-style: none; 285 | margin-left: 25px; 286 | } 287 | 288 | .transfer-double-list-main .transfer-double-group-list-ul .transfer-double-group-list-li .transfer-double-group-list-li-ul .transfer-double-group-list-li-ul-li { 289 | margin-top: 5px; 290 | } 291 | 292 | .transfer-double-selected-list-header { 293 | padding: 8px 8px 6px 8px; 294 | text-align: center; 295 | } 296 | 297 | .transfer-double-selected-list-search-input { 298 | width: 232px; 299 | height: 24px; 300 | line-height: 24px; 301 | border: 1px solid #ddd; 302 | padding: 5px 0 4px 8px; 303 | border-radius: 2px; 304 | } 305 | 306 | .transfer-double-selected-list-content { 307 | padding: 3px 3px; 308 | } 309 | 310 | .transfer-double-selected-list-main { 311 | height: 210px; 312 | overflow-y: auto; 313 | } 314 | 315 | .transfer-double-selected-list-main .transfer-double-selected-list-ul { 316 | list-style: none; 317 | padding-left: 25px; 318 | margin: 0; 319 | } 320 | 321 | .transfer-double-selected-list-main .transfer-double-selected-list-ul .transfer-double-selected-list-li { 322 | margin-top: 5px; 323 | } 324 | 325 | .transfer-double-selected-list-main .transfer-double-selected-list-ul .transfer-double-selected-list-li .checkbox-group { 326 | width: 65%; 327 | } 328 | 329 | .transfer-double-selected-list-main .transfer-double-selected-list-ul .transfer-double-selected-list-li input[type="checkbox"] { 330 | margin-right: 10px; 331 | } 332 | 333 | .transfer-double-selected-list-main .transfer-double-selected-list-ul .transfer-double-selected-list-li input[type="text"] { 334 | min-width: 40px; 335 | width: 40px; 336 | min-height: 24px; 337 | height: 24px; 338 | } 339 | 340 | .transfer-double-list-footer { 341 | height: 24px; 342 | line-height: 24px; 343 | border-top: 1px solid #ddd; 344 | padding-left: 18px; 345 | color: #999; 346 | padding-top: 1px; 347 | } 348 | 349 | .transfer-double-list-footer span { 350 | margin-left: 20px; 351 | } 352 | 353 | .transfer-double-list-footer input { 354 | min-width: 40px; 355 | width: 40px; 356 | min-height: 24px; 357 | height: 24px; 358 | margin-left: 75px; 359 | } 360 | 361 | .transfer-double-list-footer .btn-setting { 362 | display: inline-block; 363 | margin-left: 5px; 364 | } 365 | 366 | .transfer-double-list-footer label { 367 | margin-left: 10px; 368 | } 369 | 370 | .transfer-double-footer { 371 | padding: 10px; 372 | text-align: right; 373 | } 374 | 375 | .btn-select-arrow { 376 | display: inline-block; 377 | width: 34px; 378 | height: 28px; 379 | line-height: 28px; 380 | color: #bbb; 381 | background: #e0e0e0; 382 | } 383 | 384 | .btn-select-arrow + .btn-select-arrow { 385 | margin-top: 10px; 386 | } 387 | 388 | .btn-arrow-active { 389 | color: #fff; 390 | background: #387EE8; 391 | } 392 | 393 | /* 394 | * clear float 395 | */ 396 | .clearfix:before, .clearfix:after { 397 | display: table; 398 | content: " "; 399 | } 400 | 401 | .clearfix:after { 402 | clear: both; 403 | } 404 | 405 | .clearfix { 406 | *zoom: 1; 407 | } 408 | 409 | /* 410 | * input placeholder style 411 | */ 412 | input::-webkit-input-placeholder { /* WebKit browsers */ 413 | font-size: 12px; 414 | color: #bbb; 415 | } 416 | 417 | input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ 418 | font-size: 12px; 419 | color: #bbb; 420 | } 421 | 422 | input::-moz-placeholder { /* Mozilla Firefox 19+ */ 423 | font-size: 12px; 424 | color: #bbb; 425 | } 426 | 427 | input:-ms-input-placeholder { /* Internet Explorer 10+ */ 428 | font-size: 12px; 429 | color: #bbb; 430 | } 431 | 432 | /* 433 | * webkit scrollbar 434 | */ 435 | .transfer-double-list-main::-webkit-scrollbar { 436 | width: 4px; 437 | height: 4px; 438 | } 439 | 440 | .transfer-double-list-main::-webkit-scrollbar-track { 441 | background: #f6f6f6; 442 | border-radius: 2px; 443 | } 444 | 445 | .transfer-double-list-main::-webkit-scrollbar-thumb { 446 | background: #ddd; 447 | border-radius: 2px; 448 | } 449 | 450 | .transfer-double-list-main::-webkit-scrollbar-thumb:hover { 451 | background: #999; 452 | } 453 | 454 | .transfer-double-list-main::-webkit-scrollbar-corner { 455 | background: #f6f6f6; 456 | } 457 | 458 | .transfer-double-selected-list-main::-webkit-scrollbar { 459 | width: 4px; 460 | height: 4px; 461 | } 462 | 463 | .transfer-double-selected-list-main::-webkit-scrollbar-track { 464 | background: #f6f6f6; 465 | border-radius: 2px; 466 | } 467 | 468 | .transfer-double-selected-list-main::-webkit-scrollbar-thumb { 469 | background: #ddd; 470 | border-radius: 2px; 471 | } 472 | 473 | .transfer-double-selected-list-main::-webkit-scrollbar-thumb:hover { 474 | background: #999; 475 | } 476 | 477 | .transfer-double-selected-list-main::-webkit-scrollbar-corner { 478 | background: #f6f6f6; 479 | } -------------------------------------------------------------------------------- /icon_font/css/icon_font.css: -------------------------------------------------------------------------------- 1 | 2 | @font-face {font-family: "iconfont"; 3 | src: url('../font/iconfont.eot?t=1519785387995'); /* IE9*/ 4 | src: url('../font/iconfont.eot?t=1519785387995#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'), 6 | url('../font/iconfont.ttf?t=1519785387995') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ 7 | url('../font/iconfont.svg?t=1519785387995#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family:"iconfont" !important; 12 | font-size:16px; 13 | font-style:normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .icon-loading:before { content: "\e64f"; } 19 | 20 | .icon-dot1:before { content: "\e654"; } 21 | 22 | .icon-iconfontscan:before { content: "\e603"; } 23 | 24 | .icon-dot-tmall:before { content: "\e602"; } 25 | 26 | .icon-cc-dot:before { content: "\e6bf"; } 27 | 28 | .icon-dot:before { content: "\e63f"; } 29 | 30 | .icon-tianjiayonghu:before { content: "\e65c"; } 31 | 32 | .icon-5yuan:before { content: "\e632"; } 33 | 34 | .icon-adduserregular:before { content: "\e604"; } 35 | 36 | .icon-shangjiantou:before { content: "\e600"; } 37 | 38 | .icon-xiajiantou:before { content: "\e601"; } 39 | 40 | .icon-rili:before { content: "\e8cf"; } 41 | 42 | .icon-rili-xianxing-xi:before { content: "\e915"; } 43 | 44 | .icon-add:before { content: "\e931"; } 45 | 46 | .icon-back:before { content: "\e934"; } 47 | 48 | .icon-close:before { content: "\e93c"; } 49 | 50 | .icon-complete-r:before { content: "\e93d"; } 51 | 52 | .icon-complete:before { content: "\e93e"; } 53 | 54 | .icon-dialog:before { content: "\e942"; } 55 | 56 | .icon-error-r:before { content: "\e946"; } 57 | 58 | .icon-exclamatory-mark-r:before { content: "\e947"; } 59 | 60 | .icon-extend:before { content: "\e949"; } 61 | 62 | .icon-exit-fullscreen:before { content: "\e94a"; } 63 | 64 | .icon-fullscreen:before { content: "\e94e"; } 65 | 66 | .icon-forward:before { content: "\e94d"; } 67 | 68 | .icon-info-r:before { content: "\e953"; } 69 | 70 | .icon-minus-r:before { content: "\e95d"; } 71 | 72 | .icon-minus:before { content: "\e95f"; } 73 | 74 | .icon-minus-s:before { content: "\e95e"; } 75 | 76 | .icon-search:before { content: "\e970"; } 77 | 78 | .icon-shrink:before { content: "\e973"; } 79 | 80 | .icon-add-o:before { content: "\e985"; } 81 | 82 | .icon-add-s-o:before { content: "\e986"; } 83 | 84 | .icon-add-r-o:before { content: "\e987"; } 85 | 86 | .icon-back-o:before { content: "\e989"; } 87 | 88 | .icon-back-r-o:before { content: "\e98a"; } 89 | 90 | .icon-checkbox-selected-o:before { content: "\e98f"; } 91 | 92 | .icon-close-o:before { content: "\e990"; } 93 | 94 | .icon-complete-r-o:before { content: "\e993"; } 95 | 96 | .icon-delete-o:before { content: "\e995"; } 97 | 98 | .icon-dialog-o:before { content: "\e996"; } 99 | 100 | .icon-edit-o:before { content: "\e999"; } 101 | 102 | .icon-error-r-o:before { content: "\e99a"; } 103 | 104 | .icon-drop-o:before { content: "\e99b"; } 105 | 106 | .icon-error-s-o:before { content: "\e99c"; } 107 | 108 | .icon-exclamatory-mark-r-o:before { content: "\e99d"; } 109 | 110 | .icon-extend-o:before { content: "\e99e"; } 111 | 112 | .icon-exit-fullscreen-o:before { content: "\e9a2"; } 113 | 114 | .icon-extend-r-o:before { content: "\e99f"; } 115 | 116 | .icon-forward-o:before { content: "\e9a0"; } 117 | 118 | .icon-forward-r-o:before { content: "\e9a1"; } 119 | 120 | .icon-fullscreen-o:before { content: "\e9a3"; } 121 | 122 | .icon-info-r-o:before { content: "\e9a6"; } 123 | 124 | .icon-minus-r-o:before { content: "\e9b0"; } 125 | 126 | .icon-minus-s-o:before { content: "\e9b1"; } 127 | 128 | .icon-rise-o:before { content: "\e9c2"; } 129 | 130 | .icon-search-o:before { content: "\e9c6"; } 131 | 132 | .icon-shrink-r-o:before { content: "\e9c9"; } 133 | 134 | .icon-shrink-o:before { content: "\e9ca"; } 135 | 136 | .icon-sort-o:before { content: "\e9cb"; } 137 | 138 | .icon-arrow-down:before { content: "\e9d8"; } 139 | 140 | .icon-arrow-left:before { content: "\e9d9"; } 141 | 142 | .icon-arrow-right:before { content: "\e9da"; } 143 | 144 | .icon-arrow-up:before { content: "\e9db"; } 145 | 146 | .icon-arrow-down1:before { content: "\e9dc"; } 147 | 148 | .icon-arrow-right1:before { content: "\e9dd"; } 149 | 150 | .icon-arrow-left1:before { content: "\e9de"; } 151 | 152 | .icon-arrow-up1:before { content: "\e9df"; } 153 | 154 | .icon-user-add:before { content: "\e739"; } 155 | -------------------------------------------------------------------------------- /icon_font/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | -------------------------------------------------------------------------------- /js/jquery.transfer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery transfer 3 | */ 4 | ;(function($) { 5 | 6 | var Transfer = function(element, options) { 7 | this.$element = element; 8 | // default options 9 | this.defaults = { 10 | // data item name 11 | itemName: "item", 12 | // group data item name 13 | groupItemName: "groupItem", 14 | // group data array name 15 | groupArrayName: "groupArray", 16 | // data value name 17 | valueName: "value", 18 | // tab text 19 | tabNameText: "items", 20 | // right tab text 21 | rightTabNameText: "selected items", 22 | // search placeholder text 23 | searchPlaceholderText: "search", 24 | // items data array 25 | dataArray: [], 26 | // group data array 27 | groupDataArray: [], 28 | // wildcard matching item search or searching from beginning of word 29 | wildcardSearch: true 30 | }; 31 | // merge options 32 | this.settings = $.extend(this.defaults, options); 33 | 34 | // tab text 35 | this.tabNameText = this.settings.tabNameText; 36 | // right tab text 37 | this.rightTabNameText = this.settings.rightTabNameText; 38 | // search placeholder text 39 | this.searchPlaceholderText = this.settings.searchPlaceholderText; 40 | // default total number text template 41 | this.default_total_num_text_template = "pre_num/total_num"; 42 | // default zero item 43 | this.default_right_item_total_num_text = get_total_num_text(this.default_total_num_text_template, 0, 0); 44 | // item total number 45 | this.item_total_num = this.settings.dataArray.length; 46 | // group item total number 47 | this.group_item_total_num = get_group_items_num(this.settings.groupDataArray, this.settings.groupArrayName); 48 | // use group 49 | this.isGroup = this.group_item_total_num > 0; 50 | // inner data 51 | this._data = new InnerMap(); 52 | // inner group data 53 | this._group_data = new InnerMap(); 54 | 55 | // Id 56 | this.id = (getId())(); 57 | // id selector for the item searcher 58 | this.itemSearcherId = "#listSearch_" + this.id; 59 | // id selector for the group item searcher 60 | this.groupItemSearcherId = "#groupListSearch_" + this.id; 61 | // id selector for the right searcher 62 | this.selectedItemSearcherId = "#selectedListSearch_" + this.id; 63 | 64 | // class selector for the transfer-double-list-ul 65 | this.transferDoubleListUlClass = ".transfer-double-list-ul-" + this.id; 66 | // class selector for the transfer-double-list-li 67 | this.transferDoubleListLiClass = ".transfer-double-list-li-" + this.id; 68 | // class selector for the left checkbox item 69 | this.checkboxItemClass = ".checkbox-item-" + this.id; 70 | // class selector for the left checkbox item label 71 | this.checkboxItemLabelClass = ".checkbox-name-" + this.id; 72 | // class selector for the left item total number label 73 | this.totalNumLabelClass = ".total_num_" + this.id; 74 | // id selector for the left item select all 75 | this.leftItemSelectAllId = "#leftItemSelectAll_" + this.id; 76 | 77 | // class selector for the transfer-double-group-list-ul 78 | this.transferDoubleGroupListUlClass = ".transfer-double-group-list-ul-" + this.id; 79 | // class selector for the transfer-double-group-list-li 80 | this.transferDoubleGroupListLiClass = ".transfer-double-group-list-li-" + this.id; 81 | // class selector for the group select all 82 | this.groupSelectAllClass = ".group-select-all-" + this.id; 83 | // class selector fro the transfer-double-group-list-li-ul-li 84 | this.transferDoubleGroupListLiUlLiClass = ".transfer-double-group-list-li-ul-li-" + this.id; 85 | // class selector for the group-checkbox-item 86 | this.groupCheckboxItemClass = ".group-checkbox-item-" + this.id; 87 | // class selector for the group-checkbox-name 88 | this.groupCheckboxNameLabelClass = ".group-checkbox-name-" + this.id; 89 | // class selector for the left group item total number label 90 | this.groupTotalNumLabelClass = ".group_total_num_" + this.id; 91 | // id selector for the left group item select all 92 | this.groupItemSelectAllId = "#groupItemSelectAll_" + this.id; 93 | 94 | // class selector for the transfer-double-selected-list-ul 95 | this.transferDoubleSelectedListUlClass = ".transfer-double-selected-list-ul-" + this.id; 96 | // class selector for the transfer-double-selected-list-li 97 | this.transferDoubleSelectedListLiClass = ".transfer-double-selected-list-li-" + this.id; 98 | // class selector for the right select checkbox item 99 | this.checkboxSelectedItemClass = ".checkbox-selected-item-" + this.id; 100 | // id selector for the right item select all 101 | this.rightItemSelectAllId = "#rightItemSelectAll_" + this.id; 102 | // class selector for the 103 | this.selectedTotalNumLabelClass = ".selected_total_num_" + this.id; 104 | // id selector for the add button 105 | this.addSelectedButtonId = "#add_selected_" + this.id; 106 | // id selector for the delete button 107 | this.deleteSelectedButtonId = "#delete_selected_" + this.id; 108 | } 109 | 110 | $.fn.transfer = function(options) { 111 | // new Transfer 112 | var transfer = new Transfer(this, options); 113 | // init 114 | transfer.init(); 115 | 116 | return { 117 | // get selected items 118 | getSelectedItems: function() { 119 | return get_selected_items(transfer) 120 | } 121 | } 122 | } 123 | 124 | /** 125 | * init 126 | */ 127 | Transfer.prototype.init = function() { 128 | // generate transfer 129 | this.$element.append(this.generate_transfer()); 130 | 131 | if (this.isGroup) { 132 | // fill group data 133 | this.fill_group_data(); 134 | 135 | // left group checkbox item click handler 136 | this.left_group_checkbox_item_click_handler(); 137 | // group select all handler 138 | this.group_select_all_handler(); 139 | // group item select all handler 140 | this.group_item_select_all_handler(); 141 | // left group items search handler 142 | this.left_group_items_search_handler(); 143 | 144 | } else { 145 | // fill data 146 | this.fill_data(); 147 | 148 | // left checkbox item click handler 149 | this.left_checkbox_item_click_handler(); 150 | // left item select all handler 151 | this.left_item_select_all_handler(); 152 | // left items search handler 153 | this.left_items_search_handler(); 154 | } 155 | 156 | // right checkbox item click handler 157 | this.right_checkbox_item_click_handler(); 158 | // move the pre-selection items to the right handler 159 | this.move_pre_selection_items_handler(); 160 | // move the selected item to the left handler 161 | this.move_selected_items_handler(); 162 | // right items search handler 163 | this.right_items_search_handler(); 164 | // right item select all handler 165 | this.right_item_select_all_handler(); 166 | } 167 | 168 | /** 169 | * generate transfer 170 | */ 171 | Transfer.prototype.generate_transfer = function() { 172 | 173 | var template = parseHTMLTemplate(function() { 174 | /* 175 |
176 |
177 |
178 | 179 | {{ // left part start }} 180 | 181 |
182 |
183 |
{{= self.tabNameText }}
184 |
185 | 186 | {{= self.isGroup ? self.generate_group_items_container() : self.generate_items_container() }} 187 | 188 |
189 | 190 | {{ // left part end }} 191 | 192 |
193 |
194 |
195 |
196 | 197 | {{ // right part start }} 198 | 199 |
200 |
201 |
{{= self.rightTabNameText }}
202 |
203 |
204 |
205 | 208 |
209 |
210 |
211 |
    212 |
    213 |
    214 | 220 |
    221 |
    222 | 223 | {{ // right part end }} 224 | 225 |
    226 | 227 |
    228 | */ 229 | }) 230 | 231 | var compiled = $.template(template); 232 | return compiled({ self: this }) 233 | } 234 | 235 | /** 236 | * generate group items container 237 | */ 238 | Transfer.prototype.generate_group_items_container = function() { 239 | 240 | var template = parseHTMLTemplate(function() { 241 | /* 242 |
    243 |
    244 | 247 |
    248 |
    249 |
    250 |
      251 |
      252 |
      253 | 258 |
      259 | */ 260 | }) 261 | 262 | var compiled = $.template(template); 263 | return compiled({ self: this }) 264 | } 265 | 266 | /** 267 | * generate items container 268 | */ 269 | Transfer.prototype.generate_items_container = function() { 270 | 271 | var template = parseHTMLTemplate(function() { 272 | /* 273 |
      274 |
      275 | 278 |
      279 |
      280 |
      281 |
        282 |
        283 |
        284 | 289 |
        290 | */ 291 | }) 292 | 293 | var compiled = $.template(template); 294 | return compiled({ self: this }) 295 | } 296 | 297 | /** 298 | * fill data 299 | */ 300 | Transfer.prototype.fill_data = function() { 301 | this.$element.find(this.transferDoubleListUlClass).empty(); 302 | this.$element.find(this.transferDoubleListUlClass).append(this.generate_left_items()); 303 | 304 | this.$element.find(this.transferDoubleSelectedListUlClass).empty(); 305 | this.$element.find(this.transferDoubleSelectedListUlClass).append(this.generate_right_items()); 306 | 307 | // render total num 308 | this.$element.find(this.totalNumLabelClass).empty(); 309 | this.$element.find(this.totalNumLabelClass).append(get_total_num_text(this.default_total_num_text_template, 0, this._data.get("left_total_count"))); 310 | 311 | // render right total num 312 | this.$element.find(this.selectedTotalNumLabelClass).empty(); 313 | this.$element.find(this.selectedTotalNumLabelClass).append(get_total_num_text(this.default_total_num_text_template, 0, this._data.get("right_total_count"))); 314 | } 315 | 316 | /** 317 | * fill group data 318 | */ 319 | Transfer.prototype.fill_group_data = function() { 320 | this.$element.find(this.transferDoubleGroupListUlClass).empty(); 321 | this.$element.find(this.transferDoubleGroupListUlClass).append(this.generate_left_group_items()); 322 | 323 | this.$element.find(this.transferDoubleSelectedListUlClass).empty(); 324 | this.$element.find(this.transferDoubleSelectedListUlClass).append(this.generate_right_group_items()); 325 | 326 | var self = this; 327 | var left_total_count = 0; 328 | this._group_data.forEach(function(key, value) { 329 | left_total_count += value["left_total_count"] 330 | value["left_total_count"] == 0 ? self.$element.find("#" + key).prop("disabled", true).prop("checked", true) : void(0) 331 | }) 332 | 333 | // render total num 334 | this.$element.find(this.groupTotalNumLabelClass).empty(); 335 | this.$element.find(this.groupTotalNumLabelClass).append(get_total_num_text(this.default_total_num_text_template, 0, left_total_count)); 336 | 337 | // render right total num 338 | this.$element.find(this.selectedTotalNumLabelClass).empty(); 339 | this.$element.find(this.selectedTotalNumLabelClass).append(get_total_num_text(this.default_total_num_text_template, 0, this._data.get("right_total_count"))); 340 | } 341 | 342 | /** 343 | * generate left items 344 | */ 345 | Transfer.prototype.generate_left_items = function() { 346 | var html = ""; 347 | var dataArray = this.settings.dataArray; 348 | var itemName = this.settings.itemName; 349 | var valueName = this.settings.valueName; 350 | 351 | var template = parseHTMLTemplate(function() { 352 | /* 353 |
      • 354 |
        355 | 356 | 357 |
        358 |
      • 359 | */ 360 | }) 361 | 362 | for (var i = 0; i < dataArray.length; i++) { 363 | 364 | var selected = dataArray[i].selected || false; 365 | var disabled = dataArray[i].disabled || false; 366 | var right_total_count = this._data.get("right_total_count") || 0; 367 | var disabled_count = this._data.get("left_disabled_count") || 0; 368 | this._data.get("right_total_count") == undefined ? this._data.put("right_total_count", right_total_count) : void(0) 369 | selected ? this._data.put("right_total_count", ++right_total_count) : void(0) 370 | !selected && disabled ? this._data.put("left_disabled_count", ++disabled_count) : void(0) 371 | 372 | var compiled = $.template(template); 373 | html += compiled({ self: this, dataArray: dataArray, i: i, itemName: itemName, valueName: valueName, selected: selected, disabled: disabled }) 374 | } 375 | 376 | this._data.put("left_pre_selection_count", 0); 377 | this._data.put("left_total_count", dataArray.length - this._data.get("right_total_count")); 378 | 379 | return html; 380 | } 381 | 382 | /** 383 | * render left group items 384 | */ 385 | Transfer.prototype.generate_left_group_items = function() { 386 | var html = ""; 387 | var id = this.id; 388 | var groupDataArray = this.settings.groupDataArray; 389 | var groupItemName = this.settings.groupItemName; 390 | var groupArrayName = this.settings.groupArrayName; 391 | var itemName = this.settings.itemName; 392 | var valueName = this.settings.valueName; 393 | 394 | var groupItemTemplate = parseHTMLTemplate(function() { 395 | /* 396 |
      • 397 |
        398 | 399 | 400 |
        401 |
      • 402 | */ 403 | }) 404 | 405 | var groupTemplate = parseHTMLTemplate(function() { 406 | /* 407 |
      • 408 |
        409 | 410 | 411 |
        412 |
      • ' 441 | } 442 | } 443 | 444 | return html; 445 | } 446 | 447 | /** 448 | * generate right items 449 | */ 450 | Transfer.prototype.generate_right_items = function() { 451 | var html = ""; 452 | var dataArray = this.settings.dataArray; 453 | var itemName = this.settings.itemName; 454 | var valueName = this.settings.valueName; 455 | var selected_count = 0; 456 | var disabled_count = 0; 457 | 458 | this._data.put("right_pre_selection_count", selected_count); 459 | this._data.put("right_total_count", selected_count); 460 | 461 | for (var i = 0; i < dataArray.length; i++) { 462 | if (dataArray[i].selected || false) { 463 | var disabled = dataArray[i].disabled || false; 464 | disabled ? disabled_count++ : void(0) 465 | this._data.put("right_total_count", ++selected_count); 466 | html += this.generate_item(this.id, i, dataArray[i][valueName], dataArray[i][itemName], disabled); 467 | } 468 | } 469 | 470 | this._data.put("right_disabled_count", disabled_count); 471 | 472 | if (this._data.get("right_total_count") == 0) { 473 | $(this.rightItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 474 | } 475 | 476 | return html; 477 | } 478 | 479 | /** 480 | * generate right group items 481 | */ 482 | Transfer.prototype.generate_right_group_items = function() { 483 | var html = ""; 484 | var groupDataArray = this.settings.groupDataArray; 485 | var groupArrayName = this.settings.groupArrayName; 486 | var itemName = this.settings.itemName; 487 | var valueName = this.settings.valueName; 488 | var selected_count = 0; 489 | 490 | this._data.put("right_pre_selection_count", selected_count); 491 | this._data.put("right_total_count", selected_count); 492 | 493 | for (var i = 0; i < groupDataArray.length; i++) { 494 | if (groupDataArray[i][groupArrayName] && groupDataArray[i][groupArrayName].length > 0) { 495 | for (var j = 0; j < groupDataArray[i][groupArrayName].length; j++) { 496 | if (groupDataArray[i][groupArrayName][j].selected || false) { 497 | this._data.put("right_total_count", ++selected_count); 498 | html += this.generate_group_item(this.id, i, j, groupDataArray[i][groupArrayName][j][valueName], groupDataArray[i][groupArrayName][j][itemName]); 499 | } 500 | } 501 | } 502 | } 503 | 504 | if (this._data.get("right_total_count") == 0) { 505 | $(this.rightItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 506 | } 507 | 508 | return html; 509 | } 510 | 511 | /** 512 | * left checkbox item click handler 513 | */ 514 | Transfer.prototype.left_checkbox_item_click_handler = function() { 515 | var self = this; 516 | self.$element.on("click", self.checkboxItemClass, function () { 517 | var pre_selection_num = 0; 518 | $(this).is(":checked") ? pre_selection_num++ : pre_selection_num-- 519 | 520 | var left_pre_selection_count = self._data.get("left_pre_selection_count"); 521 | self._data.put("left_pre_selection_count", left_pre_selection_count + pre_selection_num); 522 | self.$element.find(self.totalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("left_pre_selection_count"), self._data.get("left_total_count"))); 523 | 524 | if (self._data.get("left_pre_selection_count") > 0) { 525 | $(self.addSelectedButtonId).addClass("btn-arrow-active"); 526 | } else { 527 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 528 | } 529 | 530 | if (self._data.get("left_pre_selection_count") < self._data.get("left_total_count")) { 531 | $(self.leftItemSelectAllId).prop("checked", false); 532 | } else if (self._data.get("left_pre_selection_count") == self._data.get("left_total_count")) { 533 | $(self.leftItemSelectAllId).prop("checked", true); 534 | } 535 | if (self._data.get("left_pre_selection_count") == (self._data.get("left_total_count") - self._data.get("left_disabled_count"))) { 536 | $(self.leftItemSelectAllId).prop("checked", true); 537 | } 538 | }); 539 | } 540 | 541 | /** 542 | * left group checkbox item click handler 543 | */ 544 | Transfer.prototype.left_group_checkbox_item_click_handler = function() { 545 | var self = this; 546 | self.$element.on("click", self.groupCheckboxItemClass, function () { 547 | var pre_selection_num = 0; 548 | var total_pre_selection_num = 0; 549 | var remain_left_total_count = 0 550 | 551 | $(this).is(":checked") ? pre_selection_num++ : pre_selection_num-- 552 | 553 | var groupIndex = $(this).prop("id").split("_")[1]; 554 | var groupItem = self._group_data.get('group_' + groupIndex + '_' + self.id); 555 | var left_pre_selection_count = groupItem["left_pre_selection_count"]; 556 | groupItem["left_pre_selection_count"] = left_pre_selection_count + pre_selection_num 557 | 558 | self._group_data.forEach(function(key, value) { 559 | total_pre_selection_num += value["left_pre_selection_count"] 560 | remain_left_total_count += value["left_total_count"] 561 | }); 562 | 563 | self.$element.find(self.groupTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, total_pre_selection_num, remain_left_total_count)); 564 | 565 | if (total_pre_selection_num > 0) { 566 | $(self.addSelectedButtonId).addClass("btn-arrow-active"); 567 | } else { 568 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 569 | } 570 | 571 | if (groupItem["left_pre_selection_count"] < groupItem["left_total_count"]) { 572 | self.$element.find("#group_" + groupIndex + "_" + self.id).prop("checked", false); 573 | } else if (groupItem["left_pre_selection_count"] == groupItem["left_total_count"]) { 574 | self.$element.find("#group_" + groupIndex + "_" + self.id).prop("checked", true); 575 | } 576 | 577 | if (total_pre_selection_num == remain_left_total_count) { 578 | $(self.groupItemSelectAllId).prop("checked", true); 579 | } else { 580 | $(self.groupItemSelectAllId).prop("checked", false); 581 | } 582 | }); 583 | } 584 | 585 | /** 586 | * group select all handler 587 | */ 588 | Transfer.prototype.group_select_all_handler = function() { 589 | var self = this; 590 | $(self.groupSelectAllClass).on("click", function () { 591 | // group index 592 | var groupIndex = ($(this).attr("id")).split("_")[1]; 593 | var groups = self.$element.find(".belongs-group-" + groupIndex + "-" + self.id); 594 | var left_pre_selection_count = 0; 595 | var left_total_count = 0; 596 | 597 | // a group is checked 598 | if ($(this).is(':checked')) { 599 | // active button 600 | $(self.addSelectedButtonId).addClass("btn-arrow-active"); 601 | for (var i = 0; i < groups.length; i++) { 602 | if (!groups.eq(i).is(':checked') && groups.eq(i).parent("div").parent("li").css("display") != "none") { 603 | groups.eq(i).prop("checked", true); 604 | } 605 | } 606 | 607 | var groupItem = self._group_data.get($(this).prop("id")); 608 | groupItem["left_pre_selection_count"] = groupItem["left_total_count"]; 609 | 610 | self._group_data.forEach(function(key, value) { 611 | left_pre_selection_count += value["left_pre_selection_count"]; 612 | left_total_count += value["left_total_count"]; 613 | }) 614 | 615 | if (left_pre_selection_count == left_total_count) { 616 | $(self.groupItemSelectAllId).prop("checked", true); 617 | } 618 | } else { 619 | for (var j = 0; j < groups.length; j++) { 620 | if (groups.eq(j).is(':checked') && groups.eq(j).parent("div").parent("li").css("display") != "none") { 621 | groups.eq(j).prop("checked", false); 622 | } 623 | } 624 | 625 | self._group_data.get($(this).prop("id"))["left_pre_selection_count"] = 0; 626 | 627 | self._group_data.forEach(function(key, value) { 628 | left_pre_selection_count += value["left_pre_selection_count"]; 629 | left_total_count += value["left_total_count"]; 630 | }) 631 | 632 | if (left_pre_selection_count != left_total_count) { 633 | $(self.groupItemSelectAllId).prop("checked", false); 634 | } 635 | 636 | if (left_pre_selection_count == 0) { 637 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 638 | } 639 | } 640 | self.$element.find(self.groupTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, left_pre_selection_count, left_total_count)); 641 | }); 642 | } 643 | 644 | /** 645 | * group item select all handler 646 | */ 647 | Transfer.prototype.group_item_select_all_handler = function() { 648 | var self = this; 649 | $(self.groupItemSelectAllId).on("click", function () { 650 | var groupCheckboxItems = self.$element.find(self.groupCheckboxItemClass); 651 | var left_pre_selection_count = 0; 652 | var left_total_count = 0; 653 | if ($(this).is(':checked')) { 654 | for (var i = 0; i < groupCheckboxItems.length; i++) { 655 | if (groupCheckboxItems.parent("div").parent("li").eq(i).css('display') != "none" && !groupCheckboxItems.eq(i).is(':checked')) { 656 | groupCheckboxItems.eq(i).prop("checked", true); 657 | var groupIndex = groupCheckboxItems.eq(i).prop("id").split("_")[1]; 658 | if (!self.$element.find(self.groupSelectAllClass).eq(groupIndex).is(':checked')) { 659 | self.$element.find(self.groupSelectAllClass).eq(groupIndex).prop("checked", true); 660 | } 661 | } 662 | } 663 | 664 | self._group_data.forEach(function (key, value) { 665 | value["left_pre_selection_count"] = value["left_total_count"]; 666 | left_pre_selection_count += value["left_pre_selection_count"]; 667 | left_total_count += value["left_total_count"]; 668 | }) 669 | 670 | $(self.addSelectedButtonId).addClass("btn-arrow-active"); 671 | } else { 672 | for (var i = 0; i < groupCheckboxItems.length; i++) { 673 | if (groupCheckboxItems.parent("div").parent("li").eq(i).css('display') != "none" && groupCheckboxItems.eq(i).is(':checked')) { 674 | groupCheckboxItems.eq(i).prop("checked", false); 675 | var groupIndex = groupCheckboxItems.eq(i).prop("id").split("_")[1]; 676 | if (self.$element.find(self.groupSelectAllClass).eq(groupIndex).is(':checked')) { 677 | self.$element.find(self.groupSelectAllClass).eq(groupIndex).prop("checked", false); 678 | } 679 | } 680 | } 681 | 682 | self._group_data.forEach(function (key, value) { 683 | value["left_pre_selection_count"] = 0; 684 | left_pre_selection_count = 0; 685 | left_total_count += value["left_total_count"]; 686 | }) 687 | 688 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 689 | } 690 | self.$element.find(self.groupTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, left_pre_selection_count, left_total_count)); 691 | }); 692 | } 693 | 694 | /** 695 | * left group items search handler 696 | */ 697 | Transfer.prototype.left_group_items_search_handler = function() { 698 | var self = this; 699 | $(self.groupItemSearcherId).on("keyup", function () { 700 | self.$element.find(self.transferDoubleGroupListUlClass).css('display', 'block'); 701 | var transferDoubleGroupListLiUlLis = self.$element.find(self.transferDoubleGroupListLiUlLiClass); 702 | if ($(self.groupItemSearcherId).val() == "") { 703 | for (var i = 0; i < transferDoubleGroupListLiUlLis.length; i++) { 704 | if (!transferDoubleGroupListLiUlLis.eq(i).hasClass("selected-hidden")) { 705 | transferDoubleGroupListLiUlLis.eq(i).parent("ul").parent("li").css('display', 'block'); 706 | transferDoubleGroupListLiUlLis.eq(i).css('display', 'block'); 707 | } else { 708 | transferDoubleGroupListLiUlLis.eq(i).parent("ul").parent("li").css('display', 'block'); 709 | } 710 | } 711 | return; 712 | } 713 | 714 | // Mismatch 715 | self.$element.find(self.transferDoubleGroupListLiClass).css('display', 'none'); 716 | transferDoubleGroupListLiUlLis.css('display', 'none'); 717 | 718 | for (var j = 0; j < transferDoubleGroupListLiUlLis.length; j++) { 719 | if (!transferDoubleGroupListLiUlLis.eq(j).hasClass("selected-hidden") 720 | && transferDoubleGroupListLiUlLis.eq(j).text().trim() 721 | .substr(0, $(self.groupItemSearcherId).val().length).toLowerCase() == $(self.groupItemSearcherId).val().toLowerCase()) { 722 | transferDoubleGroupListLiUlLis.eq(j).parent("ul").parent("li").css('display', 'block'); 723 | transferDoubleGroupListLiUlLis.eq(j).css('display', 'block'); 724 | } 725 | } 726 | }); 727 | } 728 | 729 | /** 730 | * left item select all handler 731 | */ 732 | Transfer.prototype.left_item_select_all_handler = function() { 733 | var self = this; 734 | $(self.leftItemSelectAllId).on("click", function () { 735 | var checkboxItems = self.$element.find(self.checkboxItemClass); 736 | var pre_selection_num = self._data.get("left_pre_selection_count"); 737 | if ($(this).is(':checked')) { 738 | for (var i = 0; i < checkboxItems.length; i++) { 739 | if (!checkboxItems.eq(i).prop("disabled")) { 740 | if (checkboxItems.eq(i).parent("div").parent("li").css('display') != "none" && !checkboxItems.eq(i).is(':checked') && !checkboxItems.eq(i).prop('disabled')) { 741 | checkboxItems.eq(i).prop("checked", true); 742 | self._data.put("left_pre_selection_count", ++pre_selection_num); 743 | } 744 | } 745 | } 746 | $(self.addSelectedButtonId).addClass("btn-arrow-active"); 747 | } else { 748 | for (var i = 0; i < checkboxItems.length; i++) { 749 | if (checkboxItems.eq(i).parent("div").parent("li").css('display') != "none" && checkboxItems.eq(i).is(':checked')) { 750 | checkboxItems.eq(i).prop("checked", false); 751 | } 752 | } 753 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 754 | self._data.put("left_pre_selection_count", 0); 755 | } 756 | self.$element.find(self.totalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("left_pre_selection_count"), self._data.get("left_total_count"))); 757 | }); 758 | } 759 | 760 | /** 761 | * right item select all handler 762 | */ 763 | Transfer.prototype.right_item_select_all_handler = function() { 764 | var self = this; 765 | $(self.rightItemSelectAllId).on("click", function () { 766 | var checkboxSelectedItems = self.$element.find(self.checkboxSelectedItemClass); 767 | if ($(this).is(':checked')) { 768 | self._data.put("right_pre_selection_count", 0); 769 | var right_pre_selection_count = self._data.get("right_pre_selection_count"); 770 | for (var i = 0; i < checkboxSelectedItems.length; i++) { 771 | if (checkboxSelectedItems.eq(i).parent("div").parent("li").css('display') != "none" && !checkboxSelectedItems.eq(i).prop("disabled")) { 772 | checkboxSelectedItems.eq(i).prop("checked", true); 773 | self._data.put("right_pre_selection_count", ++right_pre_selection_count); 774 | } 775 | } 776 | 777 | $(self.deleteSelectedButtonId).addClass("btn-arrow-active"); 778 | 779 | if (self._data.get("right_pre_selection_count") < self._data.get("right_total_count")) { 780 | $(self.rightItemSelectAllId).prop("checked", false); 781 | } else if (self._data.get("right_pre_selection_count") == self._data.get("right_total_count")) { 782 | $(self.rightItemSelectAllId).prop("checked", true); 783 | } 784 | if (self._data.get("right_pre_selection_count") == self._data.get("right_total_count") - self._data.get("right_disabled_count")) { 785 | $(self.rightItemSelectAllId).prop("checked", true); 786 | } 787 | 788 | } else { 789 | for (var i = 0; i < checkboxSelectedItems.length; i++) { 790 | if (checkboxSelectedItems.eq(i).parent("div").parent("li").css('display') != "none" && checkboxSelectedItems.eq(i).is(':checked')) { 791 | checkboxSelectedItems.eq(i).prop("checked", false); 792 | } 793 | } 794 | $(self.deleteSelectedButtonId).removeClass("btn-arrow-active"); 795 | self._data.put("right_pre_selection_count", 0); 796 | } 797 | 798 | self.$element.find(self.selectedTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("right_pre_selection_count"), self._data.get("right_total_count"))); 799 | 800 | }); 801 | } 802 | 803 | /** 804 | * left items search handler 805 | */ 806 | Transfer.prototype.left_items_search_handler = function() { 807 | var self = this; 808 | $(self.itemSearcherId).on("keyup", function () { 809 | var transferDoubleListLis = self.$element.find(self.transferDoubleListLiClass); 810 | self.$element.find(self.transferDoubleListUlClass).css('display', 'block'); 811 | if ($(self.itemSearcherId).val() == "") { 812 | for (var i = 0; i < transferDoubleListLis.length; i++) { 813 | if (!transferDoubleListLis.eq(i).hasClass("selected-hidden")) { 814 | self.$element.find(self.transferDoubleListLiClass).eq(i).css('display', 'block'); 815 | } 816 | } 817 | return; 818 | } 819 | 820 | transferDoubleListLis.css('display', 'none'); 821 | 822 | if (self.settings.wildcardSearch) { 823 | for (var j = 0; j < transferDoubleListLis.length; j++) { 824 | if (!transferDoubleListLis.eq(j).hasClass("selected-hidden") 825 | && transferDoubleListLis.eq(j).text().trim() 826 | .toLowerCase().indexOf($(self.itemSearcherId).val().toLowerCase()) > -1 ) { 827 | transferDoubleListLis.eq(j).css('display', 'block'); 828 | } 829 | } 830 | } else { 831 | for (var j = 0; j < transferDoubleListLis.length; j++) { 832 | if (!transferDoubleListLis.eq(j).hasClass("selected-hidden") 833 | && transferDoubleListLis.eq(j).text().trim() 834 | .substr(0, $(self.itemSearcherId).val().length).toLowerCase() == $(self.itemSearcherId).val().toLowerCase()) { 835 | transferDoubleListLis.eq(j).css('display', 'block'); 836 | } 837 | } 838 | } 839 | }); 840 | } 841 | 842 | /** 843 | * right checkbox item click handler 844 | */ 845 | Transfer.prototype.right_checkbox_item_click_handler = function() { 846 | var self = this; 847 | self.$element.on("click", self.checkboxSelectedItemClass, function () { 848 | var pre_selection_num = 0; 849 | $(this).is(":checked") ? pre_selection_num++ : pre_selection_num-- 850 | 851 | var right_pre_selection_count = self._data.get("right_pre_selection_count"); 852 | self._data.put("right_pre_selection_count", right_pre_selection_count + pre_selection_num); 853 | self.$element.find(self.selectedTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("right_pre_selection_count"), self._data.get("right_total_count"))); 854 | 855 | if (self._data.get("right_pre_selection_count") > 0) { 856 | $(self.deleteSelectedButtonId).addClass("btn-arrow-active"); 857 | } else { 858 | $(self.deleteSelectedButtonId).removeClass("btn-arrow-active"); 859 | } 860 | 861 | if (self._data.get("right_pre_selection_count") < self._data.get("right_total_count")) { 862 | $(self.rightItemSelectAllId).prop("checked", false); 863 | } else if (self._data.get("right_pre_selection_count") == self._data.get("right_total_count")) { 864 | $(self.rightItemSelectAllId).prop("checked", true); 865 | } 866 | if (self._data.get("right_pre_selection_count") == self._data.get("right_total_count") - self._data.get("right_disabled_count")) { 867 | $(self.rightItemSelectAllId).prop("checked", true); 868 | } 869 | 870 | }); 871 | } 872 | 873 | /** 874 | * move the pre-selection items to the right handler 875 | */ 876 | Transfer.prototype.move_pre_selection_items_handler = function() { 877 | var self = this; 878 | $(self.addSelectedButtonId).on("click", function () { 879 | if ($(this).hasClass("btn-arrow-active")) { 880 | self.isGroup ? self.move_pre_selection_group_items() : self.move_pre_selection_items() 881 | // callable 882 | applyCallable(self); 883 | } 884 | }); 885 | } 886 | 887 | /** 888 | * move the pre-selection group items to the right 889 | */ 890 | Transfer.prototype.move_pre_selection_group_items = function() { 891 | var pre_selection_num = 0; 892 | var html = ""; 893 | var groupCheckboxItems = this.$element.find(this.groupCheckboxItemClass); 894 | for (var i = 0; i < groupCheckboxItems.length; i++) { 895 | if (!groupCheckboxItems.eq(i).parent("div").parent("li").hasClass("selected-hidden") && groupCheckboxItems.eq(i).is(':checked')) { 896 | var checkboxItemId = groupCheckboxItems.eq(i).attr("id"); 897 | var groupIndex = checkboxItemId.split("_")[1]; 898 | var itemIndex = checkboxItemId.split("_")[3]; 899 | var labelText = this.$element.find(this.groupCheckboxNameLabelClass).eq(i).text(); 900 | var value = groupCheckboxItems.eq(i).val(); 901 | 902 | html += this.generate_group_item(this.id, groupIndex, itemIndex, value, labelText); 903 | groupCheckboxItems.parent("div").parent("li").eq(i).css("display", "").addClass("selected-hidden"); 904 | pre_selection_num++; 905 | 906 | var groupItem = this._group_data.get('group_' + groupIndex + '_' + this.id); 907 | var left_total_count = groupItem["left_total_count"]; 908 | var left_pre_selection_count = groupItem["left_pre_selection_count"]; 909 | var right_total_count = this._data.get("right_total_count"); 910 | groupItem["left_total_count"] = --left_total_count; 911 | groupItem["left_pre_selection_count"] = --left_pre_selection_count; 912 | this._data.put("right_total_count", ++right_total_count); 913 | } 914 | } 915 | 916 | if (pre_selection_num > 0) { 917 | var groupSelectAllArray = this.$element.find(this.groupSelectAllClass); 918 | for (var j = 0; j < groupSelectAllArray.length; j++) { 919 | if (groupSelectAllArray.eq(j).is(":checked")) { 920 | groupSelectAllArray.eq(j).prop("disabled", "disabled"); 921 | } 922 | } 923 | 924 | var remain_left_total_count = 0; 925 | this._group_data.forEach(function(key, value) { 926 | remain_left_total_count += value["left_total_count"]; 927 | }) 928 | 929 | var groupTotalNumLabel = this.$element.find(this.groupTotalNumLabelClass); 930 | groupTotalNumLabel.text(get_total_num_text(this.default_total_num_text_template, 0, remain_left_total_count)); 931 | this.$element.find(this.selectedTotalNumLabelClass).text(get_total_num_text(this.default_total_num_text_template, 0, this._data.get("right_total_count"))); 932 | 933 | if (remain_left_total_count == 0) { 934 | $(this.groupItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 935 | } 936 | 937 | if (this._data.get("right_total_count") > 0) { 938 | $(this.rightItemSelectAllId).prop("checked", false).removeAttr("disabled"); 939 | } 940 | 941 | $(this.addSelectedButtonId).removeClass("btn-arrow-active"); 942 | var transferDoubleSelectedListUl = this.$element.find(this.transferDoubleSelectedListUlClass); 943 | transferDoubleSelectedListUl.append(html); 944 | } 945 | } 946 | 947 | /** 948 | * move the pre-selection items to the right 949 | */ 950 | Transfer.prototype.move_pre_selection_items = function() { 951 | var pre_selection_num = 0; 952 | var html = ""; 953 | var self = this; 954 | var checkboxItems = self.$element.find(self.checkboxItemClass); 955 | for (var i = 0; i < checkboxItems.length; i++) { 956 | if (checkboxItems.eq(i).parent("div").parent("li").css("display") != "none" && checkboxItems.eq(i).is(':checked')) { 957 | var checkboxItemId = checkboxItems.eq(i).attr("id"); 958 | // checkbox item index 959 | var index = checkboxItemId.split("_")[1]; 960 | var labelText = self.$element.find(self.checkboxItemLabelClass).eq(i).text(); 961 | var value = checkboxItems.eq(i).val(); 962 | self.$element.find(self.transferDoubleListLiClass).eq(i).css("display", "").addClass("selected-hidden"); 963 | html += self.generate_item(self.id, index, value, labelText, false); 964 | pre_selection_num++; 965 | 966 | var left_pre_selection_count = self._data.get("left_pre_selection_count"); 967 | var left_total_count = self._data.get("left_total_count"); 968 | var right_total_count = self._data.get("right_total_count"); 969 | self._data.put("left_pre_selection_count", --left_pre_selection_count); 970 | self._data.put("left_total_count", --left_total_count); 971 | self._data.put("right_total_count", ++right_total_count); 972 | } 973 | } 974 | 975 | if (self._data.get("right_total_count") > 0) { 976 | $(self.rightItemSelectAllId).prop("checked", false).removeAttr("disabled"); 977 | } 978 | 979 | if (pre_selection_num > 0) { 980 | var totalNumLabel = self.$element.find(self.totalNumLabelClass); 981 | self.$element.find(self.totalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("left_pre_selection_count"), self._data.get("left_total_count"))); 982 | totalNumLabel.text(get_total_num_text(self.default_total_num_text_template, self._data.get("left_pre_selection_count"), self._data.get("left_total_count"))); 983 | self.$element.find(self.selectedTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, 0, self._data.get("right_total_count"))); 984 | if (self._data.get("left_total_count") == 0 || (self._data.get("left_disabled_count") == self._data.get("left_total_count"))) { 985 | $(self.leftItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 986 | } 987 | 988 | $(self.addSelectedButtonId).removeClass("btn-arrow-active"); 989 | self.$element.find(self.transferDoubleSelectedListUlClass).append(html); 990 | } 991 | } 992 | 993 | /** 994 | * move the selected item to the left handler 995 | */ 996 | Transfer.prototype.move_selected_items_handler = function() { 997 | var self = this; 998 | $(self.deleteSelectedButtonId).on("click", function () { 999 | if ($(this).hasClass("btn-arrow-active")) { 1000 | self.isGroup ? self.move_selected_group_items() : self.move_selected_items() 1001 | $(self.deleteSelectedButtonId).removeClass("btn-arrow-active"); 1002 | // callable 1003 | applyCallable(self); 1004 | } 1005 | }); 1006 | } 1007 | 1008 | /** 1009 | * move the selected group item to the left 1010 | */ 1011 | Transfer.prototype.move_selected_group_items = function() { 1012 | var pre_selection_num = 0; 1013 | var checkboxSelectedItems = this.$element.find(this.checkboxSelectedItemClass); 1014 | for (var i = 0; i < checkboxSelectedItems.length;) { 1015 | var another_checkboxSelectedItems = this.$element.find(this.checkboxSelectedItemClass); 1016 | if (another_checkboxSelectedItems.eq(i).parent("div").parent("li").css("display") != "none" && another_checkboxSelectedItems.eq(i).is(':checked')) { 1017 | var checkboxSelectedItemId = another_checkboxSelectedItems.eq(i).attr("id"); 1018 | var groupIndex = checkboxSelectedItemId.split("_")[1]; 1019 | var index = checkboxSelectedItemId.split("_")[3]; 1020 | 1021 | another_checkboxSelectedItems.parent("div").parent("li").eq(i).remove(); 1022 | this.$element.find("#group_" + groupIndex + "_" + this.id).prop("checked", false).removeAttr("disabled"); 1023 | this.$element.find("#group_" + groupIndex + "_checkbox_" + index + "_" + this.id) 1024 | .prop("checked", false).parent("div").parent("li").css("display", "").removeClass("selected-hidden"); 1025 | 1026 | pre_selection_num++; 1027 | 1028 | var groupItem = this._group_data.get('group_' + groupIndex + '_' + this.id); 1029 | var left_total_count = groupItem["left_total_count"]; 1030 | var right_pre_selection_count = this._data.get("right_pre_selection_count"); 1031 | var right_total_count = this._data.get("right_total_count"); 1032 | groupItem["left_total_count"] = ++left_total_count; 1033 | this._data.put("right_total_count", --right_total_count); 1034 | this._data.put("right_pre_selection_count", --right_pre_selection_count); 1035 | 1036 | } else { 1037 | i++; 1038 | } 1039 | } 1040 | if (pre_selection_num > 0) { 1041 | this.$element.find(this.groupTotalNumLabelClass).empty(); 1042 | 1043 | var remain_left_total_count = 0; 1044 | this._group_data.forEach(function(key, value) { 1045 | remain_left_total_count += value["left_total_count"]; 1046 | }) 1047 | 1048 | if (this._data.get("right_total_count") == 0) { 1049 | $(this.rightItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 1050 | } 1051 | 1052 | this.$element.find(this.groupTotalNumLabelClass).text(get_total_num_text(this.default_total_num_text_template, 0, remain_left_total_count)); 1053 | this.$element.find(this.selectedTotalNumLabelClass).text(get_total_num_text(this.default_total_num_text_template, 0, this._data.get("right_total_count"))); 1054 | if ($(this.groupItemSelectAllId).is(':checked')) { 1055 | $(this.groupItemSelectAllId).prop("checked", false).removeAttr("disabled"); 1056 | } 1057 | } 1058 | } 1059 | 1060 | /** 1061 | * move the selected item to the left 1062 | */ 1063 | Transfer.prototype.move_selected_items = function() { 1064 | var pre_selection_num = 0; 1065 | var self = this; 1066 | 1067 | for (var i = 0; i < self.$element.find(self.checkboxSelectedItemClass).length;) { 1068 | var checkboxSelectedItems = self.$element.find(self.checkboxSelectedItemClass); 1069 | if (checkboxSelectedItems.eq(i).parent("div").parent("li").css("display") != "none" && checkboxSelectedItems.eq(i).is(':checked')) { 1070 | var index = checkboxSelectedItems.eq(i).attr("id").split("_")[1]; 1071 | checkboxSelectedItems.parent("div").parent("li").eq(i).remove(); 1072 | self.$element.find(self.checkboxItemClass).eq(index).prop("checked", false); 1073 | self.$element.find(self.transferDoubleListLiClass).eq(index).css("display", "").removeClass("selected-hidden"); 1074 | 1075 | pre_selection_num++; 1076 | 1077 | var right_total_count = self._data.get("right_total_count"); 1078 | var right_pre_selection_count = self._data.get("right_pre_selection_count"); 1079 | self._data.put("right_total_count", --right_total_count); 1080 | self._data.put("right_pre_selection_count", --right_pre_selection_count); 1081 | 1082 | var left_total_count = self._data.get("left_total_count"); 1083 | self._data.put("left_total_count", ++left_total_count); 1084 | 1085 | 1086 | } else { 1087 | i++; 1088 | } 1089 | } 1090 | 1091 | if (self._data.get("right_total_count") == 0 || (self._data.get("right_pre_selection_count") == self._data.get("right_total_count") - self._data.get("right_disabled_count"))) { 1092 | $(self.rightItemSelectAllId).prop("checked", true).prop("disabled", "disabled"); 1093 | } 1094 | 1095 | 1096 | if (pre_selection_num > 0) { 1097 | self.$element.find(self.totalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("left_pre_selection_count"), self._data.get("left_total_count"))); 1098 | self.$element.find(self.selectedTotalNumLabelClass).text(get_total_num_text(self.default_total_num_text_template, self._data.get("right_pre_selection_count"), self._data.get("right_total_count"))); 1099 | if ($(self.leftItemSelectAllId).is(':checked')) { 1100 | $(self.leftItemSelectAllId).prop("checked", false).removeAttr("disabled"); 1101 | } 1102 | } 1103 | } 1104 | 1105 | /** 1106 | * right items search handler 1107 | */ 1108 | Transfer.prototype.right_items_search_handler = function() { 1109 | var self = this; 1110 | $(self.selectedItemSearcherId).keyup(function () { 1111 | var transferDoubleSelectedListLis = self.$element.find(self.transferDoubleSelectedListLiClass); 1112 | self.$element.find(self.transferDoubleSelectedListUlClass).css('display', 'block'); 1113 | 1114 | if ($(self.selectedItemSearcherId).val() == "") { 1115 | transferDoubleSelectedListLis.css('display', 'block'); 1116 | return; 1117 | } 1118 | 1119 | transferDoubleSelectedListLis.css('display', 'none'); 1120 | 1121 | if (self.settings.wildcardSearch) { 1122 | for (var i = 0; i < transferDoubleSelectedListLis.length; i++) { 1123 | if (transferDoubleSelectedListLis.eq(i).text().trim() 1124 | .toLowerCase().indexOf($(self.selectedItemSearcherId).val().toLowerCase()) > -1 ) { 1125 | transferDoubleSelectedListLis.eq(i).css('display', 'block'); 1126 | } 1127 | } 1128 | } else { 1129 | for (var i = 0; i < transferDoubleSelectedListLis.length; i++) { 1130 | if (transferDoubleSelectedListLis.eq(i).text().trim() 1131 | .substr(0, $(self.selectedItemSearcherId).val().length).toLowerCase() == $(self.selectedItemSearcherId).val().toLowerCase()) { 1132 | transferDoubleSelectedListLis.eq(i).css('display', 'block'); 1133 | } 1134 | } 1135 | } 1136 | }); 1137 | } 1138 | 1139 | /** 1140 | * generate item 1141 | */ 1142 | Transfer.prototype.generate_item = function(id, index, value, labelText, disabled) { 1143 | 1144 | var template = parseHTMLTemplate(function() { 1145 | /* 1146 |
      • 1147 |
        1148 | 1149 | 1150 |
        1151 |
      • 1152 | */ 1153 | }) 1154 | 1155 | var compiled = $.template(template); 1156 | return compiled({ id: id, index: index, value: value, labelText: labelText, disabled: disabled }) 1157 | } 1158 | 1159 | /** 1160 | * generate group item 1161 | */ 1162 | Transfer.prototype.generate_group_item = function(id, groupIndex, itemIndex, value, labelText) { 1163 | 1164 | var template = parseHTMLTemplate(function() { 1165 | /* 1166 |
      • 1167 |
        1168 | 1169 | 1170 |
        1171 |
      • 1172 | */ 1173 | }) 1174 | 1175 | var compiled = $.template(template); 1176 | return compiled({ id: id, groupIndex: groupIndex, itemIndex: itemIndex, value: value, labelText: labelText }); 1177 | } 1178 | 1179 | /** 1180 | * apply callable 1181 | */ 1182 | function applyCallable(transfer) { 1183 | if (Object.prototype.toString.call(transfer.settings.callable) === "[object Function]") { 1184 | var selected_items = get_selected_items(transfer); 1185 | 1186 | // send reply in case of empty array 1187 | //if (selected_items.length > 0) { 1188 | transfer.settings.callable.call(transfer, selected_items); 1189 | //} 1190 | } 1191 | } 1192 | 1193 | /** 1194 | * get selected items 1195 | */ 1196 | function get_selected_items(transfer) { 1197 | var selected = []; 1198 | var transferDoubleSelectedListLiArray = transfer.$element.find(transfer.transferDoubleSelectedListLiClass); 1199 | for (var i = 0; i < transferDoubleSelectedListLiArray.length; i++) { 1200 | var checkboxGroup = transferDoubleSelectedListLiArray.eq(i).find(".checkbox-group"); 1201 | 1202 | var item = {}; 1203 | item[transfer.settings.itemName] = checkboxGroup.find("label").text(); 1204 | item[transfer.settings.valueName] = checkboxGroup.find("input").val(); 1205 | selected.push(item); 1206 | } 1207 | return selected; 1208 | } 1209 | 1210 | /** 1211 | * get group items number 1212 | * @param {Array} groupDataArray 1213 | * @param {string} groupArrayName 1214 | */ 1215 | function get_group_items_num(groupDataArray, groupArrayName) { 1216 | var group_item_total_num = 0; 1217 | for (var i = 0; i < groupDataArray.length; i++) { 1218 | var groupItemData = groupDataArray[i][groupArrayName]; 1219 | if (groupItemData && groupItemData.length > 0) { 1220 | group_item_total_num = group_item_total_num + groupItemData.length; 1221 | } 1222 | } 1223 | return group_item_total_num; 1224 | } 1225 | 1226 | /** 1227 | * replacing the template 1228 | * @param {*} template 1229 | * @param {*} pre_num 1230 | * @param {*} total_num 1231 | */ 1232 | function get_total_num_text(template, pre_num, total_num) { 1233 | var _template = template; 1234 | return _template.replace("pre_num", pre_num).replace("total_num", total_num); 1235 | } 1236 | 1237 | /** 1238 | * Inner Map 1239 | */ 1240 | function InnerMap() { 1241 | this.keys = new Array(); 1242 | this.values = new Object(); 1243 | 1244 | this.put = function(key, value) { 1245 | if (this.values[key] == null) { 1246 | this.keys.push(key); 1247 | } 1248 | this.values[key] = value; 1249 | } 1250 | this.get = function(key) { 1251 | return this.values[key]; 1252 | } 1253 | this.remove = function(key) { 1254 | for (var i = 0; i < this.keys.length; i++) { 1255 | if (this.keys[i] === key) { 1256 | this.keys.splice(i, 1); 1257 | } 1258 | } 1259 | delete this.values[key]; 1260 | } 1261 | this.forEach = function(fn) { 1262 | for (var i = 0; i < this.keys.length; i++) { 1263 | var key = this.keys[i]; 1264 | var value = this.values[key]; 1265 | fn(key, value); 1266 | } 1267 | } 1268 | this.isEmpty = function() { 1269 | return this.keys.length == 0; 1270 | } 1271 | this.size = function() { 1272 | return this.keys.length; 1273 | } 1274 | } 1275 | 1276 | /** 1277 | * get id 1278 | */ 1279 | function getId() { 1280 | var counter = 0; 1281 | return function(prefix) { 1282 | var id = (+new Date()).toString(32), i = 0; 1283 | for (; i < 5; i++) { 1284 | id += Math.floor(Math.random() * 65535).toString(32); 1285 | } 1286 | return (prefix || '') + id + (counter++).toString(32); 1287 | } 1288 | } 1289 | 1290 | /** 1291 | * parse html template 1292 | * @param {*} f 1293 | */ 1294 | function parseHTMLTemplate(func) { 1295 | return func.toString().match(/\/\*([\s\S]*?)\*\//)[1] 1296 | } 1297 | 1298 | }(jQuery)); 1299 | 1300 | 1301 | /** 1302 | * underscore.template 1303 | */ 1304 | ;(function ($) { 1305 | var escapes = { 1306 | "'": "'", 1307 | '\\': '\\', 1308 | '\r': 'r', 1309 | '\n': 'n', 1310 | '\u2028': 'u2028', 1311 | '\u2029': 'u2029' 1312 | }, escapeMap = { 1313 | '&': '&', 1314 | '<': '<', 1315 | '>': '>', 1316 | '"': '"', 1317 | "'": ''', 1318 | '`': '`' 1319 | }; 1320 | var escapeChar = function(match) { 1321 | return '\\' + escapes[match]; 1322 | }; 1323 | var createEscaper = function(map) { 1324 | var escaper = function(match) { 1325 | return map[match]; 1326 | }; 1327 | var source = "(?:&|<|>|\"|'|`)"; 1328 | var testRegexp = RegExp(source); 1329 | var replaceRegexp = RegExp(source, 'g'); 1330 | return function(string) { 1331 | string = string == null ? '' : '' + string; 1332 | return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1333 | }; 1334 | }; 1335 | var escape = createEscaper(escapeMap); 1336 | $.extend({ 1337 | templateSettings: { 1338 | escape: /{{-([\s\S]+?)}}/g, 1339 | interpolate : /{{=([\s\S]+?)}}/g, 1340 | evaluate: /{{([\s\S]+?)}}/g 1341 | }, 1342 | escapeHtml: escape, 1343 | template: function (text, settings) { 1344 | var options = $.extend(true, {}, this.templateSettings, settings); 1345 | var matcher = RegExp([options.escape.source, 1346 | options.interpolate.source, 1347 | options.evaluate.source].join('|') + '|$', 'g'); 1348 | var index = 0; 1349 | var source = "__p+='"; 1350 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 1351 | source += text.slice(index, offset).replace(/\\|'|\r|\n|\u2028|\u2029/g, escapeChar); 1352 | index = offset + match.length; 1353 | if (escape) { 1354 | source += "'+\n((__t=(" + escape + "))==null?'':$.escapeHtml(__t))+\n'"; 1355 | } else if (interpolate) { 1356 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 1357 | } else if (evaluate) { 1358 | source += "';\n" + evaluate + "\n__p+='"; 1359 | } 1360 | return match; 1361 | }); 1362 | source += "';\n"; 1363 | if (!options.variable) source = 'with(obj||{}){\n' + source + '}\n'; 1364 | source = "var __t,__p='',__j=Array.prototype.join," + 1365 | "print=function(){__p+=__j.call(arguments,'');};\n" + 1366 | source + 'return __p;\n'; 1367 | try { 1368 | var render = new Function(options.variable || 'obj', source); 1369 | } catch (e) { 1370 | e.source = source; 1371 | throw e; 1372 | } 1373 | var template = function(data) { 1374 | return render.call(this, data); 1375 | }; 1376 | var argument = options.variable || 'obj'; 1377 | template.source = 'function(' + argument + '){\n' + source + '}'; 1378 | return template; 1379 | } 1380 | }); 1381 | })(jQuery); 1382 | --------------------------------------------------------------------------------