[Kimchi-devel] [PATCH V3] Add nfs server and target UI in create storage pool

Yu Xin Huo huoyuxin at linux.vnet.ibm.com
Mon Jan 13 09:16:06 UTC 2014


On 1/10/2014 5:48 PM, zhoumeina wrote:
> v2-v3 Make nfs server inputbox to combobox
>        Edit jquery widgets to fix some small nits in it.
>        change some parameter according to the changes from
>        back end.
> v1-v2 Fix some bug in this patch, make it working and retest
> This patch is working adding a select box in create nfs pool,
> when user don't want to input the server ip or name, he can
> simply select "used the server I have used before" and choose
> a server in a select box, this is more convinent.
>
> Add a new jquery filter-select widget
>
> In order to show server target I did a select box in UI, but sometimes
> maybe the export path number is large. So I made a filter-select
> widget to make user easier to choose the export path he want.
> This is the first jquery widget. And let us make all common widget to
> jquery widget from now on.
>
> Signed-off-by: zhoumeina <zhoumein at linux.vnet.ibm.com>
> ---
>   ui/css/theme-default/button.css          |   12 +++-
>   ui/css/theme-default/popover.css         |    1 +
>   ui/js/src/kimchi.popable.js              |    2 +-
>   ui/js/src/kimchi.storagepool_add_main.js |   26 +++----
>   ui/js/widgets/combobox.js                |  124 ++++++++++++++++++++++++++++++
>   ui/js/widgets/filter-select.js           |   37 +++------
>   ui/js/widgets/select-menu.js             |   37 +++------
>   ui/pages/i18n.html.tmpl                  |    2 +-
>   ui/pages/storagepool-add.html.tmpl       |   32 ++++----
>   9 files changed, 189 insertions(+), 84 deletions(-)
>   create mode 100644 ui/js/widgets/combobox.js
>
> diff --git a/ui/css/theme-default/button.css b/ui/css/theme-default/button.css
> index f99679a..693ed59 100644
> --- a/ui/css/theme-default/button.css
> +++ b/ui/css/theme-default/button.css
> @@ -261,8 +261,16 @@
>       cursor: pointer;
>   }
>
> -.btn-select .text {
> -    padding: 0 10px;
> +.btn-select .input {
> +	border: 0 solid #CCCCCC;
> +	padding: 0 10px;
> +	margin-right: 10px;
> +    font-size: 16px;
> +    height: 30px;
> +    line-height: 30px;
> +    width: 100%;
> +    position: absolute;
> +    background: transparent;
>   }
There are tabs.
>
>   .btn-select .arrow {
> diff --git a/ui/css/theme-default/popover.css b/ui/css/theme-default/popover.css
> index 95eb183..e91ccc0 100644
> --- a/ui/css/theme-default/popover.css
> +++ b/ui/css/theme-default/popover.css
> @@ -31,6 +31,7 @@
>       left: 0;
>       display: none;
>       cursor: default;
> +    width: 100%;
>   }
>
>   .popover:BEFORE {
> diff --git a/ui/js/src/kimchi.popable.js b/ui/js/src/kimchi.popable.js
> index 153d32c..2a843be 100644
> --- a/ui/js/src/kimchi.popable.js
> +++ b/ui/js/src/kimchi.popable.js
> @@ -25,7 +25,7 @@ kimchi.popable = function() {
>       $(document).on("click", ".popable", function(e) {
>           var isOpen = $(this).hasClass('open');
>           $(".popable").removeClass('open');
> -        if (!isOpen) {
> +        if (!isOpen && $(this).find('ul').html() !== '') {
>               $(this).addClass('open');
>           }
>
> diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
> index 134d13f..4192649 100644
> --- a/ui/js/src/kimchi.storagepool_add_main.js
> +++ b/ui/js/src/kimchi.storagepool_add_main.js
> @@ -54,8 +54,8 @@ kimchi.initStorageAddPage = function() {
>               });
>               $('.host-partition').html(listHtml);
>           }
> -        $('#storagePool-list').selectMenu();
> -        $('#storagePool-list').selectMenu("setData", options);
> +        $('#poolTypeId').selectMenu();
> +        $('#poolTypeId').selectMenu("setData", options);
options should be passed in when constructor is called
>           kimchi.getStorageServers('netfs', function(data) {
>               var serverContent = [];
>               serverContent.push({
> @@ -65,14 +65,14 @@ kimchi.initStorageAddPage = function() {
>               if (data.length > 0) {
>                   $.each(data, function(index, value) {
>                       serverContent.push({
> -                        label : value,
> -                        value : value
> +                        label : value.addr,
> +                        value : value.addr
>                       });
>                   });
>               }
> -            $('#nfs-server-used').selectMenu();
> -            $('#nfs-server-used').selectMenu("setData", serverContent);
> -            $('#nfs-server-target').filterselect();
> +            $('#serverComboboxId').combobox();
> +            $('#serverComboboxId').combobox("setData", serverContent);
options should be passed in when constructor is called
> +            $('#targetFilterSelectId').filterselect();
>               $('input[name=nfsServerType]').change(function() {
>                   if ($(this).val() === 'input') {
>                       $('#nfsServerInputDiv').removeClass('tmpl-html');
> @@ -82,17 +82,13 @@ kimchi.initStorageAddPage = function() {
>                       $('#nfsServerChooseDiv').removeClass('tmpl-html');
>                   }
>               });
> -            $('#nfsServerSelect').change(function() {
> -                $('#nfsserverId').val($(this).val());
> -                $('#nfsserverId').trigger("keydown");
> -            });
> -            $('#nfsserverId').on("keydown",function() {
> +            $('#nfsserverId').on("change",function() {
>                   if ($(this).val() !== '' && kimchi.isServer($(this).val())) {
>                       $('#nfspathId').removeAttr('disabled');
>                   } else {
>                       $('#nfspathId').attr('disabled','disabled');
change this to be $('#nfspathId').attr('disabled',true);

>                   }
> -                $('#nfs-server-target').filterselect('clear');
> +                $('#targetFilterSelectId').filterselect('clear');
>               });
>               $('#nfspathId').focus(function() {
>                   var targetContent = [];
> @@ -110,7 +106,7 @@ kimchi.initStorageAddPage = function() {
>                               value : ''
>                           });
>                       }
> -                    $('#nfs-server-target').filterselect("setData", targetContent);
> +                    $('#targetFilterSelectId').filterselect("setData", targetContent);
>                   },function() {
>                       targetContent.push({
>                           label : i18n['msg.no.result'],
> @@ -120,7 +116,7 @@ kimchi.initStorageAddPage = function() {
>                   });
>               });
>           });
> -        $('#poolType').change(function() {
> +        $('#poolTypeInputId').change(function() {
>               if ($(this).val() === 'dir') {
>                   $('.path-section').removeClass('tmpl-html');
>                   $('.logical-section').addClass('tmpl-html');
> diff --git a/ui/js/widgets/combobox.js b/ui/js/widgets/combobox.js
> new file mode 100644
> index 0000000..dfa6566
> --- /dev/null
> +++ b/ui/js/widgets/combobox.js
> @@ -0,0 +1,124 @@
> +/*
> + * Project Kimchi
> + *
> + * Copyright IBM, Corp. 2013
> + *
> + * Authors:
> + *  zhoumeina <zhoumein at linux.vnet.ibm.com>
> + *
> + * Licensed under the Apache License, Version 2.0 (the 'License');
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an 'AS IS' BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +(function($) {
> +    $.widget('kimchi.combobox', {
> +        _create : function() {
> +            this.selectDiv = this.element;
> +            this.listControl = this.selectDiv.find('ul').first();
> +            this.listControl.html('');
> +            this.target = this.selectDiv.find('input').first();
> +            this.selectDiv.addClass('btn-select dropdown popable');
> +            this.target.addClass('input');
> +            this.listControl.addClass('select-list');
> +            this.listControl.parent().addClass('popover');
> +        },
> +
> +        setData : function(options) {
> +            this.listControl.html('');
> +            var that = this;
> +            var value = this.target.val();
> +            var selectedClass = 'active';
> +            var itemTag = 'li';
> +
> +            that.listControl.on('click', itemTag, function(e) {
> +                that.listControl.children().removeClass(selectedClass);
> +                that.listControl.addClass(selectedClass);
> +                that.target.text($(this).text());
> +                var oldValue = that.target.val();
> +                var newValue = $(this).data('value');
> +                that.target.val(newValue);
> +                if (oldValue !== newValue) {
> +                    that.target.change();
> +                }
> +            });
> +
> +            that.selectDiv.click(function(e) {
> +                that.listControl.html('');
> +                var items = that._dataList(options);
> +                $.each(items, function(index, item) {
> +                    that.listControl.append(item);
> +                })
> +            });
> +
> +            that.target.keyup(function(event) {
> +                that.listControl.html('');
> +                var items = that._dataList(options);
> +                var temp = 0;
> +                $.each(items, function(index, item) {
> +                    if (item.html().indexOf(that.target.val()) >= 0) {
> +                        that.listControl.append(item);
> +                        temp++;
> +                    }
> +                });
> +                if (that.listControl.html() === '') {
> +                    that.listControl.html(i18n['msg.no.mapping.result']);
> +                }
> +                if (temp > 0) {
> +                    that._open();
> +                }
> +            });
> +        },
> +
> +        _dataList : function(options) {
> +            var item;
> +            var itemTag = 'li';
> +            var selectedClass = 'active';
> +            var items = [];
> +            var that = this;
> +            $.each(options, function(index, option) {
> +                item = $('<' + itemTag + '></' + itemTag + '>');
> +                item.text(option.label);
> +                item.data('value', option.value);
> +                if (option.value === that.target.val()) {
> +                    item.addClass(selectedClass);
> +                }
> +                items.push(item);
> +            });
> +            return items;
> +        },
> +
> +        clear : function() {
> +            this.target.val("");
> +        },
> +
> +        _open : function() {
> +            var isOpen = this.selectDiv.hasClass('open');
> +            if (!isOpen) {
> +                this.selectDiv.addClass('open');
> +            }
> +        },
add value() and value(value) method to get and set value of the widget
> +
> +        _close : function() {
> +            var isOpen = this.selectDiv.hasClass('open');
> +            if (isOpen) {
> +                this.selectDiv.removeClass('open');
> +            }
> +        },
> +
> +        destroy : function() {
> +            this.selectDiv.removeClass('btn-select dropdown popable');
> +            this.target.removeClass('input');
> +            this.listControl.removeClass('select-list');
> +            this.listControl.parent().removeClass('popover');
> +            $.Widget.prototype.destroy.call(this);
> +        }
> +    });
> +}(jQuery));
> \ No newline at end of file
> diff --git a/ui/js/widgets/filter-select.js b/ui/js/widgets/filter-select.js
> index 02fe5d9..0686aa2 100644
> --- a/ui/js/widgets/filter-select.js
> +++ b/ui/js/widgets/filter-select.js
> @@ -20,28 +20,19 @@
>    */
>   (function($) {
>       $.widget('kimchi.filterselect', {
> -        options : {
> -            key : 0,
> -            value : 0
> -        },
> -
>           _create : function() {
> -            this.listControl = this.element;
> -            this.element.html('');
> -            var targetId = this.listControl.data('target');
> -            var labelId = this.listControl.data('label');
> -            this.target = $('#' + targetId);
> -            this.label = $('#' + labelId);
> -            this.selectDiv = this.listControl.parent().parent();
> +            this.selectDiv = this.element;
> +            this.listControl = this.selectDiv.find('ul').first();
> +            this.listControl.html('');
> +            this.target = this.selectDiv.find('input').first();
>               this.selectDiv.addClass('btn-select dropdown popable');
> +            this.target.addClass('input');
> +            this.listControl.addClass('select-list');
>               this.listControl.parent().addClass('popover');
>           },
>
> -        _setOption : function(key, value) {
> -        },
> -
>           setData : function(options) {
> -            this.element.html('');
> +            this.listControl.html('');
>               var that = this;
>               var value = this.target.val();
>               var selectedClass = 'active';
> @@ -65,13 +56,6 @@
>                   $.each(items, function(index, item) {
>                       that.listControl.append(item);
>                   })
> -                var isOpen = that.selectDiv.hasClass('open');
> -                that.selectDiv.removeClass('open');
> -                if (!isOpen && items.length > 0) {
> -                    that.selectDiv.addClass('open');
> -                }
> -                e.preventDefault();
> -                e.stopPropagation();
>               });
>
>               that.target.keyup(function(event) {
> @@ -85,7 +69,7 @@
>                       }
>                   });
>                   if (that.listControl.html() === '') {
> -                    that.listControl.html(i18n['msg.storagepool.unvalid.path']);
> +                    that.listControl.html(i18n['msg.no.mapping.result']);
>                   }
>                   if (temp > 0) {
>                       that._open();
> @@ -130,7 +114,10 @@
>           },
add value() and value(value) method to get and set value of the widget
>
>           destroy : function() {
> -            // call the base destroy function
> +            this.selectDiv.removeClass('btn-select dropdown popable');
> +            this.target.removeClass('input');
> +            this.listControl.removeClass('select-list');
> +            this.listControl.parent().removeClass('popover')
>               $.Widget.prototype.destroy.call(this);
>           }
>       });
> diff --git a/ui/js/widgets/select-menu.js b/ui/js/widgets/select-menu.js
> index 454fe3c..c2ced7e 100644
> --- a/ui/js/widgets/select-menu.js
> +++ b/ui/js/widgets/select-menu.js
> @@ -20,26 +20,20 @@
>    */
>   (function($) {
>       $.widget('kimchi.selectMenu', {
> -        options: {
> -               key: 0,
> -               value: 0
> -              },
>
>           _create : function() {
> -            this.listControl = this.element;
> -            this.element.html('');
> -            var targetId = this.listControl.data('target');
> -            var labelId = this.listControl.data('label');
> -            this.target = $('#' + targetId);
> -            this.label = $('#' + labelId);
> -            this.selectDiv = this.listControl.parent().parent();
> +            this.selectDiv = this.element;
> +            this.listControl = this.selectDiv.find('ul').first();
> +            this.listControl.html('');
> +            this.target = this.selectDiv.find('input').first();
> +            this.label = this.selectDiv.find('span').first();
>               this.selectDiv.addClass('btn-select dropdown popable');
> +            this.target.addClass('input');
> +            this.label.addClass('input');
> +            this.listControl.addClass('select-list');
>               this.listControl.parent().addClass('popover');
> -            var that = this;
>           },
>
> -        _setOption : function(key,value) {},
> -
>           setData : function (options) {
>               var that = this;
>               var value = this.target.val();
> @@ -67,19 +61,14 @@
>                   }
>               });
>
> -            that.selectDiv.click(function(e) {
> -                var isOpen = that.selectDiv.hasClass('open');
> -                that.selectDiv.removeClass('open');
> -                if (!isOpen) {
> -                    that.selectDiv.addClass('open');
> -                }
> -                e.preventDefault();
> -                e.stopPropagation();
> -            });
>           },
add value() and value(value) method to get and set value of the widget
>
>           destroy : function() {
> -            // call the base destroy function
> +            this.selectDiv.removeClass('btn-select dropdown popable');
> +            this.target.removeClass('input');
> +            this.label.removeClass('input');
> +            this.listControl.removeClass('select-list');
> +            this.listControl.parent().removeClass('popover');
>               $.Widget.prototype.destroy.call(this);
>           }
>       });
> diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
> index 3047fdc..9727eba 100644
> --- a/ui/pages/i18n.html.tmpl
> +++ b/ui/pages/i18n.html.tmpl
> @@ -124,7 +124,7 @@ var i18n = {
>       'msg.pool.edit.server.blank':"$_("Server name can not be blank.")",
>       'msg.validate.pool.edit.server':"$_("This is not a valid Server Name or IP. please, modify it.")",
>       'select_default': "$_("Please choose")",
> -    'msg.storagepool.unvalid.path': "$_("This is not a valid path")",
> +    'msg.no.mapping.result': "$_("No such data exsit.")",
>       'msg.no.result' : "$_("No valid result")"
>   };
>   </script>
> diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
> index 4276bf0..00f21d5 100644
> --- a/ui/pages/storagepool-add.html.tmpl
> +++ b/ui/pages/storagepool-add.html.tmpl
> @@ -47,11 +47,11 @@
>                   <section class="form-section">
>                       <h2>2. $_("Storage Pool Type")</h2>
>                       <div class="storage-type-wrapper-controls">
> -                        <div>
> -                            <input id="poolType" name="type" type="hidden" value="dir"/>
> -                            <span class="text" id="pool-type-label"></span><span class="arrow"></span>
> -                            <div style="width: 100%">
> -                                <ul class="select-list" id="storagePool-list" data-target="poolType" data-label="pool-type-label">
> +                        <div id="poolTypeId">
> +                            <input id="poolTypeInputId" name="type" type="hidden" value="dir"/>
> +                            <span id="pool-type-label"></span><span class="arrow"></span>
> +                            <div>
> +                                <ul id="storagePool-list">
>                                   </ul>
>                               </div>
>                           </div>
> @@ -73,14 +73,14 @@
>                   <div class="nfs-section tmpl-html">
>                       <section class="form-section">
>                           <h2>3. $_("NFS server IP")</h2>
For label, change it to be "NFS Server IP"
> -                        <div class="field">
> +                        <div class="field" style="overflow:visible">
move style="overflow:visible"to css.
>                               <p class="text-help">
> -                                $_("NFS server IP or hostname. It should not be empty.")</p>
> -                            <div style="width: 285px">
> +                                $_("NFS server IP or hostname. It can be input or choose from history.")</p>
> +                            <div id="serverComboboxId" style="width: 285px">
move style="width: 285px" to css.
>                                   <input id="nfsserverId"/>
> -                                <span class="text" id="nfs-server-label"></span><span class="arrow"></span>
> -                                <div style="width: 100%">
> -                                    <ul class="select-list" id="nfs-server-used" data-target="nfsserverId" data-label="nfs-server-label">
> +                                <span class="arrow"></span>
> +                                <div>
> +                                    <ul id="nfs-server-used">
>                                       </ul>
>                                   </div>
>                               </div>
> @@ -90,11 +90,11 @@
>                           <h2>4. $_("NFS Path")</h2>
>                           <div class="field" style="overflow:visible">
>                               <p class="text-help">$_("The nfs exported path on nfs server")</p>
> -                            <div style="width: 285px">
> -	                            <input id="nfspathId" class="text" disabled="disabled" style="width:293px;"/>
> -		                        <span class="text" id="nfs-target-label"></span><span class="arrow"></span>
> -		                        <div style="width: 100%">
> -		                            <ul class="select-list" id="nfs-server-target" data-target="nfspathId" data-label="nfs-target-label">
> +                            <div id="targetFilterSelectId" style="width: 285px">
move  style="width: 285px"  to css.
> +	                            <input id="nfspathId" class="input" disabled="disabled"/>
'disabled' is of boolean type, change it to be <input id="nfspathId" 
class="input" disabled/>
http://www.w3schools.com/tags/att_input_disabled.asp
> +	                            <span class="arrow"></span>
> +		                        <div>
> +		                            <ul id="nfs-server-target">
>   		                            </ul>
>   		                        </div>
>   		                    </div>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ovirt.org/pipermail/kimchi-devel/attachments/20140113/d7a1d5cf/attachment.html>


More information about the Kimchi-devel mailing list