mirror of https://github.com/apache/cloudstack.git
UI: Implement tagging widget
Implement a special form on input text field, for handling tag-based fields. This will tags as a set of list items, which can be removed and added to. This is for any comma-delimited field. Currently, this is only supported on detail view widgets, by adding 'isTag: true' as a new attribute for any tag field. Tags are modified when clicking the 'edit' action.
This commit is contained in:
parent
ba7d0ba4f9
commit
c69da45217
|
|
@ -8951,6 +8951,89 @@ div.panel.ui-dialog div.list-view div.fixed-header {
|
|||
background: #DFE1E3;
|
||||
}
|
||||
|
||||
/*Tagger*/
|
||||
.tagger {
|
||||
overflow: hidden;
|
||||
width: 95%;
|
||||
background: #000000;
|
||||
}
|
||||
|
||||
.tagger input {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
border: 1px solid #B2B2B2;
|
||||
background: #FFFFFF;
|
||||
height: 15px;
|
||||
padding: 2px;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.tagger ul {
|
||||
height: 19px;
|
||||
border: 1px solid #B2B2B2;
|
||||
border-right: none;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 13px;
|
||||
background: #FFFFFF;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tagger ul li {
|
||||
background: #DFDFDF 0px 4px;
|
||||
height: 15px;
|
||||
padding: 0px 18px 0 7px;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin-right: 2px;
|
||||
/*+border-radius:4px;*/
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
/*+placement:shift 0px 2px;*/
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.tagger ul li span {
|
||||
width: auto !important;
|
||||
top: 2px !important;
|
||||
left: 5px !important;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.tagger ul li span.label {
|
||||
display: none;
|
||||
/*+placement:shift 12px 2px;*/
|
||||
position: relative !important;
|
||||
left: 12px !important;
|
||||
top: 2px !important;
|
||||
}
|
||||
|
||||
.tagger ul li span.remove {
|
||||
width: 15px !important;
|
||||
overflow: hidden !important;
|
||||
height: 11px !important;
|
||||
background: #DFDFDF url(../images/sprites.png) no-repeat -595px -1183px;
|
||||
display: block;
|
||||
top: 0px !important;
|
||||
left: -3px !important;
|
||||
text-indent: 4px;
|
||||
padding: 4px 0px 0px 8px;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
position: absolute !important;
|
||||
color: #5B5B5B;
|
||||
}
|
||||
|
||||
.tagger ul li span.remove:hover {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/*VPC / vApps*/
|
||||
.vpc-chart {
|
||||
width: 100%;
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 175 KiB |
|
|
@ -1614,6 +1614,7 @@
|
|||
<script type="text/javascript" src="scripts/ui/widgets/cloudBrowser.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/listView.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/detailView.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/tagger.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/treeView.js?t=<%=now%>"></script>
|
||||
<script type="text/javascript" src="scripts/ui/widgets/notifications.js?t=<%=now%>"></script>
|
||||
|
||||
|
|
|
|||
|
|
@ -487,6 +487,10 @@
|
|||
value: data
|
||||
}).data('original-value', data)
|
||||
);
|
||||
|
||||
if ($value.closest('tr').data('detail-view-is-tagged')) {
|
||||
$value.find('input').tagger();
|
||||
}
|
||||
}
|
||||
|
||||
if (rules && rules.required) {
|
||||
|
|
@ -758,6 +762,10 @@
|
|||
// Set up validation metadata
|
||||
$value.data('validation-rules', value.validation);
|
||||
|
||||
if (value.isTag) {
|
||||
$detail.data('detail-view-is-tagged', true);
|
||||
}
|
||||
|
||||
// Set up editable metadata
|
||||
if(typeof(value.isEditable) == 'function')
|
||||
$value.data('detail-view-is-editable', value.isEditable());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
(function($) {
|
||||
var elems = {
|
||||
tagItem: function(title, onRemove) {
|
||||
var $li = $('<li>');
|
||||
var $label = $('<span>').addClass('label').html(title);
|
||||
var $remove = $('<span>').addClass('remove').html('X');
|
||||
|
||||
$remove.click(function() {
|
||||
$li.remove();
|
||||
|
||||
if (onRemove) onRemove();
|
||||
});
|
||||
|
||||
$li.append($remove, $label);
|
||||
|
||||
return $li;
|
||||
}
|
||||
};
|
||||
|
||||
$.widget('cloudStack.tagger', {
|
||||
_init: function() {
|
||||
var $container = $('<div>').addClass('tagger');
|
||||
var $tagArea = $('<ul>').addClass('tags');
|
||||
var $originalInput = this.element;
|
||||
var $input = $('<input>').attr('type', 'text');
|
||||
|
||||
$originalInput.hide();
|
||||
$originalInput.after($container);
|
||||
$container.append($tagArea, $input);
|
||||
|
||||
// Reposition input to fit tag list
|
||||
var relayout = function() {
|
||||
$input.width(
|
||||
$container.width() - $tagArea.width() - 25
|
||||
);
|
||||
$input.css({
|
||||
left: $tagArea.width(),
|
||||
top: $tagArea.position().top
|
||||
});
|
||||
};
|
||||
|
||||
var onRemove = function() {
|
||||
syncInputs(true);
|
||||
relayout();
|
||||
};
|
||||
|
||||
// sync original input box and tag list values
|
||||
//
|
||||
// flag == true: Sync tags->text
|
||||
// flag == false: Sync text->tags
|
||||
var syncInputs = function(flag) {
|
||||
if (flag) {
|
||||
$originalInput.val(
|
||||
$tagArea.find('li').map(function(index, tag) {
|
||||
return $(tag).find('span.label').html();
|
||||
}).toArray().join(',')
|
||||
);
|
||||
} else if ($originalInput.val()) {
|
||||
$($originalInput.val().split(',')).map(function(index, tag) {
|
||||
elems.tagItem(tag, onRemove).appendTo($tagArea);
|
||||
});
|
||||
|
||||
$tagArea.show();
|
||||
relayout();
|
||||
}
|
||||
};
|
||||
|
||||
// Tag detection (comma-delimited)
|
||||
$input.keypress(function(event) {
|
||||
var tagCode = 44; // Symbol used to indicate a new tag
|
||||
|
||||
if (event.which == tagCode) {
|
||||
$tagArea.show();
|
||||
elems.tagItem($input.val(), onRemove).appendTo($tagArea);
|
||||
$input.val('');
|
||||
relayout();
|
||||
syncInputs(true);
|
||||
|
||||
return false; // Don't allow delineator to be added to input box
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$tagArea.hide();
|
||||
relayout();
|
||||
syncInputs(false);
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
||||
Loading…
Reference in New Issue