[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