[PATCH] UI: Display iSCSI targets for Selection

From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- ui/css/theme-default/storage.css | 50 +++++++++++++++++++ ui/js/src/kimchi.api.js | 16 ++++++ ui/js/src/kimchi.storagepool_add_main.js | 76 ++++++++++++++++++++++++++++++ ui/pages/storagepool-add.html.tmpl | 7 ++- 4 files changed, 147 insertions(+), 2 deletions(-) diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css index 4f439e8..cb0caee 100644 --- a/ui/css/theme-default/storage.css +++ b/ui/css/theme-default/storage.css @@ -593,3 +593,53 @@ center no-repeat; padding: 0 20px 0 26px; } + +.storage-admin .filter-select { + display: inline-block; + position: relative; +} + +.storage-admin .filter-select input { + border: 1px solid #CCCCCC; + border-radius: 1px; + font-size: 14px; + color: #666666; + padding: 3px 3px 3px 10px; + height: 30px; + width: 493px; +} + +.storage-admin .filter-select input::-ms-clear { + display: none; +} + +.storage-admin .filter-select .arrow { + display: inline-block; + vertical-align: middle; + position: relative; + left: -25px; +} + +.storage-admin .filter-select .option { + border-style: solid; + border-color: #CCCCCC; + border-width: 0px 1px 1px 1px; + border-radius: 1px; + font-size: 14px; + background-color: white; + width: 506px; + max-height: 140px; + overflow: auto; + color: #666666; + position: absolute; + z-index: 1000; +} + +.storage-admin .filter-select .option .item { + padding: 5px 10px; + cursor: pointer; +} + +.storage-admin .filter-select .option .item:hover { + background-color: #DDDDDD; +} diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 4562992..d89919e 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1098,5 +1098,21 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + getISCSITargets : function(server, port, suc, err) { + server = encodeURIComponent(server); + port = encodeURIComponent(port); + kimchi.requestJSON({ + url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi&_server_port='+port, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend : true, + success : suc, + error : err ? err : function(data) { + kimchi.message.error(data.responseJSON.reason); + } + }); } }; diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js index ecbc682..49ba9e1 100644 --- a/ui/js/src/kimchi.storagepool_add_main.js +++ b/ui/js/src/kimchi.storagepool_add_main.js @@ -34,6 +34,78 @@ kimchi.storagepool_add_main = function() { }); }; +kimchi.storageFilterSelect = function(id, isUpdate) { + var input = $('input', '#'+id); + var options = $(".option", '#'+id); + var filter = function(container, key){ + container.children().each(function(){ + $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : ""); + }); + }; + if(!isUpdate){ + $('.arrow', '#'+id).click(function(){ + options.toggleClass("hide-content"); + }); + input.focus(function(){ + options.removeClass("hide-content"); + }).on("keyup", function(){ + filter(options, input.val()); + }); + } + options.children().each(function(){ + $(this).click(function(){ + input.val($(this).text()); + $('.option', "#iSCSITarget").addClass("hide-content"); + filter(options, ""); + }); + }); +}; + +kimchi.initISCSITargets = function(){ + var loadTargets = function(server, port, callback){ + var isUpdate = $(".option", "#iSCSITarget").children().length > 0; + $(".option", "#iSCSITarget").empty(); + $('input', "#iSCSITarget").val("loading targets..."); + kimchi.getISCSITargets(server, port, function(data){ + if(data.length==0){ + $('input', "#iSCSITarget").val("no targets is got."); + }else{ + for(var i=0; i<data.length; i++){ + var itemNode = $.parseHTML("<div class='item'>"+data[i].target+"</div>"); + $(".option", "#iSCSITarget").append(itemNode); + } + kimchi.storageFilterSelect('iSCSITarget', isUpdate); + $('input', "#iSCSITarget").attr("readonly", false); + $('input', "#iSCSITarget").val(""); + $('input', "#iSCSITarget").trigger("focus"); + } + callback(); + }, function(data){ + $('input', "#iSCSITarget").val("failed to load targets."); + kimchi.message.error(data.responseJSON.reason); + callback(); + }); + }; + var triggerLoadTarget = function(){ + var server = $("#iscsiserverId").val().trim(); + var port = $("#iscsiportId").val().trim(); + if(server!="" && port!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){ + $("#iscsiserverId").attr("disabled", true); + $("#iscsiportId").attr("disabled", true); + loadTargets(server, port, function(){ + $("#iscsiserverId").attr("disabled", false); + $("#iscsiportId").attr("disabled", false); + }); + } + }; + $("#iscsiserverId").change(function(){ + triggerLoadTarget(); + }); + $("#iscsiportId").change(function(){ + triggerLoadTarget(); + }); +}; + kimchi.initStorageAddPage = function() { kimchi.listHostPartitions(function(data) { if (data.length > 0) { @@ -160,6 +232,10 @@ kimchi.initStorageAddPage = function() { $('#iscsiportId').keyup(function(event) { $(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val())); }); + $('#iscsiserverId').keyup(function(event) { + $(this).toggleClass("invalid-field",!kimchi.isServer($(this).val().trim())); + }); + kimchi.initISCSITargets(); }; /* Returns 'true' if all form fields were filled, 'false' if diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl index 1eb2029..ee19ed5 100644 --- a/ui/pages/storagepool-add.html.tmpl +++ b/ui/pages/storagepool-add.html.tmpl @@ -23,7 +23,7 @@ <!DOCTYPE html> <html> <body> - <div class="window storage-window"> + <div class="window storage-window storage-admin"> <header> <h1 class="title">$_("Define a New Storage Pool")</h1> <div class="close">X</div> @@ -119,7 +119,10 @@ <h2>4. $_("Target")</h2> <div class="field"> <p class="text-help">$_("The iSCSI target on iSCSI server")</p> - <input id="iscsiTargetId" type="text" class="text storage-base-input-width"> + <span class="filter-select" id="iSCSITarget"> + <div><input id="iscsiTargetId" type="text" readonly><a class="ui-icon ui-icon-triangle-1-s arrow"></a></div> + <div class="option hide-content"></div> + </span> </div> </section> <section class="form-section"> -- 1.7.1

Reviewed-by: Daniel Barboza <danielhb@linux.vnet.ibm.com> Tested-by: Daniel Barboza <danielhb@linux.vnet.ibm.com> On 08/22/2014 06:40 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com>
Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- ui/css/theme-default/storage.css | 50 +++++++++++++++++++ ui/js/src/kimchi.api.js | 16 ++++++ ui/js/src/kimchi.storagepool_add_main.js | 76 ++++++++++++++++++++++++++++++ ui/pages/storagepool-add.html.tmpl | 7 ++- 4 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css index 4f439e8..cb0caee 100644 --- a/ui/css/theme-default/storage.css +++ b/ui/css/theme-default/storage.css @@ -593,3 +593,53 @@ center no-repeat; padding: 0 20px 0 26px; } + +.storage-admin .filter-select { + display: inline-block; + position: relative; +} + +.storage-admin .filter-select input { + border: 1px solid #CCCCCC; + border-radius: 1px; + font-size: 14px; + color: #666666; + padding: 3px 3px 3px 10px; + height: 30px; + width: 493px; +} + +.storage-admin .filter-select input::-ms-clear { + display: none; +} + +.storage-admin .filter-select .arrow { + display: inline-block; + vertical-align: middle; + position: relative; + left: -25px; +} + +.storage-admin .filter-select .option { + border-style: solid; + border-color: #CCCCCC; + border-width: 0px 1px 1px 1px; + border-radius: 1px; + font-size: 14px; + background-color: white; + width: 506px; + max-height: 140px; + overflow: auto; + color: #666666; + position: absolute; + z-index: 1000; +} + +.storage-admin .filter-select .option .item { + padding: 5px 10px; + cursor: pointer; +} + +.storage-admin .filter-select .option .item:hover { + background-color: #DDDDDD; +} diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 4562992..d89919e 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1098,5 +1098,21 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + getISCSITargets : function(server, port, suc, err) { + server = encodeURIComponent(server); + port = encodeURIComponent(port); + kimchi.requestJSON({ + url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi&_server_port='+port, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend : true, + success : suc, + error : err ? err : function(data) { + kimchi.message.error(data.responseJSON.reason); + } + }); } }; diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js index ecbc682..49ba9e1 100644 --- a/ui/js/src/kimchi.storagepool_add_main.js +++ b/ui/js/src/kimchi.storagepool_add_main.js @@ -34,6 +34,78 @@ kimchi.storagepool_add_main = function() { }); };
+kimchi.storageFilterSelect = function(id, isUpdate) { + var input = $('input', '#'+id); + var options = $(".option", '#'+id); + var filter = function(container, key){ + container.children().each(function(){ + $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : ""); + }); + }; + if(!isUpdate){ + $('.arrow', '#'+id).click(function(){ + options.toggleClass("hide-content"); + }); + input.focus(function(){ + options.removeClass("hide-content"); + }).on("keyup", function(){ + filter(options, input.val()); + }); + } + options.children().each(function(){ + $(this).click(function(){ + input.val($(this).text()); + $('.option', "#iSCSITarget").addClass("hide-content"); + filter(options, ""); + }); + }); +}; + +kimchi.initISCSITargets = function(){ + var loadTargets = function(server, port, callback){ + var isUpdate = $(".option", "#iSCSITarget").children().length > 0; + $(".option", "#iSCSITarget").empty(); + $('input', "#iSCSITarget").val("loading targets..."); + kimchi.getISCSITargets(server, port, function(data){ + if(data.length==0){ + $('input', "#iSCSITarget").val("no targets is got."); + }else{ + for(var i=0; i<data.length; i++){ + var itemNode = $.parseHTML("<div class='item'>"+data[i].target+"</div>"); + $(".option", "#iSCSITarget").append(itemNode); + } + kimchi.storageFilterSelect('iSCSITarget', isUpdate); + $('input', "#iSCSITarget").attr("readonly", false); + $('input', "#iSCSITarget").val(""); + $('input', "#iSCSITarget").trigger("focus"); + } + callback(); + }, function(data){ + $('input', "#iSCSITarget").val("failed to load targets."); + kimchi.message.error(data.responseJSON.reason); + callback(); + }); + }; + var triggerLoadTarget = function(){ + var server = $("#iscsiserverId").val().trim(); + var port = $("#iscsiportId").val().trim(); + if(server!="" && port!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){ + $("#iscsiserverId").attr("disabled", true); + $("#iscsiportId").attr("disabled", true); + loadTargets(server, port, function(){ + $("#iscsiserverId").attr("disabled", false); + $("#iscsiportId").attr("disabled", false); + }); + } + }; + $("#iscsiserverId").change(function(){ + triggerLoadTarget(); + }); + $("#iscsiportId").change(function(){ + triggerLoadTarget(); + }); +}; + kimchi.initStorageAddPage = function() { kimchi.listHostPartitions(function(data) { if (data.length > 0) { @@ -160,6 +232,10 @@ kimchi.initStorageAddPage = function() { $('#iscsiportId').keyup(function(event) { $(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val())); }); + $('#iscsiserverId').keyup(function(event) { + $(this).toggleClass("invalid-field",!kimchi.isServer($(this).val().trim())); + }); + kimchi.initISCSITargets(); };
/* Returns 'true' if all form fields were filled, 'false' if diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl index 1eb2029..ee19ed5 100644 --- a/ui/pages/storagepool-add.html.tmpl +++ b/ui/pages/storagepool-add.html.tmpl @@ -23,7 +23,7 @@ <!DOCTYPE html> <html> <body> - <div class="window storage-window"> + <div class="window storage-window storage-admin"> <header> <h1 class="title">$_("Define a New Storage Pool")</h1> <div class="close">X</div> @@ -119,7 +119,10 @@ <h2>4. $_("Target")</h2> <div class="field"> <p class="text-help">$_("The iSCSI target on iSCSI server")</p> - <input id="iscsiTargetId" type="text" class="text storage-base-input-width"> + <span class="filter-select" id="iSCSITarget"> + <div><input id="iscsiTargetId" type="text" readonly><a class="ui-icon ui-icon-triangle-1-s arrow"></a></div> + <div class="option hide-content"></div> + </span> </div> </section> <section class="form-section">

You also need to do the same for the iSCSI servers by listing the already used before. The same we did for NFS. There is a function for it: getStorageServers("iscsi") On 08/22/2014 06:40 AM, huoyuxin@linux.vnet.ibm.com wrote:
From: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com>
Signed-off-by: Yu Xin Huo <huoyuxin@linux.vnet.ibm.com> --- ui/css/theme-default/storage.css | 50 +++++++++++++++++++ ui/js/src/kimchi.api.js | 16 ++++++ ui/js/src/kimchi.storagepool_add_main.js | 76 ++++++++++++++++++++++++++++++ ui/pages/storagepool-add.html.tmpl | 7 ++- 4 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/ui/css/theme-default/storage.css b/ui/css/theme-default/storage.css index 4f439e8..cb0caee 100644 --- a/ui/css/theme-default/storage.css +++ b/ui/css/theme-default/storage.css @@ -593,3 +593,53 @@ center no-repeat; padding: 0 20px 0 26px; } + +.storage-admin .filter-select { + display: inline-block; + position: relative; +} + +.storage-admin .filter-select input { + border: 1px solid #CCCCCC; + border-radius: 1px; + font-size: 14px; + color: #666666; + padding: 3px 3px 3px 10px; + height: 30px; + width: 493px; +} + +.storage-admin .filter-select input::-ms-clear { + display: none; +} + +.storage-admin .filter-select .arrow { + display: inline-block; + vertical-align: middle; + position: relative; + left: -25px; +} + +.storage-admin .filter-select .option { + border-style: solid; + border-color: #CCCCCC; + border-width: 0px 1px 1px 1px; + border-radius: 1px; + font-size: 14px; + background-color: white; + width: 506px; + max-height: 140px; + overflow: auto; + color: #666666; + position: absolute; + z-index: 1000; +} + +.storage-admin .filter-select .option .item { + padding: 5px 10px; + cursor: pointer; +} + +.storage-admin .filter-select .option .item:hover { + background-color: #DDDDDD; +} diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js index 4562992..d89919e 100644 --- a/ui/js/src/kimchi.api.js +++ b/ui/js/src/kimchi.api.js @@ -1098,5 +1098,21 @@ var kimchi = { kimchi.message.error(data.responseJSON.reason); } }); + }, + + getISCSITargets : function(server, port, suc, err) { + server = encodeURIComponent(server); + port = encodeURIComponent(port); + kimchi.requestJSON({ + url : kimchi.url + 'storageservers/'+server+'/storagetargets?_target_type=iscsi&_server_port='+port, + type : 'GET', + contentType : 'application/json', + dataType : 'json', + resend : true, + success : suc, + error : err ? err : function(data) { + kimchi.message.error(data.responseJSON.reason); + } + }); } }; diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js index ecbc682..49ba9e1 100644 --- a/ui/js/src/kimchi.storagepool_add_main.js +++ b/ui/js/src/kimchi.storagepool_add_main.js @@ -34,6 +34,78 @@ kimchi.storagepool_add_main = function() { }); };
+kimchi.storageFilterSelect = function(id, isUpdate) { + var input = $('input', '#'+id); + var options = $(".option", '#'+id); + var filter = function(container, key){ + container.children().each(function(){ + $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : ""); + }); + }; + if(!isUpdate){ + $('.arrow', '#'+id).click(function(){ + options.toggleClass("hide-content"); + }); + input.focus(function(){ + options.removeClass("hide-content"); + }).on("keyup", function(){ + filter(options, input.val()); + }); + } + options.children().each(function(){ + $(this).click(function(){ + input.val($(this).text()); + $('.option', "#iSCSITarget").addClass("hide-content"); + filter(options, ""); + }); + }); +}; + +kimchi.initISCSITargets = function(){ + var loadTargets = function(server, port, callback){ + var isUpdate = $(".option", "#iSCSITarget").children().length > 0; + $(".option", "#iSCSITarget").empty(); + $('input', "#iSCSITarget").val("loading targets..."); + kimchi.getISCSITargets(server, port, function(data){ + if(data.length==0){ + $('input', "#iSCSITarget").val("no targets is got."); + }else{ + for(var i=0; i<data.length; i++){ + var itemNode = $.parseHTML("<div class='item'>"+data[i].target+"</div>"); + $(".option", "#iSCSITarget").append(itemNode); + } + kimchi.storageFilterSelect('iSCSITarget', isUpdate); + $('input', "#iSCSITarget").attr("readonly", false); + $('input', "#iSCSITarget").val(""); + $('input', "#iSCSITarget").trigger("focus"); + } + callback(); + }, function(data){ + $('input', "#iSCSITarget").val("failed to load targets."); + kimchi.message.error(data.responseJSON.reason); + callback(); + }); + }; + var triggerLoadTarget = function(){ + var server = $("#iscsiserverId").val().trim(); + var port = $("#iscsiportId").val().trim(); + if(server!="" && port!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){ + $("#iscsiserverId").attr("disabled", true); + $("#iscsiportId").attr("disabled", true); + loadTargets(server, port, function(){ + $("#iscsiserverId").attr("disabled", false); + $("#iscsiportId").attr("disabled", false); + }); + } + }; + $("#iscsiserverId").change(function(){ + triggerLoadTarget(); + }); + $("#iscsiportId").change(function(){ + triggerLoadTarget(); + }); +}; + kimchi.initStorageAddPage = function() { kimchi.listHostPartitions(function(data) { if (data.length > 0) { @@ -160,6 +232,10 @@ kimchi.initStorageAddPage = function() { $('#iscsiportId').keyup(function(event) { $(this).toggleClass("invalid-field",!/^[0-9]+$/.test($(this).val())); }); + $('#iscsiserverId').keyup(function(event) { + $(this).toggleClass("invalid-field",!kimchi.isServer($(this).val().trim())); + }); + kimchi.initISCSITargets(); };
/* Returns 'true' if all form fields were filled, 'false' if diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl index 1eb2029..ee19ed5 100644 --- a/ui/pages/storagepool-add.html.tmpl +++ b/ui/pages/storagepool-add.html.tmpl @@ -23,7 +23,7 @@ <!DOCTYPE html> <html> <body> - <div class="window storage-window"> + <div class="window storage-window storage-admin"> <header> <h1 class="title">$_("Define a New Storage Pool")</h1> <div class="close">X</div> @@ -119,7 +119,10 @@ <h2>4. $_("Target")</h2> <div class="field"> <p class="text-help">$_("The iSCSI target on iSCSI server")</p> - <input id="iscsiTargetId" type="text" class="text storage-base-input-width"> + <span class="filter-select" id="iSCSITarget"> + <div><input id="iscsiTargetId" type="text" readonly><a class="ui-icon ui-icon-triangle-1-s arrow"></a></div> + <div class="option hide-content"></div> + </span> </div> </section> <section class="form-section">
participants (3)
-
Aline Manera
-
Daniel H Barboza
-
huoyuxin@linux.vnet.ibm.com