PDA

View Full Version : Dynamic List - Part I


RadarBob
10-09-2002, 04:22 PM
NOTE: This post split into two threads so I don't exceed the 10k character limit.

My implementation has dynamic list opened from a parent as a separate window. Includes functions to pass the values back to the parent.

* Builds a <select> object from a selectable list & direct entry.
* List is sorted alphabetically
* Duplicates, blank entry, certain characters not allowed
* In my implementation values in the selectable list are pulled from a database server-side; You'll have to fill those in however you want.
* Server-side ASP code imbedded in the form is specific to my needs, you'll have to change all that I suppose.


<script language=javascript1.2>
<!-- Begin
// original code courtsey of David Clark through www.codingfourms.com

function sortLists(f) {
x = f.newList.options;

if (x.length > 1) {
myArray = new Array();
for (var i=0; i<x.length; i++) {
myArray[i] = new Array(x[i].text, x[i].value, x[i].defaultSelected, x[i].selected);
}

myArray.sort(sortBYtext);

for (var i=0; i<x.length; i++) {
x[i] = new Option(myArray[i][0], myArray[i][1], myArray[i][2], myArray[i][3]);
x[i].selected = myArray[i][3];
} // end for (var i=0; i<x.length; i++)
}
}


function sortBYtext(a,b) {
if (a[0].toUpperCase() < b[0].toUpperCase()) return -1
if (a[0].toUpperCase() > b[0].toUpperCase()) return 1
return 0
}


function sortBYvalue(a,b) {
if (a[1] < b[1]) return -1
if (a[1] > b[1]) return 1
return 0
}


function selOld(f) {
o = f.oldList.options;
n = f.newList.options;
for (var i=(o.length-1); i>=0; i--) {
if (o[i].selected && o[i].value != "00") {
if (!IsInList(o[i].text, f.newList)) {
n[n.length] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
if (n[0].value == "00") n[0] = null;
} // if (!IsInList())
}
}
sortLists(f);
}


function selNew(f) {
n = f.newList.options;
o = f.oldList.options;

for (var i=(n.length-1); i>=0; i--) {
if (n[i].selected && n[i].value != "00") {

if (n.length == 1) {
n[n.length] = new Option ("<--empty-->", "00", false, false);
n[n.length-1].selected = false;
}

n[i] = null;
}
}
sortLists(f);
}


function allOld(f) {
o = f.oldList.options;
n = f.newList.options;
for (var i=(o.length-1); i>=0; i--) {
if (o[i].value != "00") {
if (!IsInList(o[i].text, f.newList)) {
n[n.length] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
n[n.length-1].selected = o[i].selected;
if (n[0].value == "00") n[0] = null;
if (o.length == 1) {
o[o.length] = new Option("<--empty-->", "00", false, false);
o[o.length-1].selected = false;
}
}
}
}
sortLists(f);
}


function IsInList(theWord, theList) {
var aHit = Boolean (false);
var i = 0;

while (aHit == false && i<theList.length) {
if (theWord.toUpperCase() == theList.options[i].text.toUpperCase())
aHit = true;
i++;
}
return aHit;
}


function allNew(f) {
n = f.newList.options;
o = f.oldList.options;
for (var i=(n.length-1); i>=0; i--) {
if (n[i].value != "00") {
o[o.length-1].selected = n[i].selected;
if (o[0].value == "00") o[0] = null;
if (n.length == 1) {
n[n.length] = new Option("<--empty-->", "00", false, false);
n[n.length-1].selected = false;
}
n[i] = null;
}
}
sortLists(f);
}


function InsertNewKeyword(theform) {
selectIndex = theform.newList.length;
x = theform.newList.options;
var DuplicateWord = new Boolean (false);
var HasInvalidChars = new Boolean (false);
var IsBlank = new Boolean (false);
var InvalidChars = new RegExp ("\"|\'");

if (IsInList(theform.NewKeyword.value, theform.newList)) {
DuplicateWord = true;
alert("\"" + theform.NewKeyword.value + "\"\r" +
"is already in the keyword list");
theform.NewKeyword.focus();
theform.NewKeyword.select();
}

if (theform.NewKeyword.value == "") {
IsBlank = true;
}
if ((InvalidChars.test(theform.NewKeyword.value)) == true) {
HasInvalidChars = true;
alert(theform.NewKeyword.value + "\r" +
"has one or more invalid characters\r" +
" \" and \' are not allowed"
)
theform.NewKeyword.focus();
theform.NewKeyword.select();
}

if (IsBlank == false &&
DuplicateWord == false &&
HasInvalidChars == false) {

if (x[0].value == "00") {
x[0] == null;
selectIndex = 0;
} else {
selectIndex = theform.newList.length
}

x[selectIndex] = new Option (theform.NewKeyword.value, "", false, false);
sortLists (theform);

theform.NewKeyword.value = "";
theform.NewKeyword.focus();
}
}


function CancelNewKeyword (theform) {
theform.NewKeyword.value = "";
theform.NewKeyword.focus();
}


function delSel(f) {
x = f.oldList.options;
for (var i=(x.length-1); i>=0; i--) {
if (x[i].selected && x[i].value != "00") {
if (x.length == 1) {
x[x.length] = new Option("<--empty-->", "00", false, false);
x[x.length-1].selected = false;
}
x[i] = null;
}
}
x = f.newList.options;
for (var i=(x.length-1); i>=0; i--) {
if (x[i].selected && x[i].value != "00") {
if (x.length == 1) {
x[x.length] = new Option("<--empty-->", "00", false, false);
x[x.length-1].selected = false;
}
x[i] = null;
}
}
sortLists(f);
}

