diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index ef81697e464..e405fbf4fcb 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -8952,6 +8952,204 @@ div.panel.ui-dialog div.list-view div.fixed-header { background: #DFE1E3; } +/*Tagger*/ +.tagger { + width: 94%; + margin: auto; + padding-bottom: 12px; + background: #F2F0F0; + border: 1px solid #CFC9C9; + /*+placement:shift -4px 0px;*/ + position: relative; + left: -4px; + top: 0px; +} + +.tagger .field { + width: 179px; + float: left; + position: relative; +} + +.tagger .tag-info { + font-size: 11px; + color: #757575; + margin-top: 12px; + margin-left: 8px; +} + +.tagger .tag-info.title { + font-size: 11px; + color: #6F9BF0; + margin-bottom: 5px; +} + +.tagger form { + margin: 12px 9px 0px; +} + +.tagger.readonly form { + display: none; +} + +.tagger form label { + display: block; + float: left; + width: 28px; + text-align: right; + font-size: 10px; + color: #394552; + margin-right: 9px; + /*+placement:shift 5px 8px;*/ + position: relative; + left: 5px; + top: 8px; +} + +.tagger form label.error { + position: absolute; + color: #FF0000; + left: 42px; + top: 29px; + /*[empty]background-color:;*/ +} + +.tagger form input { + padding: 4px; + background: #FFFFFF; + border: 1px solid #808080; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} + +.tagger form input[type=submit] { + background: url(../images/bg-gradients.png) repeat-x 0px -220px; + cursor: pointer; + color: #FFFFFF; + /*+text-shadow:0px -1px 2px #000000;*/ + -moz-text-shadow: 0px -1px 2px #000000; + -webkit-text-shadow: 0px -1px 2px #000000; + -o-text-shadow: 0px -1px 2px #000000; + text-shadow: 0px -1px 2px #000000; + border: none; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; + padding: 7px 25px 7px 26px; + margin-left: 16px; +} + +.tagger form input[type=submit]:hover { + background-position: 0px -946px; +} + +.tagger ul { + display: block; + width: 96%; + margin: 16px auto auto; + /*+border-radius:2px;*/ + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; + overflow: auto; + padding-bottom: 10px; + border: 1px solid #D2D2D2; + background: #FFFFFF; + /*+box-shadow:inset 0px 0px 10px #DCDCDC;*/ + -moz-box-shadow: inset 0px 0px 10px #DCDCDC; + -webkit-box-shadow: inset 0px 0px 10px #DCDCDC; + -o-box-shadow: inset 0px 0px 10px #DCDCDC; + box-shadow: inset 0px 0px 10px #DCDCDC; +} + +.tagger.readonly ul { +} + +.tagger ul li { + background: #DFDFDF 0px 4px; + height: 15px; + padding: 0px 18px 0 7px; + display: inline-block; + float: left; + margin-left: 7px; + margin-right: 2px; + margin-top: 5px; + /*+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 { + color: #000000; +} + +.tagger ul li span.label { + font-size: 10px; + position: relative; + left: 15px; + top: -2px; +} + +.tagger.readonly ul li span.label { + left: 6px; +} + +.tagger ul li span.remove { + width: 15px !important; + overflow: hidden !important; + height: 11px !important; + background: #DFDFDF url(../images/sprites.png) no-repeat -596px -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.readonly ul li span.remove { + display: none; +} + +.tagger ul li span.remove:hover { + color: #000000; +} + +/** Dialog tagger*/ +.ui-dialog .tagger { +} + +.ui-dialog .tagger .field { + width: 119px !important; +} + +.ui-dialog .tagger input.key, +.ui-dialog .tagger input.value { + width: 66px !important; + height: 15px; + font-size: 11px !important; +} + +.ui-dialog .tagger input[type=submit] { + padding: 6px 15px; +} + /*VPC / vApps*/ .vpc-chart { width: 100%; diff --git a/ui/index.jsp b/ui/index.jsp index af05f4a652d..d942bb9776c 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -1614,7 +1614,8 @@ - + + diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index cf437afed52..55d014ba429 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -617,5 +617,83 @@ cloudStack.api = { } } } + }, + + tags: function(args) { + var resourceType = args.resourceType; + var contextId = args.contextId; + + return { + actions: { + add: function(args) { + var data = args.data; + var resourceId = args.context[contextId][0].id; + + $.ajax({ + url: createURL( + 'createTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value + ), + data: { + resourceIds: resourceId, + resourceType: resourceType + }, + success: function(json) { + args.response.success({ + _custom: { jobId: json.createtagsresponse.jobid }, + notification: { + desc: 'Add tag for instance', + poll: pollAsyncJobResult + } + }); + } + }); + }, + + remove: function(args) { + var data = args.context.tagItems[0]; + var resourceId = args.context[contextId][0].id; + + $.ajax({ + url: createURL( + 'deleteTags&tags[0].key=' + data.key + '&tags[0].value=' + data.value + ), + data: { + resourceIds: resourceId, + resourceType: resourceType + }, + success: function(json) { + args.response.success({ + _custom: { jobId: json.deletetagsresponse.jobid }, + notification: { + desc: 'Remove tag for instance', + poll: pollAsyncJobResult + } + }); + } + }); + } + }, + dataProvider: function(args) { + var resourceId = args.context[contextId][0].id; + + $.ajax({ + url: createURL('listTags'), + data: { + listAll: true, + resourceId: resourceId, + resourceType: resourceType + }, + success: function(json) { + args.response.success({ + data: json.listtagsresponse ? + json.listtagsresponse.tag : [] + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + }; } }; diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index b1e9a68c8a9..4c7448eba1a 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -287,10 +287,14 @@ * @param callback */ edit: function($detailView, args) { + $detailView.addClass('edit-mode'); + if ($detailView.find('.button.done').size()) return false; // Convert value TDs - var $inputs = $detailView.find('input, select'); + var $inputs = $detailView.find('input, select').filter(function() { + return !$(this).closest('.tagger').size() && !$(this).attr('type') == 'submit'; + }); var action = args.actions[args.actionName]; var id = $detailView.data('view-args').id; var $editButton = $('