-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-34244] Some UX improvements in the New item form. #2324
Changes from all commits
9ed502f
10d8e91
b5bdae3
86710a5
4000892
e05a328
a786377
0cfb306
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
// Initialize all modules by requiring them. Also makes sure they get bundled (see gulpfile.js). | ||
var $ = require('jquery-detached').getJQuery(); | ||
|
||
var getItems = function(){ | ||
var getItems = function() { | ||
var d = $.Deferred(); | ||
$.get('itemCategories?depth=3').done( | ||
function(data){ | ||
d.resolve(data); | ||
} | ||
function(data){ | ||
d.resolve(data); | ||
} | ||
); | ||
return d.promise(); | ||
}; | ||
|
@@ -40,18 +40,6 @@ $.when(getItems()).done(function(data) { | |
return newDesc; | ||
} | ||
|
||
function getItemTypeSelected() { | ||
var item = $('input[type="radio"][name="mode"]:checked', '#createItem').val(); | ||
if (item === "copy") { | ||
return undefined; | ||
} | ||
return item; | ||
} | ||
|
||
function getItemCopyFromSelected() { | ||
return $('input[type="radio"][name="mode"][value="copy"]:checked', '#createItem').val(); | ||
} | ||
|
||
function getCopyFromValue() { | ||
return $('input[type="text"][name="from"]', '#createItem').val(); | ||
} | ||
|
@@ -61,6 +49,14 @@ $.when(getItems()).done(function(data) { | |
return (itemName === '') ? true : false; | ||
} | ||
|
||
function getFieldValidationStatus(fieldId) { | ||
return $('#' + fieldId).data('valid'); | ||
} | ||
|
||
function setFieldValidationStatus(fieldId, status) { | ||
$('#' + fieldId).data('valid', status); | ||
} | ||
|
||
function activateValidationMessage(messageId, context, message) { | ||
if (message !== undefined && message !== '') { | ||
$(messageId, context).html('» ' + message); | ||
|
@@ -82,6 +78,65 @@ $.when(getItems()).done(function(data) { | |
$('.input-help', context).removeClass('input-message-disabled'); | ||
} | ||
|
||
// About Scroll-linked effect: https://developer.mozilla.org/en-US/docs/Mozilla/Performance/Scroll-linked_effects | ||
function doSticky() { | ||
var decorator = $('form .footer .btn-decorator'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🐜 It's a preference (and a commonly used convention) to start jQuery variables with |
||
var pos = decorator.offset(); | ||
var vpH = $(window).height(); | ||
if (pos.top >= vpH) { | ||
decorator.css({position: 'fixed'}); | ||
} | ||
|
||
$(window).scroll(function() { | ||
var footer = $('form .footer'); | ||
var ref1 = decorator.offset().top + decorator.outerHeight(); | ||
var ref2 = footer.offset().top + footer.outerHeight(); | ||
var vpH = $(window).height(); | ||
if (ref2 > vpH + $(window).scrollTop()) { | ||
decorator.css({position: 'fixed'}); | ||
} else if (ref2 - 1 <= ref1) { | ||
decorator.css({position: 'absolute'}); | ||
} | ||
}); | ||
} | ||
|
||
function enableSubmit(status) { | ||
var btn = $('form .footer .btn-decorator button[type=submit]'); | ||
if (status === true) { | ||
if (btn.hasClass('disabled')) { | ||
btn.removeClass('disabled'); | ||
btn.prop('disabled', false); | ||
} | ||
btn.focus(); | ||
} else { | ||
if (!btn.hasClass('disabled')) { | ||
btn.addClass('disabled'); | ||
btn.prop('disabled', true); | ||
} | ||
} | ||
} | ||
|
||
function getFormValidationStatus() { | ||
if (getFieldValidationStatus('name') && (getFieldValidationStatus('items') || getFieldValidationStatus('from'))) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
function cleanItemSelection() { | ||
$('.categories').find('li[role="radio"]').attr("aria-checked", "false"); | ||
$('#createItem').find('input[type="radio"][name="mode"]').removeAttr('checked'); | ||
$('.categories').find('.active').removeClass('active'); | ||
setFieldValidationStatus('items', false); | ||
} | ||
|
||
function cleanCopyFromOption() { | ||
$('#createItem').find('input[type="radio"][value="copy"]').removeAttr('checked'); | ||
$('input[type="text"][name="from"]', '#createItem').val(''); | ||
setFieldValidationStatus('from', false); | ||
} | ||
|
||
|
||
////////////////////////////////// | ||
// Draw functions | ||
|
||
|
@@ -112,18 +167,21 @@ $.when(getItems()).done(function(data) { | |
|
||
function select(e) { | ||
e.preventDefault(); | ||
$('li[role="radio"]').attr("aria-checked", "false"); | ||
$(this).find('input[type="radio"][name="mode"]').removeAttr('checked'); | ||
$(this).parents().find('.active').removeClass('active'); | ||
cleanCopyFromOption(); | ||
cleanItemSelection(); | ||
|
||
$(this).attr("aria-checked", "true"); | ||
$(this).find('input[type="radio"][name="mode"]').prop('checked', true); | ||
$(this).addClass('active'); | ||
|
||
$('input[type="text"][name="from"]', '#createItem').val(''); | ||
cleanValidationMessages('.add-item-copy'); | ||
if (isItemNameEmpty()) { | ||
setFieldValidationStatus('items', true); | ||
if (!getFieldValidationStatus('name')) { | ||
activateValidationMessage('#itemname-required', '.add-item-name'); | ||
$('input[name="name"][type="text"]', '#createItem').focus(); | ||
} else { | ||
if (getFormValidationStatus()) { | ||
enableSubmit(true); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -186,9 +244,16 @@ $.when(getItems()).done(function(data) { | |
} else { | ||
cleanValidationMessages('.add-item-name'); | ||
showInputHelp('.add-item-name'); | ||
setFieldValidationStatus('name', true); | ||
if (getFormValidationStatus()) { | ||
enableSubmit(true); | ||
} | ||
} | ||
}); | ||
} else { | ||
enableSubmit(false); | ||
setFieldValidationStatus('name', false); | ||
cleanValidationMessages('.add-item-name'); | ||
activateValidationMessage('#itemname-required', '.add-item-name'); | ||
} | ||
}); | ||
|
@@ -198,26 +263,42 @@ $.when(getItems()).done(function(data) { | |
if (getCopyFromValue() === '') { | ||
$('#createItem').find('input[type="radio"][value="copy"]').removeAttr('checked'); | ||
} else { | ||
$('.categories').find('li[role="radio"]').attr("aria-checked", "false"); | ||
$('#createItem').find('input[type="radio"][name="mode"]').removeAttr('checked'); | ||
$('.categories').find('.active').removeClass('active'); | ||
cleanItemSelection(); | ||
$('#createItem').find('input[type="radio"][value="copy"]').prop('checked', true); | ||
setFieldValidationStatus('from', true); | ||
if (!getFieldValidationStatus('name')) { | ||
activateValidationMessage('#itemname-required', '.add-item-name'); | ||
setTimeout(function() { | ||
$('input[name="name"][type="text"]', '#createItem').focus(); | ||
}, 400); | ||
} else { | ||
if (getFormValidationStatus()) { | ||
enableSubmit(true); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
// Client-side validation | ||
$("#createItem").submit(function(event) { | ||
if (isItemNameEmpty()) { | ||
activateValidationMessage('#itemname-required', '.add-item-name'); | ||
$('input[name="name"][type="text"]', '#createItem').focus(); | ||
if (!getFormValidationStatus()) { | ||
event.preventDefault(); | ||
} else { | ||
if (getItemTypeSelected() === undefined && getItemCopyFromSelected() === undefined) { | ||
activateValidationMessage('#itemtype-required', '.add-item-name'); | ||
if (!getFieldValidationStatus('name')) { | ||
activateValidationMessage('#itemname-required', '.add-item-name'); | ||
$('input[name="name"][type="text"]', '#createItem').focus(); | ||
event.preventDefault(); | ||
} else { | ||
if (!getFieldValidationStatus('items') && !getFieldValidationStatus('from')) { | ||
activateValidationMessage('#itemtype-required', '.add-item-name'); | ||
$('input[name="name"][type="text"]', '#createItem').focus(); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
// Disable the submit button | ||
enableSubmit(false); | ||
|
||
// Do sticky the form buttons | ||
doSticky(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,14 +23,14 @@ | |
|
||
.btn-decorator { | ||
position: absolute; | ||
bottom: -1px; | ||
left: -1px; | ||
bottom: 0px; | ||
padding: 20px 30px; | ||
width: auto; | ||
border-top-right-radius: 10px; | ||
border: 1px solid #aaccbb; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT: I would prefer to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Me too but we are using the this design in job configuration. I can push another PR to change both. |
||
background: rgba(245, 249, 239, 0.75); | ||
text-align: center; | ||
z-index: 10; | ||
|
||
button[type=submit] { | ||
padding: 5px 20px; | ||
|
@@ -44,6 +44,21 @@ | |
font-size: 12px; | ||
line-height: 27px; | ||
} | ||
|
||
button[type=submit]:hover:not(.disabled), button[type=submit]:focus:not(.disabled) { | ||
background-color: rgb(68, 119, 136); | ||
border-color: rgb(51, 85, 102); | ||
color: rgb(238, 238, 238); | ||
cursor: pointer; | ||
} | ||
|
||
button[type=submit].disabled { | ||
background-color: #ccc; | ||
border-color: #aaa; | ||
color: rgb(140, 140, 140); | ||
cursor: auto; | ||
opacity: 0.75; | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All whitespace modifications or do I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@batmat No, I took advantage this revision of New Item form in order to have the same coding style convention in this file.