1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 CKEDITOR.dialog.add( 'select', function( editor ) 6 { 7 // Add a new option to a SELECT object (combo or list). 8 function addOption( combo, optionText, optionValue, documentObject, index ) 9 { 10 combo = getSelect( combo ); 11 var oOption; 12 if ( documentObject ) 13 oOption = documentObject.createElement( "OPTION" ); 14 else 15 oOption = document.createElement( "OPTION" ); 16 17 if ( combo && oOption && oOption.getName() == 'option' ) 18 { 19 if ( CKEDITOR.env.ie ) { 20 if ( !isNaN( parseInt( index, 10) ) ) 21 combo.$.options.add( oOption.$, index ); 22 else 23 combo.$.options.add( oOption.$ ); 24 25 oOption.$.innerHTML = optionText.length > 0 ? optionText : ''; 26 oOption.$.value = optionValue; 27 } 28 else 29 { 30 if ( index != null && index < combo.getChildCount() ) 31 combo.getChild( index < 0 ? 0 : index ).insertBeforeMe( oOption ); 32 else 33 combo.append( oOption ); 34 35 oOption.setText( optionText.length > 0 ? optionText : '' ); 36 oOption.setValue( optionValue ); 37 } 38 } 39 else 40 return false; 41 42 return oOption; 43 } 44 // Remove all selected options from a SELECT object. 45 function removeSelectedOptions( combo ) 46 { 47 combo = getSelect( combo ); 48 49 // Save the selected index 50 var iSelectedIndex = getSelectedIndex( combo ); 51 52 // Remove all selected options. 53 for ( var i = combo.getChildren().count() - 1 ; i >= 0 ; i-- ) 54 { 55 if ( combo.getChild( i ).$.selected ) 56 combo.getChild( i ).remove(); 57 } 58 59 // Reset the selection based on the original selected index. 60 setSelectedIndex( combo, iSelectedIndex ); 61 } 62 //Modify option from a SELECT object. 63 function modifyOption( combo, index, title, value ) 64 { 65 combo = getSelect( combo ); 66 if ( index < 0 ) 67 return false; 68 var child = combo.getChild( index ); 69 child.setText( title ); 70 child.setValue( value ); 71 return child; 72 } 73 function removeAllOptions( combo ) 74 { 75 combo = getSelect( combo ); 76 while( combo.getChild( 0 ) && combo.getChild( 0 ).remove() ); 77 } 78 // Moves the selected option by a number of steps (also negative). 79 function changeOptionPosition( combo, steps, documentObject ) 80 { 81 combo = getSelect( combo ); 82 var iActualIndex = getSelectedIndex( combo ); 83 if ( iActualIndex < 0 ) 84 return false; 85 86 var iFinalIndex = iActualIndex + steps; 87 iFinalIndex = ( iFinalIndex < 0 ) ? 0 : iFinalIndex; 88 iFinalIndex = ( iFinalIndex >= combo.getChildCount() ) ? combo.getChildCount() - 1 : iFinalIndex; 89 90 if ( iActualIndex == iFinalIndex ) 91 return false; 92 93 var oOption = combo.getChild( iActualIndex ), 94 sText = oOption.getText(), 95 sValue = oOption.getValue(); 96 97 oOption.remove(); 98 99 oOption = addOption( combo, sText, sValue, ( !documentObject ) ? null : documentObject, iFinalIndex ); 100 setSelectedIndex( combo, iFinalIndex ); 101 return oOption; 102 } 103 function getSelectedIndex( combo ) 104 { 105 combo = getSelect( combo ); 106 return combo ? combo.$.selectedIndex : -1; 107 } 108 function setSelectedIndex( combo, index ) 109 { 110 combo = getSelect( combo ); 111 if ( index < 0 ) 112 return ; 113 var count = combo.getChildren().count(); 114 combo.$.selectedIndex = ( index >= count ) ? ( count - 1 ) : index; 115 return combo; 116 } 117 function getOptions( combo ) 118 { 119 combo = getSelect( combo ); 120 return combo ? combo.getChildren() : false; 121 } 122 function getSelect( obj ) 123 { 124 if ( obj && obj.domId && obj.getInputElement().$ ) // Dialog element. 125 return obj.getInputElement(); 126 else if ( obj && obj.$ ) 127 return obj; 128 return false; 129 } 130 131 return { 132 title : editor.lang.select.title, 133 minWidth : 400, 134 minHeight : 370, 135 onShow : function() 136 { 137 // IE BUG: Selection must be in the editor for getSelectedElement() 138 // to work. 139 this.restoreSelection(); 140 141 this.setupContent( 'clear' ); 142 var element = this.getParentEditor().getSelection().getSelectedElement(); 143 if ( element && element.getName() == "select" ) 144 { 145 this._element = element; 146 this.setupContent( element.getName(), element ); 147 148 //Load Options into dialog. 149 var objOptions = getOptions( element ); 150 for ( var i = 0 ; i < objOptions.count() ; i++ ) 151 this.setupContent( 'option', objOptions.getItem( i ) ); 152 } 153 }, 154 onOk : function() 155 { 156 var editor = this.getParentEditor(), 157 element = this._element, 158 isInsertMode = !element; 159 160 if ( isInsertMode ) 161 element = editor.document.createElement( 'select' ); 162 this.commitContent( element ); 163 164 if ( isInsertMode ) 165 { 166 this.restoreSelection(); 167 this.clearSavedSelection(); 168 editor.insertElement( element ); 169 } 170 }, 171 contents : [ 172 { 173 id : 'info', 174 label : editor.lang.select.selectInfo, 175 title : editor.lang.select.selectInfo, 176 accessKey : '', 177 elements : [ 178 { 179 id : 'txtName', 180 type : 'text', 181 widths : [ '25%','75%' ], 182 labelLayout : 'horizontal', 183 label : editor.lang.common.name, 184 'default' : '', 185 accessKey : 'N', 186 align : 'center', 187 style : 'width:350px', 188 setup : function( name, element ) 189 { 190 if ( name == 'select' ) 191 { 192 this.setValue( element.getAttribute( 'name' ) ); 193 this.focus(); 194 } 195 }, 196 commit : function( element ) 197 { 198 if ( this.getValue() != '' || this.isChanged() ) 199 element.setAttribute( 'name', this.getValue() ); 200 } 201 }, 202 { 203 id : 'txtValue', 204 type : 'text', 205 widths : [ '25%','75%' ], 206 labelLayout : 'horizontal', 207 label : editor.lang.select.value, 208 style : 'width:350px', 209 'default' : '', 210 readonly : true, // TODO: make it readonly somehow. 211 disabled : true 212 }, 213 { 214 type : 'hbox', 215 widths : [ '175px', '170px' ], 216 align : 'center', 217 children : 218 [ 219 { 220 id : 'txtSize', 221 type : 'text', 222 align : 'center', 223 labelLayout : 'horizontal', 224 label : editor.lang.select.size, 225 'default' : '', 226 accessKey : 'S', 227 style : 'width:175px', 228 validate: function() 229 { 230 var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed ); 231 return ( ( this.getValue() == '' ) || func.apply( this ) ); 232 }, 233 setup : function( name, element ) 234 { 235 if ( name == 'select' ) 236 this.setValue( element.getAttribute( 'size' ) ); 237 }, 238 commit : function( element ) 239 { 240 if ( this.getValue() != '' || this.isChanged() ) 241 element.setAttribute( 'size', this.getValue() ); 242 } 243 }, 244 { 245 type : 'html', 246 html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.select.lines ) + '</span>' 247 } 248 ] 249 }, 250 { 251 type : 'html', 252 html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.select.opAvail ) + '</span>' 253 }, 254 { 255 type : 'hbox', 256 widths : [ '115px', '115px' ,'100px' ], 257 align : 'top', 258 children : 259 [ 260 { 261 type : 'vbox', 262 children : 263 [ 264 { 265 id : 'txtOptName', 266 type : 'text', 267 label : editor.lang.select.opText, 268 style : 'width:115px', 269 setup : function( name, element ) 270 { 271 if ( name == 'clear' ) 272 this.setValue( "" ); 273 } 274 }, 275 { 276 type : 'select', 277 id : 'cmbName', 278 label : '', 279 title : '', 280 size : 5, 281 style : 'width:115px;height:75px', 282 items : [], 283 onChange : function() 284 { 285 var dialog = this.getDialog(), 286 values = dialog.getContentElement( 'info', 'cmbValue' ), 287 optName = dialog.getContentElement( 'info', 'txtOptName' ), 288 optValue = dialog.getContentElement( 'info', 'txtOptValue' ), 289 iIndex = getSelectedIndex( this ); 290 291 setSelectedIndex( values, iIndex ); 292 optName.setValue( this.getValue() ); 293 optValue.setValue( values.getValue() ); 294 }, 295 setup : function( name, element ) 296 { 297 if ( name == 'clear' ) 298 removeAllOptions( this ); 299 else if ( name == 'option' ) 300 addOption( this, element.getText(), element.getText(), 301 this.getDialog().getParentEditor().document ); 302 }, 303 commit : function( element ) 304 { 305 var dialog = this.getDialog(), 306 optionsNames = getOptions( this ), 307 optionsValues = getOptions( dialog.getContentElement( 'info', 'cmbValue' ) ), 308 selectValue = dialog.getContentElement( 'info', 'txtValue' ).getValue(); 309 310 removeAllOptions( element ); 311 312 for ( var i = 0 ; i < optionsNames.count() ; i++ ) 313 { 314 var oOption = addOption( element, optionsNames.getItem( i ).getValue(), 315 optionsValues.getItem( i ).getValue(), dialog.getParentEditor().document ); 316 if ( optionsValues.getItem( i ).getValue() == selectValue ) 317 { 318 oOption.setAttribute( 'selected', 'selected' ); 319 oOption.selected = true; 320 } 321 } 322 } 323 } 324 ] 325 }, 326 { 327 type : 'vbox', 328 children : 329 [ 330 { 331 id : 'txtOptValue', 332 type : 'text', 333 label : editor.lang.select.opValue, 334 style : 'width:115px', 335 setup : function( name, element ) 336 { 337 if ( name == 'clear' ) 338 this.setValue( "" ); 339 } 340 }, 341 { 342 type : 'select', 343 id : 'cmbValue', 344 label : '', 345 size : 5, 346 style : 'width:115px;height:75px', 347 items : [], 348 onChange : function() 349 { 350 var dialog = this.getDialog(), 351 names = dialog.getContentElement( 'info', 'cmbName' ), 352 optName = dialog.getContentElement( 'info', 'txtOptName' ), 353 optValue = dialog.getContentElement( 'info', 'txtOptValue' ), 354 iIndex = getSelectedIndex( this ); 355 356 setSelectedIndex( names, iIndex ); 357 optName.setValue( names.getValue() ); 358 optValue.setValue( this.getValue() ); 359 }, 360 setup : function( name, element ) 361 { 362 if ( name == 'clear' ) 363 removeAllOptions( this ); 364 else if ( name == 'option' ) 365 { 366 var oValue = element.getValue(); 367 addOption( this, oValue, oValue, 368 this.getDialog().getParentEditor().document ); 369 if ( element.getAttribute( 'selected' ) == 'selected' ) 370 this.getDialog().getContentElement( 'info', 'txtValue' ).setValue( oValue ); 371 } 372 } 373 }, 374 ] 375 }, 376 { 377 type : 'vbox', 378 padding : 5, 379 children : 380 [ 381 { 382 type : 'button', 383 style : '', 384 label : editor.lang.select.btnAdd, 385 title : editor.lang.select.btnAdd, 386 style : 'width:100%;', 387 onClick : function() 388 { 389 //Add new option. 390 var dialog = this.getDialog(); 391 parentEditor = dialog.getParentEditor(), 392 optName = dialog.getContentElement( 'info', 'txtOptName' ), 393 optValue = dialog.getContentElement( 'info', 'txtOptValue' ), 394 names = dialog.getContentElement( 'info', 'cmbName' ), 395 values = dialog.getContentElement( 'info', 'cmbValue' ); 396 397 addOption(names, optName.getValue(), optName.getValue(), dialog.getParentEditor().document ); 398 addOption(values, optValue.getValue(), optValue.getValue(), dialog.getParentEditor().document ); 399 400 optName.setValue( "" ); 401 optValue.setValue( "" ); 402 } 403 }, 404 { 405 type : 'button', 406 label : editor.lang.select.btnModify, 407 title : editor.lang.select.btnModify, 408 style : 'width:100%;', 409 onClick : function() 410 { 411 //Modify selected option. 412 var dialog = this.getDialog(); 413 optName = dialog.getContentElement( 'info', 'txtOptName' ), 414 optValue = dialog.getContentElement( 'info', 'txtOptValue' ), 415 names = dialog.getContentElement( 'info', 'cmbName' ), 416 values = dialog.getContentElement( 'info', 'cmbValue' ), 417 iIndex = getSelectedIndex( names ); 418 419 if ( iIndex >= 0 ) 420 { 421 modifyOption( names, iIndex, optName.getValue(), optName.getValue() ); 422 modifyOption( values, iIndex, optValue.getValue(), optValue.getValue() ); 423 } 424 } 425 }, 426 { 427 type : 'button', 428 style : 'width:100%;', 429 label : editor.lang.select.btnUp, 430 title : editor.lang.select.btnUp, 431 onClick : function() 432 { 433 //Move up. 434 var dialog = this.getDialog(), 435 names = dialog.getContentElement( 'info', 'cmbName' ), 436 values = dialog.getContentElement( 'info', 'cmbValue' ); 437 438 changeOptionPosition( names, -1, dialog.getParentEditor().document ); 439 changeOptionPosition( values, -1, dialog.getParentEditor().document ); 440 } 441 }, 442 { 443 type : 'button', 444 style : 'width:100%;', 445 label : editor.lang.select.btnDown, 446 title : editor.lang.select.btnDown, 447 onClick : function() 448 { 449 //Move down. 450 var dialog = this.getDialog(), 451 names = dialog.getContentElement( 'info', 'cmbName' ), 452 values = dialog.getContentElement( 'info', 'cmbValue' ); 453 454 changeOptionPosition( names, 1, dialog.getParentEditor().document ); 455 changeOptionPosition( values, 1, dialog.getParentEditor().document ); 456 } 457 } 458 ] 459 } 460 ] 461 }, 462 { 463 type : 'hbox', 464 widths : [ '40%', '20%', '40%' ], 465 children : 466 [ 467 { 468 type : 'button', 469 label : editor.lang.select.btnSetValue, 470 title : editor.lang.select.btnSetValue, 471 onClick : function() 472 { 473 //Set as default value. 474 var dialog = this.getDialog(), 475 values = dialog.getContentElement( 'info', 'cmbValue' ), 476 txtValue = dialog.getContentElement( 'info', 'txtValue' ); 477 txtValue.setValue( values.getValue() ); 478 } 479 }, 480 { 481 type : 'button', 482 label : editor.lang.select.btnDelete, 483 title : editor.lang.select.btnDelete, 484 onClick : function() 485 { 486 // Delete option. 487 var dialog = this.getDialog(), 488 names = dialog.getContentElement( 'info', 'cmbName' ), 489 values = dialog.getContentElement( 'info', 'cmbValue' ), 490 optName = dialog.getContentElement( 'info', 'txtOptName' ), 491 optValue = dialog.getContentElement( 'info', 'txtOptValue' ); 492 493 removeSelectedOptions( names ); 494 removeSelectedOptions( values ); 495 496 optName.setValue( "" ); 497 optValue.setValue( "" ); 498 } 499 }, 500 { 501 id : 'chkMulti', 502 type : 'checkbox', 503 label : editor.lang.select.chkMulti, 504 'default' : '', 505 accessKey : 'M', 506 value : "checked", 507 setup : function( name, element ) 508 { 509 if ( name == 'select' ) 510 this.setValue( element.getAttribute( 'multiple' ) ); 511 }, 512 commit : function( element ) 513 { 514 if ( this.getValue() == true || this.isChanged() ) 515 element.setAttribute( 'multiple', this.getValue() ); 516 } 517 } 518 ] 519 } 520 ] 521 } 522 ] 523 }; 524 }); 525