var fnd = "";

function findOption(sel, evt) {
if (window.event) var k = String.fromCharCode(event.keyCode);
else var k = String.fromCharCode(evt.which);
if (k < " " || k > "~") return true;
if (k == " ") fnd = "";
else fnd += k.toUpperCase();
for (var i=0; i<sel.options.length; i++) {
if (fnd <= sel.options[i].text.toUpperCase()) break;
}
sel.selectedIndex = i;
return false;
}
function initSelected(sel) {
window["saved"+sel.name] = new Array();
}

function prefill (theform) {
var e = theform.newList.options;

with (window.opener.DBForm.fKeywords) {
for (var i = 0; i < length; i++) {
e[i] = new Option(options[i].text, options[i].value);
}
}
theform.NewKeyword.focus();
}


function finished(theform) {
var e = theform.newList.options;
if (e[0].value=='00') e[0]=null;

window.opener.clearKeywordList();

for (var i=0; i <= e.length-1; i++) {
window.opener.addKeyword(e.options[i].text, e.options[i].text);
}

window.close();
}
// End -->
</script>

</head>

<body>

RadarBob
10-09-2002, 04:23 PM
Note: this is the 2nd of two parts. I had to split the code so I didn't exceed the 10k character limit.

This is the form on the parent page that utilitzes the dynamic list (Dynamic List - part I).

<form>
<center>
<table width="-1" border="5" height="350">
<tr>
<td border="3" valign="middle" align="center" width="-1" height="228">
Available Keywords<br><br>

<select size="14" name="oldList" width="300" multiple tabindex="1"
onKeyPress="return findOption(this)">

<%
rsAllDBKeywords.MoveFirst()

if rsAllDBKeywords.EOF then
response.write "<option value=""00"">&lt;--empty--&gt;</option>"
else
Do while not rsAllDBKeywords.EOF
response.write "<option>" & rsAllDBKeywords.fields("keyword").value & "</option>"
rsAllDBKeywords.MoveNext()
loop
end if

rsAllDBKeywords.Close
Set rsAllDBKeywords = Nothing

%>
</select>

<p><input type="button" value="Select All" onClick="
if (this.value=='Select All') {
var set=true;
this.value='Unselect';
} else {
var set=false;
this.value='Select All';
}
var opt=this.form.oldList.options;
var i, len=opt.length;
for (i=0; i<len; i++) {
opt[i].selected=set;
}
return true;"></p>
</td>

<td border="3" valign="middle" align="center" width="-1" height="228">
<input type="button" value=" > " name="selold" onClick="selOld(this.form);" title="Copy or Move Selected Items" tabindex="3"><br>
<input type="button" value=" < " name="selnew" onClick="selNew(this.form);" title="Copy or Move Selected Items" tabindex="4"><br>
<br>
<input type="button" value=" >> " name="allold" onClick="allOld(this.form);" title="Copy or Move All remaining Items" tabindex="5"><br>
<input type="button" value=" << " name="allnew" onClick="allNew(this.form);" title="Copy or Move All remaining Items" tabindex="6"><br>
<br>
</td>

<td border="3" valign="middle" align="center" width="-1" height="228">
Keywords for This Database<br><br>
<select size="6" name="newList" width="300" multiple tabindex="7"
onKeyPress="return findOption(this)">
<option value="00">&lt;--empty--&gt;</option>
</select>

<p><input type="button" value="Select All" onClick="
if (this.value=='Select All') {
var set=true;
this.value='Unselect';
} else {
var set=false;
this.value='Select All';
}
var opt=this.form.newList.options;
var i, len=opt.length;
for (i=0; i<len; i++) {
opt[i].selected=set;
}
return true;"></p>
<br>

New Keyword:<br>
<input type="text" name="NewKeyword" value=""><br>
<input type="button" name="AddNewKeyword" value=" Add " onclick="InsertNewKeyword(this.form);">&nbsp&nbsp;
<input type="button" name="CancelNewKeyword()" value=" Cancel " onclick="CancelNewKeyword(this.form);">
</td>
</tr>

<!-- Finished keyword entry button -->
<tr>
<td colspan=4 align="center">
<input type="button" name="closewindow" value=" Finished " onclick="finished(this.form)">
</td>
</tr>

</table>
</center>
</form>



Here's two functions you'll need that are on the parent page. They don't have to be on the parent page, that's just how I did it.


/*
fKeywords is a <select> that will receive the values from the child entry window.

function openKeywordWindow is triggered by the onclick event of a button on the parent page.

NOTE: To pass ALL the values back to the server when you click your SUBMIT button, all the values must be selected. Only selected values of a <select> are passed. So you need a function that simply sets the selected attribute to true which is called during the "onsubmit" event in the <form> tag.
*/
function openKeywordWindow (theform) {
DBKeywordsWindow = window.open("Keyword_Entry_Page.asp","AddKeywords","toolbar=no,menubar=yes, location=no, directories=no, width=500, height=400, resizable=yes, scrollbars=yes");
}


function addKeyword(kwText, kwValue) {
document.DBForm.fKeywords.options[document.DBForm.fKeywords.options.length] = new Option (kwText, kwValue);
}


function clearKeywordList () {
while (document.DBForm.fKeywords.length > 0) {
document.DBForm.fKeywords.options[document.DBForm.fKeywords.options.length-1] = null;
}
}

Spookster
10-09-2002, 05:03 PM
You could always just put it into a text file and attach the file to your post. :)

jkd
10-09-2002, 05:09 PM
Ah ha ha, merging threads is cool! :)