Now with attachments! On 11/6/07, Al Tobey <tobert@xxxxxxxxx> wrote: > On 11/5/07, Michael DeHaan <mdehaan@xxxxxxxxxx> wrote: > > Al Tobey wrote: > > > I got distracted by the multiple interface system edit screen and > > > decided to clean it up a bit. A patch and partial screenshot are > > > attached. > > Nice... > > > > I do like the boxes and not repeating the tooltips for the later interfaces. > > > > > The javascript is a lot less complex. The screen looks a lot more > > > useable for the common case now. The help text is hidden for > > > interfaces > 0, which saves a ton of vertical space. Each interface > > > is in its own fieldset element now, which groups it better IMO. > > > Configured interfaces are displayed by default. > > > > > > I took out the image-based +/- for now, but it can go back if people > > > really like it better. I only changed it to simplify things while > > > hacking. Most of the stuff in cobbler.js can go away if this approach > > > is taken instead. > > > > > > > Well, Cobbler.js is going to stay. The point is to get the javascript > > code pulled out of the templates > > as much as possible, so it can be read all in one place, and we don't > > have things copy/pasted everywhere > > when they are more generically useful. Ideally the javascript code in > > this patch would be moved there. > > > > A few things I'd like to see done before I can apply this: > > > > -- Have you tested this in MSIE? > > -- Put back the +/- graphics > > -- Fix mixed tabs/spaces > > New patch attached. > > I only tested IE7 which was horribly broken. I think the <hr/>'s > were defaulting to width="100%" or something, making the left nav bar > width 100%. I forced the div containing the nav bar to 200px in the > CSS which seems to have brought it under control. > > -Al > > > > > Thanks! > > > > --Michael > > > > > > > -Al > > > > > > ------------------------------------------------------------------------ > > > > > > ------------------------------------------------------------------------ > > > > > > _______________________________________________ > > > et-mgmt-tools mailing list > > > et-mgmt-tools@xxxxxxxxxx > > > https://www.redhat.com/mailman/listinfo/et-mgmt-tools > > > > _______________________________________________ > > et-mgmt-tools mailing list > > et-mgmt-tools@xxxxxxxxxx > > https://www.redhat.com/mailman/listinfo/et-mgmt-tools > > >
From b2a0b3b4a33e327ae3a60f4fe45e019e0811be14 Mon Sep 17 00:00:00 2001 From: Al Tobey <tobert@xxxxxxxxx> Date: Tue, 6 Nov 2007 12:35:36 -0800 Subject: [PATCH] Rework system edit webui screen. Fix up MSIE7 support. --- webui_content/cobbler.js | 235 +++++-------------------- webui_content/style.css | 3 +- webui_templates/master.tmpl | 2 + webui_templates/system_edit.tmpl | 354 ++++++++++++++++---------------------- 4 files changed, 197 insertions(+), 397 deletions(-) diff --git a/webui_content/cobbler.js b/webui_content/cobbler.js index 318a342..24cd314 100644 --- a/webui_content/cobbler.js +++ b/webui_content/cobbler.js @@ -14,10 +14,6 @@ IMAGE_EXPANDED_PATH = '/cobbler/webui/list-collapse.png'; //not really used: IMAGE_CHILDLESS_PATH = '/cobbler/webui/list-parent.png'; -var rowHash = new Array(); -var browserType; -var columnsPerRow; - // tip of the Red Hat to Mar Orlygsson for this little IE detection script var is_ie/*@cc_on = { quirksmode : (document.compatMode=="BackCompat"), @@ -25,197 +21,62 @@ var is_ie/*@cc_on = { }@*/; browserType = is_ie; -function onLoadStuff(columns) { - columnsPerRow = columns; - var channelTable = document.getElementById('channel-list'); - createParentRows(channelTable, rowHash); - reuniteChildrenWithParents(channelTable, rowHash); - iconifyChildlessParents(rowHash); -} - -function iconifyChildlessParents(rowHash) { - for (var i in rowHash) { - if (!rowHash[i].hasChildren && rowHash[i].image) { - // not needed in this implementation - // rowHash[i].image.src = IMAGE_CHILDLESS_PATH; +function system_edit_vis_toggle(target, num, display) +{ + t = document.getElementById(target + num); + c = document.getElementById('control' + num); + next_num = num + 1; + next = document.getElementById('interface' + next_num); + + current = t.style.display; + + if ( display ) { + if ( display == 'none' ) { + current = 'block'; + } + if ( display == 'block' ) { + current = 'none'; + } } - } -} -// called from clicking the show/hide button on individual rows in the page -function toggleRowVisibility(id) { - if (!rowHash[id]) { return; } - if (!rowHash[id].hasChildren) { return; } - rowHash[id].toggleVisibility(); - return; -} - -function showAllRows() { - var row; - for (var i in rowHash) { - row = rowHash[i]; - if (!row) { continue; } - if (!row.hasChildren) { continue; } - row.show(); - } - return; -} - -function hideAllRows() { - var row; - for (var i in rowHash) { - row = rowHash[i]; - if (!row) { continue; } - if (!row.hasChildren) { continue; } - row.hide(); - } - return; -} - -function Row(cells, image) { - this.cells = new Array(); - for (var i = 0; i < cells.length; i++) { this.cells[i] = cells[i]; } - this.image = image; - this.hasChildren = 0; - this.isHidden = 0; // 1 = hidden; 0 = visible. all rows are visible by default - - -// Row object methods below! - this.toggleVisibility = function() { - if (this.isHidden == 1) { this.show(); } - else if (this.isHidden == 0) { this.hide(); } - return; - } - - this.hide = function hide() { - - this.image.src = IMAGE_COLLAPSED_PATH; - // we start with columnsPerRow, because we want to skip the td cells of the parent tr. - for (var i = columnsPerRow; i < this.cells.length; i++) { - // this looks suspicious - // this.cells[i].parentNode.style.display = 'none'; - - // MPD: I added this: - if (! this.isParent) { - this.cells[i].style.display = 'none'; - } + if ( t.style.display == 'block' ) { + t.style.display = 'none'; + if ( c ) { + c.innerHTML='<img src="' + IMAGE_COLLAPSED_PATH + '" alt="[+]"/>'; + } } - this.isHidden = 1; - return; - } - - this.show = function() { - displayType = ''; - this.image.src = IMAGE_EXPANDED_PATH; - - for (var i = 0; i < this.cells.length; i++) { - this.cells[i].style.display = ''; - // also suspicious - // this.cells[i].parentNode.style.display = displayType; + else if ( t.style.display == 'none' ) { + t.style.display = 'block'; + if ( c ) { + c.innerHTML='<img src="' + IMAGE_EXPANDED_PATH + '" alt="[-]"/>'; + } + if ( next ) { + next.style.display = 'block'; + } } - this.isHidden = 0; - return; - } } -function createParentRows(channelTable, rowHash) { - for (var i = 0; i < channelTable.rows.length; i++) { - tableRowNode = channelTable.rows[i]; - if (isParentRowNode(tableRowNode)) { - if (!tableRowNode.id) { continue; } - id = tableRowNode.id; - var cells = tableRowNode.cells; - var image = findRowImageFromCells(cells, id) - if (!image) { continue; } - rowHash[id] = new Row(cells, image); - // MPD: I added this - rowHash[id].isParent = 1 +function disablename(value) +{ + document.getElementById("name").disabled=value; + if (value) { + document.getElementById("name").value = "$system.name"; } - else { - // MPD: I added this - rowHash[id].isParent = 0 - - } - } - return; -} - -function reuniteChildrenWithParents(channelTable, rowHash) { - var parentNode; - var childId; - var tableChildRowNode; - for (var i = 0; i < channelTable.rows.length; i++) { - tableChildRowNode = channelTable.rows[i]; - // when we find a parent, set it as parent for the children after it - if (isParentRowNode(tableChildRowNode) && tableChildRowNode.id) { - parentNode = tableChildRowNode; - continue; - } - if (!parentNode) { continue; } - - // it its not a child node we bail here - if (!isChildRowNode(tableChildRowNode)) { continue; } - // check child id against parent id - if (!rowHash[parentNode.id]) { /*alert('bailing, cant find parent in hash');*/ continue; } - for (var j = 0; j < tableChildRowNode.cells.length; j++) { - rowHash[parentNode.id].cells.push(tableChildRowNode.cells[j]); - rowHash[parentNode.id].hasChildren = 1; - } - } - return; -} - - -function getNodeTagName(node) { - var tagName; - var nodeId; - tagName = new String(node.tagName); - return tagName.toLowerCase(); -} - -function isParentRowNode(node) { - var nodeInLowercase = getNodeTagName(node); - if (nodeInLowercase != 'tr') { return 0; } - nodeId = node.id; - if ((nodeId.indexOf('id')) && !(nodeId.indexOf('child'))) { - return 0; - } - return 1; -} - -function isChildRowNode(node) { - var nodeInLowercase = getNodeTagName(node); - var nodeId; - if (nodeInLowercase != 'tr') { return 0; } - nodeId = node.id; - if (nodeId.indexOf('child')) { return 0; } - return 1; } - -function findRowImageFromCells(cells, id) { - var imageId = id + '-image'; - var childNodes; // first level child - var grandchildNodes; // second level child - for (var i = 0; i < cells.length; i++) { - childNodes = null; - grandchildNodes = null; - - if (!cells[i].hasChildNodes()) { continue; } - - childNodes = cells[i].childNodes; - - for (var j = 0; j < childNodes.length; j++) { - if (!childNodes[j].hasChildNodes()) { continue; } - if (getNodeTagName(childNodes[j]) != 'a') { continue; } - grandchildNodes = childNodes[j].childNodes; - - for (var k = 0; k < grandchildNodes.length; k++) { - if (grandchildNodes[k].name != imageId) { continue; } - if (grandchildNodes[k].nodeName == 'IMG' || grandchildNodes[k].nodeName == 'img') { return grandchildNodes[k]; } - } - } - } - return null; +function get_random_mac() +{ + xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", "$base_url/random_mac", true); + xmlHttp.onreadystatechange = function () { + if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { + var mac_field = document.getElementById("macaddress") + var result = xmlHttp.responseText; + if (result.charAt(2) == ':' && result.charAt(5) == ':') { + mac_field.value = result; + } + } + }; + xmlHttp.send(null); } diff --git a/webui_content/style.css b/webui_content/style.css index 17e17b8..321e5a4 100644 --- a/webui_content/style.css +++ b/webui_content/style.css @@ -47,6 +47,7 @@ ul { #sidebar { height: auto; + width: 200px; float: left; } @@ -103,7 +104,7 @@ div#main { } div#content { - width: 70%; + width: auto; float: right; padding: 0px 24px; } diff --git a/webui_templates/master.tmpl b/webui_templates/master.tmpl index abd09af..db6e171 100644 --- a/webui_templates/master.tmpl +++ b/webui_templates/master.tmpl @@ -26,6 +26,7 @@ <div id="main"> +<div style="clear: both;"/> <div id="sidebar"> <ul id="nav"> <li><a href="/cobbler/webui/wui.html" class="menu">Docs</a></li> @@ -56,6 +57,7 @@ #end block body </div><!-- content --> +<div style="clear: both;"/> </div><!-- main --> </body> diff --git a/webui_templates/system_edit.tmpl b/webui_templates/system_edit.tmpl index 83d5908..3429a0d 100644 --- a/webui_templates/system_edit.tmpl +++ b/webui_templates/system_edit.tmpl @@ -8,83 +8,18 @@ ### FIXME: add gateway, subnet, and any other missing fields #set $fields = [ "macaddress", "ipaddress", "hostname", "dhcptag", "virtbridge", "subnet", "gateway"] +#set $all_interfaces = [ "intf0", "intf1", "intf2", "intf3", "intf4", "intf5", "intf6", "intf7" ] - -<script language="javascript"> - +<script type="text/javascript"> +//<![CDATA[ function delete_interface(num) { #for $field in $fields document.getElementById("${field}-intf" + num).value = ""; #end for - toggleRowVisibility("id" + num); -} - -#if $system -function disablename(value) -{ - document.getElementById("name").disabled=value; - if (value) { - document.getElementById("name").value = "$system.name"; - } -} -#else -function get_random_mac() -{ - xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", "$base_url/random_mac", true); - xmlHttp.onreadystatechange = function () { - if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { - var mac_field = document.getElementById("macaddress") - var result = xmlHttp.responseText; - if (result.charAt(2) == ':' && result.charAt(5) == ':') { - mac_field.value = result; - } - } - }; - xmlHttp.send(null); -} -#end if -</script> - -## -## determine a bit about what interfaces should be shown and which should not. -## - -#set $all_interfaces = [ "intf0", "intf1", "intf2", "intf3", "intf4", "intf5", "intf6", "intf7" ] -#if $system - #set $interfaces = $system.interfaces.keys() - #set $defined_interfaces = [] - #for $potential in $all_interfaces - #if $potential in $interfaces - #set $rc = $defined_interfaces.append($potential) - #end if - #end for -#else - #set $interfaces = [ "intf0", "intf1", "intf2", "intf3", "intf4", "intf5", "intf6", "intf7" ] - #set $defined_interfaces = [ "intf0" ] -#end if - - -### -### now generate the onload function. -### - -<script language="javascript"> - -function page_onload() { - - onLoadStuff(2); - hideAllRows(); - #set counter = 0 - #for $interface in $all_interfaces - #if $interface in $defined_interfaces - toggleRowVisibility("id${counter}"); - #end if - #set $counter = $counter+1 - #end for - + toggle_vis('form', num, 'none'); } +//]]> </script> <form method="post" action="$base_url/system_save"> @@ -208,12 +143,13 @@ function page_onload() { </td> </tr> - ## ====================================== start of looping through interfaces #set $counter = -1 + #set $have_add_control = None #for $interface in $all_interfaces - #set $counter = $counter+1 + #set $counter = $counter+1 + #set $display = 'none' ## ---------------------------------- ## load up initial variable values @@ -227,6 +163,7 @@ function page_onload() { #set $virtbridge = $system.interfaces[$interface]["virt_bridge"] #set $subnet = $system.interfaces[$interface]["subnet"] #set $gateway = $system.interfaces[$interface]["gateway"] + #set $display = 'block' #else #set $macaddress = "" #set $ipaddress = "" @@ -235,149 +172,148 @@ function page_onload() { #set $virtbridge = "" #set $subnet = "" #set $gateway = "" + #if $counter < 1: + #set display = 'block' + #else + #set display = 'none' + #end if #end if - ## ---------------------------------------- - ## render the toggle link to hide the interfaces not yet defined - ## ---------------------------------------- - - <tr class="listrow" id="1000${counter}"> - <td> - <hr width="100%"/> - </td> - <td> - <hr width="100%"/> - </td> - </tr> - -## -##<td><a onclick="toggleRowVisibility('id263');" style="cursor: pointer;"><img name="id263-image" src="/img/list-expand.gif" alt=""/></a><a href="/network/software/channels/details.pxt?cid=263">Red Hat Enterprise Linux (v. 5 for 32-bit x86)</a></td> -## + <tr class="listrow" id="tr${counter}"> + <td> + #if $counter == 0: + Interface $interface.replace("intf","") + #else + <span id="interface${counter}" + #if $have_add_control is None: + style="display: block;" + #set $have_add_control = 1 + #else if $display is 'block': + style="display: block;" + #else + style="display: none;" + #end if + > + Interface $interface.replace("intf","") + <a onclick="system_edit_vis_toggle('form', ${counter});" id="control${counter}" style="cursor: pointer;"><img src="/cobbler/webui/list-expand.png" alt="[+]"></a> + </span> + #end if + </td> - <tr class="listrow" id="id${counter}"> - <td> - Interface $interface.replace("intf","") - </td> - <td> - <a onclick="toggleRowVisibility('id${counter}');" style="cursor: pointer;"><img name="id${counter}-image" src="/cobbler/webui/list-expand.png" alt=""/></A> - </td> - </tr> + <td> + <div id="form${counter}" style="display: $display;"> + <br/> + <fieldset id="cform"> - ## ---------------------------------------- - ## now show all of the interface fields which may or may not - ## be hidden but are always there - ## ---------------------------------------- - - <tr class="listrow" id="child-id${counter}-0"> - <td> - <label for="macaddress-$interface">MAC</label> - </td> - <td> - <input type="text" size="64" style="width: 150px;" name="macaddress-$interface" id="macaddress-$interface" - value="$macaddress" - /> - #if not $system - <a href="javascript: get_random_mac()" style="font-size: 0.8em;">random</a> - #end if - <p class="context-tip">Example: AA:BB:CC:DD:EE:FF</p> - </td> - </tr> - - <tr class="listrow" id="child-id${counter}-1"> - <td> - <label for="ipaddress-$interface">IP</label> - </td> - <td> - <input type="text" size="64" style="width: 150px;" name="ipaddress-$interface" id="ipaddress-$interface" - value="$ipaddress" - /> - <p class="context-tip">Example: 192.168.10.15</p> - </td> - </tr> - - <tr class="listrow" id="child-id${counter}-3"> - <td> - <label for="hostname-$interface">Hostname</label> - </td> - <td> - <input type="text" size="255" style="width: 150px;" name="hostname-$interface" id="hostname-$interface" - value="$hostname" - /> - <p class="context-tip">Example: vanhalen.example.org</p> - </td> - </tr> - - <tr class="listrow" id="child-id${counter}-4"> - <td> - <label for="dhcptag-$interface">DHCP Tag</label> - </td> - <td> - <input type="text" size="128" style="width: 150px;" name="dhcptag-$interface" id="dhcptag-$interface" - value="$dhcptag" - /> - <p class="context-tip">Selects alternative subnets, see manpage or leave blank</p> - </td> - </tr> - - ## FIXME: add virt_bridge editing (like above) - - <tr class="listrow" id="child-id${counter}-5"> - <td> - <label for="virtbridge-$interface">Virt Bridge</label> - </td> - <td> - <input type="text" size="20" style="width: 150px;" name="virtbridge-$interface" id="virtbridge-$interface" - value="$virtbridge" - /> - <p class="context-tip">Example: 'xenbr0' or 'virbr0'. Can be blank if set in profile or settings.</p> - </td> - </tr> - - ## FIXME: add subnet editing (like above) - - <tr class="listrow" id="child-id${counter}-6"> - <td> - <label for="subnet-$interface">Subnet</label> - </td> - <td> - <input type="text" size="64" style="width: 150px;" name="subnet-$interface" id="subnet-$interface" - value="$subnet" - /> - <p class="context-tip">Ex: "255.255.255.0". For use in kickstart templates for static IPs.</p> - </td> - </tr> - - ## FIXME: add gateway editing (like above) - - <tr class="listrow" id="child-id${counter}-7"> - <td> - <label for="gateway-$interface">Gateway</label> - </td> - <td> - <input type="text" size="64" style="width: 150px;" name="gateway-$interface" id="gateway-$interface" - value="$gateway" - /> - <p class="context-tip">Ex: "192.168.1.11". For use in kickstart templates for static IPs.</p> + <!-- MAC --> + <label for="macaddress-$interface">MAC</label> + <input type="text" size="64" style="width: 150px;" name="macaddress-$interface" id="macaddress-$interface" + value="$macaddress" + /> + #if not $system + <a href="javascript: get_random_mac()" style="font-size: 0.8em;">random</a> + #end if + #if $counter == 0: + <p class="context-tip">Example: AA:BB:CC:DD:EE:FF</p> + #else: + <br/> + #end if + + <!-- IP --> + <label for="ipaddress-$interface">IP</label> + <input type="text" size="64" style="width: 150px;" + name="ipaddress-$interface" id="ipaddress-$interface" + value="$ipaddress"/> + #if $counter == 0: + <p class="context-tip">Example: 192.168.10.15</p> + #else: + <br/> + #end if + + <! -- hostname --> + <label for="hostname-$interface">Hostname</label> + <input type="text" size="255" style="width: 150px;" + name="hostname-$interface" id="hostname-$interface" + value="$hostname" + /> + #if $counter == 0: + <p class="context-tip">Example: vanhalen.example.org</p> + #else: + <br/> + #end if + + <!-- DHCP Tag --> + <label for="dhcptag-$interface">DHCP Tag</label> + <input type="text" size="128" style="width: 150px;" + name="dhcptag-$interface" id="dhcptag-$interface" + value="$dhcptag"/> + #if $counter == 0: + <p class="context-tip">Selects alternative subnets, see manpage or leave blank</p> + #else: + <br/> + #end if + + ## FIXME: add virt_bridge editing (like above) + + <!-- Virt Bridge --> + <label for="virtbridge-$interface">Virt Bridge</label> + <input type="text" size="20" style="width: 150px;" + name="virtbridge-$interface" id="virtbridge-$interface" + value="$virtbridge"/> + #if $counter == 0: + <p class="context-tip">Example: 'xenbr0' or 'virbr0'. Can be blank if set in profile or settings.</p> + #else: + <br/> + #end if + + ## FIXME: add subnet editing (like above) + + <!-- Gateway --> + <label for="subnet-$interface">Subnet</label> + <input type="text" size="64" style="width: 150px;" + name="subnet-$interface" id="subnet-$interface" + value="$subnet"/> + #if $counter == 0: + <p class="context-tip">Ex: "255.255.255.0". For use in kickstart templates for static IPs.</p> + #else: + <br/> + #end if + + ## FIXME: add gateway editing (like above) + + <!-- Gateway Interface --> + <label for="gateway-$interface">Gateway</label> + <input type="text" size="64" style="width: 150px;" + name="gateway-$interface" id="gateway-$interface" + value="$gateway"/> + #if $counter == 0: + <p class="context-tip">Ex: "192.168.1.11". For use in kickstart templates for static IPs.</p> + #else: + <br/> + #end if + + <!-- remove button --> + #if $interface != "intf0" + <label for="enabled-$interface">Remove</label> + <input type="button" name="delete-$interface" + value="remove" onclick="delete_interface($counter);"/> + #if $counter == 0: + <p class="context-tip">Clicking this button removes the interface from the configuration.</p> + #else: + <br/> + #end if + #end if + + + ## FIXME: make the save function understand the new + ## fieldname-$interface variables only enable an interface for + ## saving if one of it's fields is non-empty + ## FIXME: delete checkboxes and accompanying API method. No + ## delete for intf0. + </fieldset> + </div> </td> </tr> - - #if $interface != "intf0" - <tr class="listrow" id="child-id${counter}-8"> - <td> - <label for="enabled-$interface">Remove</label> - </td> - <td> - <input type="button" name="delete-$interface" value="remove" onclick="delete_interface($counter)"> - <p class="context-tip">Clicking this button removes the interface from the configuration.</p> - </td> - </tr> - #end if - - - ## FIXME: make the save function understand the new fieldname-$interface variables - ## only enable an interface for saving if one of it's fields is non-empty - ## FIXME: delete checkboxes and accompanying API method. No delete for intf0. - #end for ## ====================================== end of looping through interfaces -- 1.5.3.4
_______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools