+function cbi_browser_init(id, respath, url, defpath)
+{
+ function cbi_browser_btnclick(e) {
+ cbi_filebrowser(id, url, defpath);
+ return false;
+ }
+
+ var field = document.getElementById(id);
+
+ var btn = document.createElement('img');
+ btn.className = 'cbi-image-button';
+ btn.src = respath + '/cbi/folder.gif';
+ field.parentNode.insertBefore(btn, field.nextSibling);
+
+ cbi_bind(btn, 'click', cbi_browser_btnclick);
+}
+
+function cbi_dynlist_init(name, respath, datatype, optional, choices)
+{
+ var input0 = document.getElementsByName(name)[0];
+ var prefix = input0.name;
+ var parent = input0.parentNode;
+ var holder = input0.placeholder;
+
+ var values;
+
+ function cbi_dynlist_redraw(focus, add, del)
+ {
+ values = [ ];
+
+ while (parent.firstChild)
+ {
+ var n = parent.firstChild;
+ var i = parseInt(n.index);
+
+ if (i != del)
+ {
+ if (n.nodeName.toLowerCase() == 'input')
+ values.push(n.value || '');
+ else if (n.nodeName.toLowerCase() == 'select')
+ values[values.length-1] = n.options[n.selectedIndex].value;
+ }
+
+ parent.removeChild(n);
+ }
+
+ if (add >= 0)
+ {
+ focus = add+1;
+ values.splice(focus, 0, '');
+ }
+ else if (values.length == 0)
+ {
+ focus = 0;
+ values.push('');
+ }
+
+ for (var i = 0; i < values.length; i++)
+ {
+ var t = document.createElement('input');
+ t.id = prefix + '.' + (i+1);
+ t.name = prefix;
+ t.value = values[i];
+ t.type = 'text';
+ t.index = i;
+ t.className = 'cbi-input-text';
+
+ if (i == 0 && holder)
+ {
+ t.placeholder = holder;
+ }
+
+ var b = document.createElement('img');
+ b.src = respath + ((i+1) < values.length ? '/cbi/remove.gif' : '/cbi/add.gif');
+ b.className = 'cbi-image-button';
+
+ parent.appendChild(t);
+ parent.appendChild(b);
+ parent.appendChild(document.createElement('br'));
+
+ if (datatype)
+ {
+ cbi_validate_field(t.id, ((i+1) == values.length) || optional, datatype);
+ }
+
+ if (choices)
+ {
+ cbi_combobox_init(t.id, choices[0], '', choices[1]);
+ t.nextSibling.index = i;
+
+ cbi_bind(t.nextSibling, 'keydown', cbi_dynlist_keydown);
+ cbi_bind(t.nextSibling, 'keypress', cbi_dynlist_keypress);
+
+ if (i == focus || -i == focus)
+ t.nextSibling.focus();
+ }
+ else
+ {
+ cbi_bind(t, 'keydown', cbi_dynlist_keydown);
+ cbi_bind(t, 'keypress', cbi_dynlist_keypress);
+
+ if (i == focus)
+ {
+ t.focus();
+ }
+ else if (-i == focus)
+ {
+ t.focus();
+
+ /* force cursor to end */
+ var v = t.value;
+ t.value = ' '
+ t.value = v;
+ }
+ }
+
+ cbi_bind(b, 'click', cbi_dynlist_btnclick);
+ }
+ }
+
+ function cbi_dynlist_keypress(ev)
+ {
+ ev = ev ? ev : window.event;
+
+ var se = ev.target ? ev.target : ev.srcElement;
+
+ if (se.nodeType == 3)
+ se = se.parentNode;
+
+ switch (ev.keyCode)
+ {
+ /* backspace, delete */
+ case 8:
+ case 46:
+ if (se.value.length == 0)
+ {
+ if (ev.preventDefault)
+ ev.preventDefault();
+
+ return false;
+ }
+
+ return true;
+
+ /* enter, arrow up, arrow down */
+ case 13:
+ case 38:
+ case 40:
+ if (ev.preventDefault)
+ ev.preventDefault();
+
+ return false;
+ }
+
+ return true;
+ }
+
+ function cbi_dynlist_keydown(ev)
+ {
+ ev = ev ? ev : window.event;
+
+ var se = ev.target ? ev.target : ev.srcElement;
+
+ if (se.nodeType == 3)
+ se = se.parentNode;
+
+ var prev = se.previousSibling;
+ while (prev && prev.name != name)
+ prev = prev.previousSibling;
+
+ var next = se.nextSibling;
+ while (next && next.name != name)
+ next = next.nextSibling;
+
+ /* advance one further in combobox case */
+ if (next && next.nextSibling.name == name)
+ next = next.nextSibling;
+
+ switch (ev.keyCode)
+ {
+ /* backspace, delete */
+ case 8:
+ case 46:
+ var del = (se.nodeName.toLowerCase() == 'select')
+ ? true : (se.value.length == 0);
+
+ if (del)
+ {
+ if (ev.preventDefault)
+ ev.preventDefault();
+
+ var focus = se.index;
+ if (ev.keyCode == 8)
+ focus = -focus+1;
+
+ cbi_dynlist_redraw(focus, -1, se.index);
+
+ return false;
+ }
+
+ break;
+
+ /* enter */
+ case 13:
+ cbi_dynlist_redraw(-1, se.index, -1);
+ break;
+
+ /* arrow up */
+ case 38:
+ if (prev)
+ prev.focus();
+
+ break;
+
+ /* arrow down */
+ case 40:
+ if (next)
+ next.focus();
+
+ break;
+ }
+
+ return true;
+ }
+
+ function cbi_dynlist_btnclick(ev)
+ {
+ ev = ev ? ev : window.event;
+
+ var se = ev.target ? ev.target : ev.srcElement;
+
+ if (se.src.indexOf('remove') > -1)
+ {
+ se.previousSibling.value = '';
+
+ cbi_dynlist_keydown({
+ target: se.previousSibling,
+ keyCode: 8
+ });
+ }
+ else
+ {
+ cbi_dynlist_keydown({
+ target: se.previousSibling,
+ keyCode: 13
+ });
+ }
+
+ return false;
+ }
+
+ cbi_dynlist_redraw(NaN, -1, -1);
+}
+