[Kimchi-devel] [PATCH] Enable buttons only when all required data is entered

Sheldon shaohef at linux.vnet.ibm.com
Thu May 15 05:59:16 UTC 2014


need improve

After I apply this patch.

my browser remember the user name and password.
But I can no login.
I can login after I input any character and then delete it.

The storage add page is right.

Your method is right for storage page.



On 05/14/2014 04:44 AM, Crístian Viana wrote:
> Most forms contain fields that must be filled before they are submitted.
> Some of them submit the missing data and display an error message when
> something goes wrong, and some of them do not allow the user to submit
> them if some data is missing.
>
> Make the forms behavior consistent by enabling their buttons only
> when the required data is entered.
> Internally, the page tags all required fields with the class "required"
> and whenever any of their values change, they are checke. If any
> required field is empty, the submit button becomses disabled; otherwise,
> it becomes enabled.
>
> Fix GitHub issue #317 ("Inconsistent button status when adding or
> creating new resources").
>
> Signed-off-by: Crístian Viana <vianac at linux.vnet.ibm.com>
> ---
>   ui/css/theme-default/login-window.css    |  4 --
>   ui/js/src/kimchi.guest_edit_main.js      | 15 +++++++
>   ui/js/src/kimchi.login_window.js         | 36 +++++++--------
>   ui/js/src/kimchi.storagepool_add_main.js | 75 +++++++++++++++++++++++---------
>   ui/js/src/kimchi.template_edit_main.js   | 20 +++++++++
>   ui/pages/guest-edit.html.tmpl            |  6 +--
>   ui/pages/i18n.html.tmpl                  |  6 ---
>   ui/pages/login-window.html.tmpl          |  8 ++--
>   ui/pages/storagepool-add.html.tmpl       |  6 +--
>   ui/pages/template-edit.html.tmpl         |  8 ++--
>   10 files changed, 117 insertions(+), 67 deletions(-)
>
> diff --git a/ui/css/theme-default/login-window.css b/ui/css/theme-default/login-window.css
> index 8a21090..d021be6 100644
> --- a/ui/css/theme-default/login-window.css
> +++ b/ui/css/theme-default/login-window.css
> @@ -62,10 +62,6 @@
>       width: 290px;
>   }
>   
> -#login-window .login-panel .msg-required {
> -    color: red;
> -}
> -
>   #login-window .login-panel button {
>       font-size: 18px;
>       height: 40px;
> diff --git a/ui/js/src/kimchi.guest_edit_main.js b/ui/js/src/kimchi.guest_edit_main.js
> index 0236e2d..bb4ee51 100644
> --- a/ui/js/src/kimchi.guest_edit_main.js
> +++ b/ui/js/src/kimchi.guest_edit_main.js
> @@ -202,6 +202,21 @@ kimchi.guest_edit_main = function() {
>   
>       kimchi.retrieveVM(kimchi.selectedGuest, initContent);
>   
> +    var updateSubmitButtonStatus = function() {
> +        var valid = true;
> +        guestEditForm.find('input.required').each(function(index, field) {
> +            if (field.value === '') {
> +                valid = false;
> +                return;
> +            }
> +        });
> +
> +        saveButton.prop('disabled', !valid);
> +    };
> +
> +    guestEditForm.find('input.required').on('input propertychange',
> +                                            updateSubmitButtonStatus);
> +
>       var submitForm = function(event) {
>           $(saveButton).prop('disabled', true);
>           var data=$('#form-guest-edit-general').serializeObject();
> diff --git a/ui/js/src/kimchi.login_window.js b/ui/js/src/kimchi.login_window.js
> index 9c06a50..52394a5 100644
> --- a/ui/js/src/kimchi.login_window.js
> +++ b/ui/js/src/kimchi.login_window.js
> @@ -30,26 +30,25 @@ kimchi.login_main = function() {
>           $(opt).prop('selected', selectedLanguage === k);
>       }
>   
> +    var updateSubmitButtonStatus = function() {
> +        var valid = true;
> +        $('#form-login').find('input.required').each(function(index, field) {
> +            if (field.value === '') {
> +                valid = false;
> +                return;
> +            }
> +        });
> +
> +        $('#btn-login').prop('disabled', !valid);
> +    }
> +
> +    $('#form-login').find('input.required').on('input propertychange',
> +                                               updateSubmitButtonStatus);
> +
>       $('#language').on('change', function() {
>           kimchi.topic('languageChanged').publish($(this).val());
>       });
>   
> -    var validateNonEmpty = function(idsArray) {
> -        for(var i = 0; i < idsArray.length; i++) {
> -            var id = idsArray[i];
> -            if (!$('#' + id).val()) {
> -                $('#' + id + '-msg').text(i18n['KCHAUTH6002E']);
> -                placeCursor(id);
> -                return false;
> -            }
> -            else {
> -                $('#' + id + '-msg').empty();
> -            }
> -        }
> -
> -        return true;
> -    };
> -
>       var placeCursor = function(id) {
>           if (id && $('#' + id).size() > 0) {
>               $('#' + id).focus();
> @@ -66,11 +65,6 @@ kimchi.login_main = function() {
>       };
>   
>       var login = function(event) {
> -
> -        if (!validateNonEmpty(['username', 'password'])) {
> -            return false;
> -        }
> -
>           $('#btn-login').text(i18n['KCHAUTH6002M']).prop('disabled', true);
>   
>           var userName = $('#username').val();
> diff --git a/ui/js/src/kimchi.storagepool_add_main.js b/ui/js/src/kimchi.storagepool_add_main.js
> index 86dbe7f..5356985 100644
> --- a/ui/js/src/kimchi.storagepool_add_main.js
> +++ b/ui/js/src/kimchi.storagepool_add_main.js
> @@ -122,6 +122,18 @@ kimchi.initStorageAddPage = function() {
>           });
>       });
>   
> +    var updateSubmitButtonStatus = function() {
> +        var valid = true;
> +        $('#form-pool-add').find('input.required').each(function(index, field) {
> +            if (field.value === '') {
> +                valid = false;
> +                return;
> +            }
> +        });
> +
> +        $('#pool-doAdd').prop('disabled', !valid);
> +    };
> +
>       $('#poolTypeInputId').change(function() {
>           var poolObject = {'dir': ".path-section", 'netfs': '.nfs-section',
>                             'iscsi': '.iscsi-section', 'scsi': '.scsi-section',
> @@ -134,7 +146,49 @@ kimchi.initStorageAddPage = function() {
>                   $(value).addClass('tmpl-html');
>               }
>           });
> +
> +        switch (selectType) {
> +            case 'dir':
> +                $('#pathId').addClass('required');
> +
> +                $('#nfsserverId').removeClass('required');
> +                $('#nfspathId').removeClass('required');
> +                $('#iscsiserverId').removeClass('required');
> +                break;
> +            case 'netfs':
> +                $('#nfsserverId').addClass('required');
> +                $('#nfspathId').addClass('required');
> +
> +                $('#pathId').removeClass('required');
> +                $('#iscsiserverId').removeClass('required');
> +                break;
> +            case 'iscsi':
> +                $('#iscsiserverId').addClass('required');
> +
> +                $('#pathId').removeClass('required');
> +                $('#nfsserverId').removeClass('required');
> +                $('#nfspathId').removeClass('required');
> +                break;
> +            case 'scsi':
> +                $('#pathId').removeClass('required');
> +                $('#nfsserverId').removeClass('required');
> +                $('#nfspathId').removeClass('required');
> +                $('#iscsiserverId').removeClass('required');
> +                break;
> +            case 'logical':
> +                $('#pathId').removeClass('required');
> +                $('#nfsserverId').removeClass('required');
> +                $('#nfspathId').removeClass('required');
> +                $('#iscsiserverId').removeClass('required');
> +                break;
> +        }
> +
> +        updateSubmitButtonStatus();
>       });
> +
> +    $('#form-pool-add').find('input').on('input propertychange',
> +                                         updateSubmitButtonStatus);
> +
>       $('#authId').click(function() {
>           if ($(this).prop("checked")) {
>               $('.authenticationfield').removeClass('tmpl-html');
> @@ -150,10 +204,6 @@ kimchi.initStorageAddPage = function() {
>   kimchi.validateForm = function() {
>       var name = $('#poolId').val();
>       var poolType = $("#poolTypeInputId").val();
> -    if ('' === name) {
> -        kimchi.message.error.code('KCHPOOL6001E');
> -        return false;
> -    }
>       if (name.indexOf("/")!=-1) {
>           kimchi.message.error.code('KCHPOOL6004E');
>           return false;
> @@ -173,10 +223,6 @@ kimchi.validateForm = function() {
>   
>   kimchi.validateDirForm = function () {
>       var path = $('#pathId').val();
> -    if ('' === path) {
> -        kimchi.message.error.code('KCHPOOL6002E');
> -        return false;
> -    }
>       if (!/(^\/.*)$/.test(path)) {
>           kimchi.message.error.code('KCHAPI6003E');
>           return false;
> @@ -190,10 +236,6 @@ kimchi.validateNfsForm = function () {
>       if (!kimchi.validateServer(nfsserver)) {
>           return false;
>       }
> -    if ('' === nfspath) {
> -        kimchi.message.error.code('KCHPOOL6003E');
> -        return false;
> -    }
>       if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
>           kimchi.message.error.code('KCHPOOL6005E');
>           return false;
> @@ -203,22 +245,13 @@ kimchi.validateNfsForm = function () {
>   
>   kimchi.validateIscsiForm = function() {
>       var iscsiServer = $('#iscsiserverId').val();
> -    var iscsiTarget = $('#iscsiTargetId').val();
>       if (!kimchi.validateServer(iscsiServer)) {
>           return false;
>       }
> -    if ('' === iscsiTarget) {
> -        kimchi.message.error.code('KCHPOOL6007E');
> -        return false;
> -    }
>       return true;
>   };
>   
>   kimchi.validateServer = function(serverField) {
> -    if ('' === serverField) {
> -        kimchi.message.error.code('KCHPOOL6008E');
> -        return false;
> -    }
>       if(!kimchi.isServer(serverField)) {
>           kimchi.message.error.code('KCHPOOL6009E');
>           return false;
> diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
> index f0f4718..e552bf9 100644
> --- a/ui/js/src/kimchi.template_edit_main.js
> +++ b/ui/js/src/kimchi.template_edit_main.js
> @@ -104,6 +104,26 @@ kimchi.template_edit_main = function() {
>           });
>       });
>   
> +    var updateSubmitButtonStatus = function() {
> +        var valid = true;
> +        templateEditForm.find('input.required').each(function(index, field) {
> +            if (field.value === '') {
> +                valid = false;
> +                return;
> +            }
> +        });
> +
> +        if (valid) {
> +            $('#tmpl-edit-button-save').removeAttr('disabled');
> +        }
> +        else {
> +            $('#tmpl-edit-button-save').attr('disabled', 'disabled');
> +        }
> +    };
> +
> +    templateEditForm.find('input.required').on('input propertychange',
> +                                                updateSubmitButtonStatus);
> +
>       $('#tmpl-edit-button-cancel').on('click', function() {
>           kimchi.window.close();
>       });
> diff --git a/ui/pages/guest-edit.html.tmpl b/ui/pages/guest-edit.html.tmpl
> index 96d907e..d35ad7a 100644
> --- a/ui/pages/guest-edit.html.tmpl
> +++ b/ui/pages/guest-edit.html.tmpl
> @@ -49,7 +49,7 @@
>                           </div>
>                           <div class="guest-edit-wrapper-controls">
>                               <input id="guest-edit-id-textbox"
> -                                name="name" type="text" />
> +                                name="name" type="text" class="required" />
>                           </div>
>                       </div>
>                       <div>
> @@ -62,7 +62,7 @@
>                               <input
>                                   id="guest-edit-cores-textbox"
>                                   name="cpus"
> -                                type="text" />
> +                                type="text" class="required" />
>                           </div>
>                       </div>
>                       <div>
> @@ -74,7 +74,7 @@
>                           <div class="guest-edit-wrapper-controls">
>                               <input id="guest-edit-memory-textbox"
>                                   name="memory"
> -                                type="text" />
> +                                type="text" class="required" />
>                           </div>
>                       </div>
>                       <div>
> diff --git a/ui/pages/i18n.html.tmpl b/ui/pages/i18n.html.tmpl
> index 98da828..814825f 100644
> --- a/ui/pages/i18n.html.tmpl
> +++ b/ui/pages/i18n.html.tmpl
> @@ -33,7 +33,6 @@
>   <script>
>   var i18n = {
>       'KCHAUTH6001E': "$_("The username or password you entered is incorrect. Please try again.")",
> -    'KCHAUTH6002E': "$_("This field is required.")",
>   
>       'KCHAUTH6001M': "$_("Log in")",
>       'KCHAUTH6002M': "$_("Logging in...")",
> @@ -158,14 +157,9 @@ var i18n = {
>       'KCHPOOL6004M': "$_("SCSI Fibre Channel")",
>       'KCHPOOL6005M': "$_("No SCSI adapters found.")",
>   
> -    'KCHPOOL6001E': "$_("The storage pool name can not be blank.")",
> -    'KCHPOOL6002E': "$_("The storage pool path can not be blank.")",
> -    'KCHPOOL6003E': "$_("NFS server mount path can not be blank.")",
>       'KCHPOOL6004E': "$_("Invalid storage pool name. It should not contain '/'.")",
>       'KCHPOOL6005E': "$_("Invalid NFS mount path.")",
>       'KCHPOOL6006E': "$_("No logical device selected.")",
> -    'KCHPOOL6007E': "$_("The iSCSI target can not be blank.")",
> -    'KCHPOOL6008E': "$_("Server name can not be blank.")",
>       'KCHPOOL6009E': "$_("This is not a valid Server Name or IP. please, modify it.")",
>       'KCHPOOL6010M': "$_("Looking for available partitions ...")",
>       'KCHPOOL6011M': "$_("No available partitions found.")",
> diff --git a/ui/pages/login-window.html.tmpl b/ui/pages/login-window.html.tmpl
> index 3e451c4..1cd9e83 100644
> --- a/ui/pages/login-window.html.tmpl
> +++ b/ui/pages/login-window.html.tmpl
> @@ -34,15 +34,13 @@
>     <div class="content login-panel">
>       <form id="form-login" action="/login" method="POST">
>         <div class="row">
> -        <input type="text" id="username" name="username" required="required" placeholder="$_("User Name")" />
> -        <div id="username-msg" class="msg-required"></div>
> +        <input type="text" id="username" name="username" class="required" placeholder="$_("User Name")" />
>         </div>
>         <div class="row">
> -        <input type="password" id="password" name="password" required="required" placeholder="$_("Password")" />
> -        <div id="password-msg" class="msg-required"></div>
> +        <input type="password" id="password" name="password" class="required" placeholder="$_("Password")" />
>         </div>
>         <div class="row">
> -        <button id="btn-login" class="btn-normal">$_("Log in")</button>
> +        <button id="btn-login" class="btn-normal" disabled="true">$_("Log in")</button>
>         </div>
>       </form>
>     </div>
> diff --git a/ui/pages/storagepool-add.html.tmpl b/ui/pages/storagepool-add.html.tmpl
> index 977db66..6ce1343 100644
> --- a/ui/pages/storagepool-add.html.tmpl
> +++ b/ui/pages/storagepool-add.html.tmpl
> @@ -36,7 +36,7 @@
>                           <p class="text-help">
>                               $_("The name used to identify the storage pools, and it should not be empty.")
>                           </p>
> -                        <input id="poolId" required="required" type="text" class="text storage-base-input-width" name="name">
> +                        <input id="poolId" type="text" class="text storage-base-input-width required" name="name">
>                       </div>
>                   </section>
>                   <section class="form-section">
> @@ -60,7 +60,7 @@
>                                   $_("The path of the Storage Pool. Each Storage Pool must have a unique path.")</p>
>                               <p class="text-help">
>                                   $_("Kimchi will try to create the directory when it does not already exist in your system.")</p>
> -                            <input id="pathId" type="text" class="text storage-base-input-width">
> +                            <input id="pathId" type="text" class="text storage-base-input-width required">
>                           </div>
>                           <div class="clear"></div>
>                       </section>
> @@ -152,7 +152,7 @@
>           </div>
>           <footer>
>               <div class="btn-group">
> -                <button id="pool-doAdd" class="btn-normal">
> +                <button id="pool-doAdd" class="btn-normal" disabled="disabled">
>                       <span class="text">$_("Create")</span>
>                   </button>
>               </div>
> diff --git a/ui/pages/template-edit.html.tmpl b/ui/pages/template-edit.html.tmpl
> index 434d938..46b7058 100644
> --- a/ui/pages/template-edit.html.tmpl
> +++ b/ui/pages/template-edit.html.tmpl
> @@ -36,7 +36,7 @@
>                           <label for="template-edit-id-textbox">$_("Name")</label>
>                       </div>
>                       <div class="template-edit-wrapper-controls">
> -                        <input id="template-edit-id-textbox" name="name" type="text" />
> +                        <input id="template-edit-id-textbox" name="name" type="text" class="required" />
>                       </div>
>                   </div>
>                   <div>
> @@ -60,7 +60,7 @@
>                           <label for="template-edit-cpu-textbox">$_("CPU Number")</label>
>                       </div>
>                       <div class="template-edit-wrapper-controls">
> -                        <input id="template-edit-cpu-textbox" name="cpus" type="text" />
> +                        <input id="template-edit-cpu-textbox" name="cpus" type="text" class="required" />
>                       </div>
>                   </div>
>                   <div>
> @@ -68,7 +68,7 @@
>                           <label for="template-edit-memory-textbox">$_("Memory")</label>
>                       </div>
>                       <div class="template-edit-wrapper-controls">
> -                        <input id="template-edit-memory-textbox" name="memory" type="text" />
> +                        <input id="template-edit-memory-textbox" name="memory" type="text" class="required" />
>                       </div>
>                   </div>
>                   <div>
> @@ -76,7 +76,7 @@
>                           <label for="template-edit-disk-textbox">$_("Disk (GB)")</label>
>                       </div>
>                       <div class="template-edit-wrapper-controls">
> -                        <input id="template-edit-disk-textbox" name="disks" type="text" />
> +                        <input id="template-edit-disk-textbox" name="disks" type="text" class="required" />
>                       </div>
>                   </div>
>               </fieldset>


-- 
Thanks and best regards!

Sheldon Feng(冯少合)<shaohef at linux.vnet.ibm.com>
IBM Linux Technology Center




More information about the Kimchi-devel mailing list