1 <!-- This page defines the form to create or edit an instance of this module -->
2 <!-- It is used from /course/mod.php. The whole instance is available as $form. -->
5 TODO: display proper message when no sequences are received
10 include_once($CFG->dirroot
.'/mod/lams/constants.php');
12 if (!isset($form->name
)) {
15 if (!isset($form->introduction
)) {
16 $form->introduction
= '';
18 if (!isset($form->learning_session_id
)) {
19 $form->learning_session_id
= '';
22 if (!isset($form->create_sequence_url
)) {
23 $datetime = date("F d,Y g:i a");
24 $plaintext = trim($datetime).trim($USER->username
).trim($LAMSCONSTANTS->author_method
).trim($CFG->lams_serverid
).trim($CFG->lams_serverkey
);
25 $hash = sha1(strtolower($plaintext));
26 $form->create_sequence_url
= $CFG->lams_serverurl
.$LAMSCONSTANTS->login_request
.
27 '?'.$LAMSCONSTANTS->param_uid
.'='.$USER->username
.
28 '&'.$LAMSCONSTANTS->param_method
.'='.$LAMSCONSTANTS->author_method
.
29 '&'.$LAMSCONSTANTS->param_timestamp
.'='.urlencode($datetime).
30 '&'.$LAMSCONSTANTS->param_serverid
.'='.$CFG->lams_serverid
.
31 '&'.$LAMSCONSTANTS->param_hash
.'='.$hash.
32 '&'.$LAMSCONSTANTS->param_courseid
.'='.$form->course
;
36 <form id=
"form" method=
"post" action=
"mod.php" onSubmit=
"disableSumbit(this);">
38 <span id=
"message"><p>Please wait .......
</p></span>
39 <table cellpadding=
"5">
41 <td align=right
><b><?php print_string("workspace", "lams") ?>:
</b></td>
43 <select id=
"workspace" name=
"workspace"></select>
47 <td align=
"right"><b><?php print_string("sequence","lams") ?>:
</b></td>
49 <select id=
"sequence" name=
"sequence"></select>
53 <td align=
"right"><b><?php print_string("name") ?>:
</b></td>
55 <input type=
"text" id=
"name" name=
"name" size=
"30" />
58 <td align=right
><p><b><?php print_string("introduction", "lams") ?>:
</b></p>
63 helpbutton("richtext", get_string("helprichtext"), "moodle", true, true);
65 helpbutton("text", get_string("helptext"), "moodle", true, true);
67 emoticonhelpbutton("form", "introduction");
76 print_textarea($usehtmleditor, 20, 50, 680, 400, "introduction", $form->introduction
);
81 <!-- The following line for Moodle 1.5 prints the visibility setting form element -->
82 <!-- <?php print_visible_setting($form); ?> -->
83 <!-- and if your module uses groups you would also have -->
84 <!-- ?php print_groupmode_setting($form); ? -->
87 <input type="hidden" name="learning_session_id"/>
88 <input type="hidden" name="create_sequence_url" id="create_sequence_url"/>
89 <input type="submit" id="save" name="save" value="<?php print_string("useSequence","lams") ?>" onClick="return validate();">
90 <input type="button" id="edit" name"edit" value="<?php print_string("editSequence","lams") ?>" onClick="openAuthor(<?php echo "'".$form->create_sequence_url."&".$LAMSCONSTANTS->param_ldid."=".$form->sequence."'";?>);">
91 <input type="button" id="create" name="create" value="<?php print_string("createSequence","lams") ?>" onClick="openAuthor(<?php echo "'".$form->create_sequence_url."'";?>);">
92 <input type="button" id="refresh" name="refresh" value="<?php print_string("refreshSequenceList","lams")?>" onclick="refreshLists();">
93 <input type="submit" id="cancel" name=cancel value="<?php print_string("cancel") ?>">
96 <!-- These hidden variables are always the same -->
97 <input type="hidden" name=course value="<?php p($form->course) ?>" />
98 <input type="hidden" name="sesskey" value="<?php p($form->sesskey) ?>" />
99 <input type="hidden" name=coursemodule value="<?php p($form->coursemodule) ?>" />
100 <input type="hidden" name=section value="<?php p($form->section) ?>" />
101 <input type="hidden" name=module value="<?php p($form->module) ?>" />
102 <input type="hidden" name=modulename value="<?php p($form->modulename) ?>" />
103 <input type="hidden" name=instance value="<?php p($form->instance) ?>" />
104 <input type="hidden" name=mode value="<?php p($form->mode) ?>" />
109 <script type="text/javascript">
113 workspaceObj = document.getElementById("workspace");
114 if (workspaceObj.options.length == 0){
115 alert("No workspace was returned from LAMS server! You may try refreshing sequence list.\nIf you still get the same problem, probably you have to cancel this activity.");
118 sequenceObj = document.getElementById("sequence");
119 if(sequenceObj.options.length == 0){
120 alert("No sequence was returned from LAMS server! You may try refreshing sequence list.\nIf you still get the same problem, probably you have to cancel this activity.");
123 if(trim(document.getElementById("name").value).length==0){
124 alert("You have to specify the activity name to proceed.");
130 function trim(trim_value){
131 if(trim_value.length < 1){
134 trim_value = rTrim(trim_value);
135 trim_value = lTrim(trim_value);
139 function rTrim(trim_value){
140 var w_space = String.fromCharCode(32);
141 var v_length = trim_value.length;
146 var iTemp = v_length -1;
149 if(trim_value.charAt(iTemp) != w_space){
150 strTemp = trim_value.substring(0,iTemp +1);
158 function lTrim(trim_value){
159 var w_space = String.fromCharCode(32);
163 var v_length = trim_value.length;
168 while(iTemp < v_length){
169 if(trim_value.charAt(iTemp) != w_space){
170 strTemp = trim_value.substring(iTemp,v_length);
178 function disableSubmit(dform) {
179 if (document.getElementById) {
180 for (var sch = 0; sch < dform.length; sch++) {
181 if (dform.elements[sch].type.toLowerCase() == "submit") dform.elements[sch].disabled = true;
187 function enableSubmit(dform) {
188 if (document.getElementById) {
189 for (var sch = 0; sch < dform.length; sch++) {
190 if (dform.elements[sch].type.toLowerCase() == "submit") dform.elements[sch].disabled = false;
196 var authorWin = null;
197 function openAuthor(url){
199 if(authorWin && authorWin.open && !authorWin.closed){
200 authorWin.document.location = url;
203 authorWin = window.open(url);
211 * This function is to initialize elements' status and refresh workspace and sequence lists
213 function refreshLists(){
214 document.getElementById("message").innerHTML = "<p>Please wait .......</p>";
215 disableSubmit(document.forms[0]);
216 document.getElementById("create").disabled = true;
217 document.getElementById("edit").disabled = true;
218 document.getElementById("refresh").disabled = true;
220 wsSelectObj = document.getElementById("workspace");
221 wsSelectObj.options.length = 0; //remove all options
222 wsSelectObj.options[0] = new Option("Loading...", "Loading...");
223 wsSelectObj.disabled = true;
225 seqSelectObj = document.getElementById("sequence");
226 seqSelectObj.options.length = 0; //remove all options
228 //clear the DynamicOptionList
229 dol = new DynamicOptionList("workspace","sequence");
230 dol.setFormName("form");
232 url = "../mod/lams/list.php?courseid="+document.getElementById('form').course.value;
233 if (window.XMLHttpRequest) { // Non-IE browsers
234 req = new XMLHttpRequest();
235 req.onreadystatechange = processStateChange;
237 req.open("GET", url, true);
242 } else if (window.ActiveXObject) { // IE
243 req = new ActiveXObject("Microsoft.XMLHTTP");
245 req.onreadystatechange = processStateChange;
246 req.open("GET", url, true);
252 function processStateChange() {
253 if (req.readyState == 4) { // Complete
254 var wsSelectObj = document.getElementById("workspace");
255 wsSelectObj.options.length = 0; //clear the workspace list
256 wsSelectObj.disabled = false;
257 enableSubmit(document.forms[0]);
258 document.getElementById("create").disabled = false;
259 document.getElementById("edit").disabled = false;
260 document.getElementById("refresh").disabled = false;
261 if (req.status == 200) { // OK response
262 var res = req.responseText.replace(/^\s*|\s*$/g,""); //get trimed result
263 var seqlistStr = res.split(':'); //seperate each set of {sid, workspace,sequence}
264 var seqlist = new Array();
266 var workspaceList = new Object();
268 //pass the response and construct the list again
269 for(var i=0; i<seqlistStr.length; i++){
270 var sws = seqlistStr[i].split(',');
273 var workspace = sws[1];
274 var sequence = sws[2];
276 if(workspaceList[workspace] == null){
277 //set workspace as keys in workspaceList (kind of like a map)
278 //therefore duplicated workspaces will be ignored
279 workspaceList[workspace] = 1; //insert workspace as a key
281 //insert workspace into workspace list
282 wsSelectObj.options[wsSelectObj.length] = new Option(workspace,workspace);
285 //insert sequence dependency into DynamicOptionList
286 dol.forValue(workspace).addOptionsTextValue(sequence,sid);
289 initDynamicOptionLists(); //construct the list
290 document.getElementById("message").innerHTML =
291 "<p>Select an existing sequence or create a new sequence.</p>";
292 }else if(req.status == 504){//gateway timeout. probabaly LAMS server is not available.
293 document.getElementById("message").innerHTML =
294 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">It seems the LAMS server is not available!<br/> Please contact your administrator.</h4></td></tr></table>';
295 }else if(req.status == 401){//AuthenticationException thrown by LAMS server.
296 document.getElementById("message").innerHTML =
297 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">This moodle server is not authenticated by LAMS!<br/> Please contact your administrator.</h4></td></tr></table>';
298 }else if(req.status == 502){//Unknow exception thrown by LAMS server
299 document.getElementById("message").innerHTML =
300 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">An unexpected error returned from LAMS server:'+req.responseText+'! Please contact your administrator.</h4></td></tr></table>';
301 }else if(req.status == 417){//ServerNotFound exception thrown by LAMS server
302 document.getElementById("message").innerHTML =
303 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">This moodle server has not registered in LAMS!<br/> Please contact your administrator.</h4></td></tr></table>';
304 }else if(req.status == 402){//All LAMS module settings have not not been set up
305 document.getElementById("message").innerHTML =
306 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">All the LAMS module settings have not been set up!<br/> Please contact your administrator.</h4></td></tr></table>';
307 }else{//this error should come from moodle server itself
308 document.getElementById("message").innerHTML =
309 '<table align="center" width="57%" class="noticebox" border="0" cellpadding="15" cellspacing="0"><tr><td bgcolor="#FFAAAA" class="noticeboxcontent"><h4 class="main">It should be a moodle server error:'+req.status + ' ' + req.statusText+'! Please contact your administrator.</h4></td></tr></table>';
314 var dynamicOptionListCount=0;
315 var dynamicOptionListObjects = new Array();
317 // Init call to setup lists after page load. One call to this function sets up all lists.
318 function initDynamicOptionLists() {
319 // init each DynamicOptionList object
320 for (var i=0; i<dynamicOptionListObjects.length; i++) {
321 var dol = dynamicOptionListObjects[i];
323 // Find the form associated with this list
324 if (dol.formName!=null) {
325 dol.form = document.forms[dol.formName];
327 else if (dol.formIndex!=null) {
328 dol.form = document.forms[dol.formIndex];
331 // Form wasn't set manually, so go find it!
332 // Search for the first form element name in the lists
333 var name = dol.fieldNames[0][0];
334 for (var f=0; f<document.forms.length; f++) {
335 if (typeof(document.forms[f][name])!="undefined") {
336 dol.form = document.forms[f];
340 if (dol.form==null) {
341 alert("ERROR: Couldn't find form element "+name+" in any form on the page! Init aborted"); return;
345 // Form is found, now set the onchange attributes of each dependent select box
346 for (var j=0; j<dol.fieldNames.length; j++) {
347 // For each set of field names...
348 for (var k=0; k<dol.fieldNames[j].length-1; k++) {
349 // For each field in the set...
350 var selObj = dol.form[dol.fieldNames[j][k]];
351 if (typeof(selObj)=="undefined") { alert("Select box named "+dol.fieldNames[j][k]+" could not be found in the form. Init aborted"); return; }
352 // Map the HTML options in the first select into the options we created
354 if (selObj.options!=null) {
355 for (l=0; l<selObj.options.length; l++) {
356 var sopt = selObj.options[l];
357 var m = dol.findMatchingOptionInArray(dol.options,sopt.text,sopt.value,false);
359 var reselectForNN6 = sopt.selected;
360 var m2 = new Option(sopt.text, sopt.value, sopt.defaultSelected, sopt.selected);
361 m2.selected = sopt.selected; // For some reason I need to do this to make NN4 happy
362 m2.defaultSelected = sopt.defaultSelected;
364 selObj.options[l] = m2;
365 selObj.options[l].selected = reselectForNN6; // Reselect this option for NN6 to be happy. Yuck.
370 if (selObj.onchange==null) {
371 // We only modify the onChange attribute if it's empty! Otherwise do it yourself in your source!
372 selObj.onchange = new Function("dynamicOptionListObjects["+dol.index+"].change(this)");
377 // Set the preselectd options on page load
378 resetDynamicOptionLists();
381 // This function populates lists with the preselected values.
382 // It's pulled out into a separate function so it can be hooked into a 'reset' button on a form
383 // Optionally passed a form object which should be the only form reset
384 function resetDynamicOptionLists(theform) {
385 // reset each DynamicOptionList object
386 for (var i=0; i<dynamicOptionListObjects.length; i++) {
387 var dol = dynamicOptionListObjects[i];
388 if (typeof(theform)=="undefined" || theform==null || theform==dol.form) {
389 for (var j=0; j<dol.fieldNames.length; j++) {
390 dol.change(dol.form[dol.fieldNames[j][0]],true); // Second argument says to use preselected values rather than default values
396 // An object to represent an Option() but just for data-holding
397 function DOLOption(text,value,defaultSelected,selected) {
400 this.defaultSelected = defaultSelected;
401 this.selected = selected;
402 this.options = new Array(); // To hold sub-options
406 // DynamicOptionList CONSTRUCTOR
407 function DynamicOptionList() {
408 this.form = null;// The form this list belongs to
409 this.options = new Array();// Holds the options of dependent lists
410 this.longestString = new Array();// Longest string that is currently a potential option (for Netscape)
411 this.numberOfOptions = new Array();// The total number of options that might be displayed, to build dummy options (for Netscape)
412 this.currentNode = null;// The current node that has been selected with forValue() or forText()
413 this.currentField = null;// The current field that is selected to be used for setValue()
414 this.currentNodeDepth = 0;// How far down the tree the currentNode is
415 this.fieldNames = new Array();// Lists of dependent fields which use this object
416 this.formIndex = null;// The index of the form to associate with this list
417 this.formName = null;// The name of the form to associate with this list
418 this.fieldListIndexes = new Object();// Hold the field lists index where fields exist
419 this.fieldIndexes = new Object();// Hold the index within the list where fields exist
420 this.selectFirstOption = true;// Whether or not to select the first option by default if no options are default or preselected, otherwise set the selectedIndex = -1
421 this.numberOfOptions = new Array();// Store the max number of options for a given option list
422 this.longestString = new Array();// Store the longest possible string
423 this.values = new Object(); // Will hold the preselected values for fields, by field name
426 this.forValue = DOL_forValue;
427 this.forText = DOL_forText;
428 this.forField = DOL_forField;
429 this.forX = DOL_forX;
430 this.addOptions = DOL_addOptions;
431 this.addOptionsTextValue = DOL_addOptionsTextValue;
432 this.setDefaultOptions = DOL_setDefaultOptions;
433 this.setValues = DOL_setValues;
434 this.setValue = DOL_setValues;
435 this.setFormIndex = DOL_setFormIndex;
436 this.setFormName = DOL_setFormName;
437 this.printOptions = DOL_printOptions;
438 this.addDependentFields = DOL_addDependentFields;
439 this.change = DOL_change;
440 this.child = DOL_child;
441 this.selectChildOptions = DOL_selectChildOptions;
442 this.populateChild = DOL_populateChild;
443 this.change = DOL_change;
444 this.addNewOptionToList = DOL_addNewOptionToList;
445 this.findMatchingOptionInArray = DOL_findMatchingOptionInArray;
447 // Optionally pass in the dependent field names
448 if (arguments.length > 0) {
449 // Process arguments and add dependency groups
450 for (var i=0; i<arguments.length; i++) {
451 this.fieldListIndexes[arguments[i].toString()] = this.fieldNames.length;
452 this.fieldIndexes[arguments[i].toString()] = i;
454 this.fieldNames[this.fieldNames.length] = arguments;
457 // Add this object to the global array of dynamicoptionlist objects
458 this.index = window.dynamicOptionListCount++;
459 window["dynamicOptionListObjects"][this.index] = this;
462 // Given an array of Option objects, search for an existing option that matches value, text, or both
463 function DOL_findMatchingOptionInArray(a,text,value,exactMatchRequired) {
464 if (a==null || typeof(a)=="undefined") { return null; }
465 var value_match = null; // Whether or not a value has been matched
466 var text_match = null; // Whether or not a text has been matched
467 for (var i=0; i<a.length; i++) {
469 // If both value and text match, return it right away
470 if (opt.value==value && opt.text==text) { return opt; }
471 if (!exactMatchRequired) {
472 // If value matches, store it until we complete scanning the list
473 if (value_match==null && value!=null && opt.value==value) {
476 // If text matches, store it for later
477 if (text_match==null && text!=null && opt.text==text) {
482 return (value_match!=null)?value_match:text_match;
485 // Util function used by forValue and forText
486 function DOL_forX(s,type) {
487 if (this.currentNode==null) { this.currentNodeDepth=0; }
488 var useNode = (this.currentNode==null)?this:this.currentNode;
489 var o = this.findMatchingOptionInArray(useNode["options"],(type=="text")?s:null,(type=="value")?s:null,false);
491 o = new DOLOption(null,null,false,false);
493 useNode.options[useNode.options.length] = o;
495 this.currentNode = o;
496 this.currentNodeDepth++;
500 // Set the portion of the list structure that is to be used by a later operation like addOptions
501 function DOL_forValue(s) { return this.forX(s,"value"); }
503 // Set the portion of the list structure that is to be used by a later operation like addOptions
504 function DOL_forText(s) { return this.forX(s,"text"); }
506 // Set the field to be used for setValue() calls
507 function DOL_forField(f) { this.currentField = f; return this; }
509 // Create and add an option to a list, avoiding duplicates
510 function DOL_addNewOptionToList(a, text, value, defaultSelected) {
511 var o = new DOLOption(text,value,defaultSelected,false);
512 // Add the option to the array
513 if (a==null) { a = new Array(); }
514 for (var i=0; i<a.length; i++) {
515 if (a[i].text==o.text && a[i].value==o.value) {
519 if (o.defaultSelected) {
520 a[i].defaultSelected = true;
528 // Add sub-options to the currently-selected node, with the same text and value for each option
529 function DOL_addOptions() {
530 if (this.currentNode==null) { this.currentNode = this; }
531 if (this.currentNode["options"] == null) { this.currentNode["options"] = new Array(); }
532 for (var i=0; i<arguments.length; i++) {
533 var text = arguments[i];
534 this.addNewOptionToList(this.currentNode.options,text,text,false);
535 if (typeof(this.numberOfOptions[this.currentNodeDepth])=="undefined") {
536 this.numberOfOptions[this.currentNodeDepth]=0;
538 if (this.currentNode.options.length > this.numberOfOptions[this.currentNodeDepth]) {
539 this.numberOfOptions[this.currentNodeDepth] = this.currentNode.options.length;
541 if (typeof(this.longestString[this.currentNodeDepth])=="undefined" || (text.length > this.longestString[this.currentNodeDepth].length)) {
542 this.longestString[this.currentNodeDepth] = text;
545 this.currentNode = null;
546 this.currentNodeDepth = 0;
549 // Add sub-options to the currently-selected node, specifying separate text and values for each option
550 function DOL_addOptionsTextValue() {
551 if (this.currentNode==null) { this.currentNode = this; }
552 if (this.currentNode["options"] == null) { this.currentNode["options"] = new Array(); }
553 for (var i=0; i<arguments.length; i++) {
554 var text = arguments[i++];
555 var value = arguments[i];
556 this.addNewOptionToList(this.currentNode.options,text,value,false);
557 if (typeof(this.numberOfOptions[this.currentNodeDepth])=="undefined") {
558 this.numberOfOptions[this.currentNodeDepth]=0;
560 if (this.currentNode.options.length > this.numberOfOptions[this.currentNodeDepth]) {
561 this.numberOfOptions[this.currentNodeDepth] = this.currentNode.options.length;
563 if (typeof(this.longestString[this.currentNodeDepth])=="undefined" || (text.length > this.longestString[this.currentNodeDepth].length)) {
564 this.longestString[this.currentNodeDepth] = text;
567 this.currentNode = null;
568 this.currentNodeDepth = 0;
571 // Find the first dependent list of a select box
572 // If it's the last list in a chain, return null because there are no children
573 function DOL_child(obj) {
574 var listIndex = this.fieldListIndexes[obj.name];
575 var index = this.fieldIndexes[obj.name];
576 if (index < (this.fieldNames[listIndex].length-1)) {
577 return this.form[this.fieldNames[listIndex][index+1]];
582 // Set the options which should be selected by default for a certain value in the parent
583 function DOL_setDefaultOptions() {
584 if (this.currentNode==null) { this.currentNode = this; }
585 for (var i=0; i<arguments.length; i++) {
586 var o = this.findMatchingOptionInArray(this.currentNode.options,null,arguments[i],false);
588 o.defaultSelected = true;
591 this.currentNode = null;
594 // Set the options which should be selected when the page loads. This is different than the default value and ONLY applies when the page LOADS
595 function DOL_setValues() {
596 if (this.currentField==null) {
597 alert("Can't call setValues() without using forField() first!");
600 if (typeof(this.values[this.currentField])=="undefined") {
601 this.values[this.currentField] = new Object();
603 for (var i=0; i<arguments.length; i++) {
604 this.values[this.currentField][arguments[i]] = true;
606 this.currentField = null;
609 // Manually set the form for the object using an index
610 function DOL_setFormIndex(i) {
614 // Manually set the form for the object using a form name
615 function DOL_setFormName(n) {
619 // Print blank <option> objects for Netscape4, since it refuses to grow or shrink select boxes for new options
620 function DOL_printOptions(name) {
621 // Only need to write out "dummy" options for Netscape4
622 if ((navigator.appName == 'Netscape') && (parseInt(navigator.appVersion) <= 4)){
623 var index = this.fieldIndexes[name];
625 if (typeof(this.numberOfOptions[index])!="undefined") {
626 for (var i=0; i<this.numberOfOptions[index]; i++) {
631 if (typeof(this.longestString[index])!="undefined") {
632 for (var i=0; i<this.longestString[index].length; i++) {
636 document.writeln(ret);
640 // Add a list of field names which use this option-mapping object.
641 // A single mapping object may be used by multiple sets of fields
642 function DOL_addDependentFields() {
643 for (var i=0; i<arguments.length; i++) {
644 this.fieldListIndexes[arguments[i].toString()] = this.fieldNames.length;
645 this.fieldIndexes[arguments[i].toString()] = i;
647 this.fieldNames[this.fieldNames.length] = arguments;
650 // Called when a parent select box is changed. It populates its direct child, then calls change on the child object to continue the population.
651 function DOL_change(obj, usePreselected) {
652 if (usePreselected==null || typeof(usePreselected)=="undefined") { usePreselected = false; }
653 var changedListIndex = this.fieldListIndexes[obj.name];
654 var changedIndex = this.fieldIndexes[obj.name];
655 var child = this.child(obj);
656 if (child == null) { return; } // No child, no need to continue
657 if (obj.type == "select-one") {
658 // Treat single-select differently so we don't have to scan the entire select list, which could potentially speed things up
659 if (child.options!=null) {
660 child.options.length=0; // Erase all the options from the child so we can re-populate
662 if (obj.options!=null && obj.options.length>0 && obj.selectedIndex>=0) {
663 var o = obj.options[obj.selectedIndex];
664 this.populateChild(o.DOLOption,child,usePreselected);
665 this.selectChildOptions(child,usePreselected);
668 else if (obj.type == "select-multiple") {
669 // For each selected value in the parent, find the options to fill in for this list
670 // Loop through the child list and keep track of options that are currently selected
671 var currentlySelectedOptions = new Array();
672 if (!usePreselected) {
673 for (var i=0; i<child.options.length; i++) {
674 var co = child.options[i];
676 this.addNewOptionToList(currentlySelectedOptions, co.text, co.value, co.defaultSelected);
680 child.options.length=0;
681 if (obj.options!=null) {
682 var obj_o = obj.options;
683 // For each selected option in the parent...
684 for (var i=0; i<obj_o.length; i++) {
685 if (obj_o[i].selected) {
686 // if option is selected, add its children to the list
687 this.populateChild(obj_o[i].DOLOption,child,usePreselected);
690 // Now go through and re-select any options which were selected before
691 var atLeastOneSelected = false;
692 if (!usePreselected) {
693 for (var i=0; i<child.options.length; i++) {
694 var m = this.findMatchingOptionInArray(currentlySelectedOptions,child.options[i].text,child.options[i].value,true);
696 child.options[i].selected = true;
697 atLeastOneSelected = true;
701 if (!atLeastOneSelected) {
702 this.selectChildOptions(child,usePreselected);
706 // Change all the way down the chain
707 this.change(child,usePreselected);
709 function DOL_populateChild(dolOption,childSelectObj,usePreselected) {
710 // If this opton has sub-options, populate the child list with them
711 if (dolOption!=null && dolOption.options!=null) {
712 for (var j=0; j<dolOption.options.length; j++) {
713 var srcOpt = dolOption.options[j];
714 if (childSelectObj.options==null) { childSelectObj.options = new Array(); }
715 // Put option into select list
716 var duplicate = false;
717 var preSelectedExists = false;
718 for (var k=0; k<childSelectObj.options.length; k++) {
719 var csi = childSelectObj.options[k];
720 if (csi.text==srcOpt.text && csi.value==srcOpt.value) {
726 var newopt = new Option(srcOpt.text, srcOpt.value, false, false);
727 newopt.selected = false; // Again, we have to do these two statements for NN4 to work
728 newopt.defaultSelected = false;
729 newopt.DOLOption = srcOpt;
730 childSelectObj.options[childSelectObj.options.length] = newopt;
736 // Once a child select is populated, go back over it to select options which should be selected
737 function DOL_selectChildOptions(obj,usePreselected) {
738 // Look to see if any options are preselected=true. If so, then set then selected if usePreselected=true, otherwise set defaults
739 var values = this.values[obj.name];
740 var preselectedExists = false;
741 if (usePreselected && values!=null && typeof(values)!="undefined") {
742 for (var i=0; i<obj.options.length; i++) {
743 var v = obj.options[i].value;
744 if (v!=null && values[v]!=null && typeof(values[v])!="undefined") {
745 preselectedExists = true;
750 // Go back over all the options to do the selection
751 var atLeastOneSelected = false;
752 for (var i=0; i<obj.options.length; i++) {
753 var o = obj.options[i];
754 if (preselectedExists && o.value!=null && values[o.value]!=null && typeof(values[o.value])!="undefined") {
756 atLeastOneSelected = true;
758 else if (!preselectedExists && o.DOLOption!=null && o.DOLOption.defaultSelected) {
760 atLeastOneSelected = true;
766 // If nothing else was selected, select the first one by default
767 if (this.selectFirstOption && !atLeastOneSelected && obj.options.length>0) {
768 obj.options[0].selected = true;
770 else if (!atLeastOneSelected && obj.type=="select-one") {
771 obj.selectedIndex = -1;
775 refreshLists();//refresh the lists when form is displayed.