"markdown-it": "^8.3.1",
"markdown-it-task-lists": "^2.0.0",
"moment": "^2.12.0",
- "vue": "^2.2.6"
+ "vue": "^2.2.6",
+ "vuedraggable": "^2.14.1"
},
"browser": {
"vue": "vue/dist/vue.common.js"
containment: "parent",
axis: "y"
};
-
- /**
- * Push an empty tag to the end of the scope tags.
- */
- function addEmptyTag() {
- $scope.tags.push({
- name: '',
- value: ''
- });
- }
- $scope.addEmptyTag = addEmptyTag;
-
- /**
- * Get all tags for the current book and add into scope.
- */
- function getTags() {
- let url = window.baseUrl(`/ajax/tags/get/page/${pageId}`);
- $http.get(url).then((responseData) => {
- $scope.tags = responseData.data;
- addEmptyTag();
- });
- }
- getTags();
-
- /**
- * Set the order property on all tags.
- */
- function setTagOrder() {
- for (let i = 0; i < $scope.tags.length; i++) {
- $scope.tags[i].order = i;
- }
- }
-
- /**
- * When an tag changes check if another empty editable
- * field needs to be added onto the end.
- * @param tag
- */
- $scope.tagChange = function(tag) {
- let cPos = $scope.tags.indexOf(tag);
- if (cPos !== $scope.tags.length-1) return;
-
- if (tag.name !== '' || tag.value !== '') {
- addEmptyTag();
- }
- };
-
- /**
- * When an tag field loses focus check the tag to see if its
- * empty and therefore could be removed from the list.
- * @param tag
- */
- $scope.tagBlur = function(tag) {
- let isLast = $scope.tags.length - 1 === $scope.tags.indexOf(tag);
- if (tag.name === '' && tag.value === '' && !isLast) {
- let cPos = $scope.tags.indexOf(tag);
- $scope.tags.splice(cPos, 1);
- }
- };
-
- /**
- * Remove a tag from the current list.
- * @param tag
- */
- $scope.removeTag = function(tag) {
- let cIndex = $scope.tags.indexOf(tag);
- $scope.tags.splice(cIndex, 1);
- };
+ // TODO - Delete
}]);
--- /dev/null
+const draggable = require('vuedraggable');
+
+let data = {
+ pageId: false,
+ tags: [],
+};
+
+const components = {draggable};
+
+let computed = {
+
+};
+
+let methods = {
+
+ addEmptyTag() {
+ this.tags.push({name: '', value: '', key: Math.random().toString(36).substring(7)});
+ },
+
+ /**
+ * When an tag changes check if another empty editable field needs to be added onto the end.
+ * @param tag
+ */
+ tagChange(tag) {
+ let tagPos = this.tags.indexOf(tag);
+ if (tagPos !== this.tags.length-1 || tag.name !== '' || tag.value !== '') return;
+ this.addEmptyTag();
+ },
+
+ /**
+ * When an tag field loses focus check the tag to see if its
+ * empty and therefore could be removed from the list.
+ * @param tag
+ */
+ tagBlur(tag) {
+ let isLast = (this.tags.indexOf(tag) === this.tags.length-1);
+ if (tag.name !== '' || tag.value !== '' || isLast) return;
+ let cPos = this.tags.indexOf(tag);
+ this.tags.splice(cPos, 1);
+ },
+
+ removeTag(tag) {
+ let tagPos = this.tags.indexOf(tag);
+ if (tagPos === -1) return;
+ this.tags.splice(tagPos, 1);
+ }
+};
+
+function mounted() {
+ this.pageId = Number(this.$el.getAttribute('page-id'));
+
+ let url = window.baseUrl(`/ajax/tags/get/page/${this.pageId}`);
+ this.$http.get(url).then(response => {
+ let tags = response.data;
+ for (let i = 0, len = tags.length; i < len; i++) {
+ tags[i].key = Math.random().toString(36).substring(7);
+ }
+ this.tags = tags;
+ this.addEmptyTag();
+ });
+}
+
+module.exports = {
+ data, computed, methods, mounted, components
+};
\ No newline at end of file
'entity-dashboard': require('./entity-search'),
'code-editor': require('./code-editor'),
'image-manager': require('./image-manager'),
+ 'tag-manager': require('./tag-manager'),
};
window.vues = {};
width: 100%;
min-width: 50px;
}
- .tags td {
+ .tags td, .tag-table > div > div > div {
padding-right: $-s;
padding-top: $-s;
position: relative;
.ui-sortable-helper {
display: table;
}
+}
+
+.fake-table {
+ display: table;
+ > div {
+ display: table-row-group;
+ }
+ > div > div {
+ display: table-row;
+ }
+ > div > div > div {
+ display: table-cell;
+ }
}
\ No newline at end of file
@endif
</div>
- <div toolbox-tab-content="tags" ng-controller="PageTagController" page-id="{{ $page->id or 0 }}">
+ <div toolbox-tab-content="tags" id="tag-manager" page-id="{{ $page->id or 0 }}">
<h4>{{ trans('entities.page_tags') }}</h4>
<div class="padded tags">
<p class="muted small">{!! nl2br(e(trans('entities.tags_explain'))) !!}</p>
- <table class="no-style" tag-autosuggestions style="width: 100%;">
- <tbody ui-sortable="sortOptions" ng-model="tags" >
- <tr ng-repeat="tag in tags track by $index">
- <td width="20" ><i class="handle zmdi zmdi-menu"></i></td>
- <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/names') }}" autosuggest-type="name" class="outline" ng-attr-name="tags[@{{$index}}][name]" type="text" ng-model="tag.name" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"></td>
- <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/values') }}" autosuggest-type="value" class="outline" ng-attr-name="tags[@{{$index}}][value]" type="text" ng-model="tag.value" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="{{ trans('entities.tag_value') }}"></td>
- <td width="10" ng-show="tags.length != 1" class="text-center text-neg" style="padding: 0;" ng-click="removeTag(tag)"><i class="zmdi zmdi-close"></i></td>
- </tr>
- </tbody>
- </table>
+
+ <draggable class="fake-table no-style tag-table" :options="{handle: '.handle'}" :list="tags" element="div" style="width: 100%;">
+ <transition-group name="test" tag="div">
+ <div v-for="(tag, i) in tags" :key="tag.key">
+ <div width="20" class="handle" ><i class="zmdi zmdi-menu"></i></div>
+ <div><input autosuggest="{{ baseUrl('/ajax/tags/suggest/names') }}" autosuggest-type="name" class="outline" :name="tags[i].name"
+ v-model="tag.name" @change="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"></div>
+ <div><input autosuggest="{{ baseUrl('/ajax/tags/suggest/values') }}" autosuggest-type="value" class="outline" :name="tags[i].value"
+ v-model="tag.value" @change="tagChange(tag)" @blur="tagBlur(tag)" placeholder="{{ trans('entities.tag_value') }}"></div>
+ <div width="10" v-show="tags.length !== 1" class="text-center text-neg" style="padding: 0;" @click="removeTag(tag)"><i class="zmdi zmdi-close"></i></div>
+ </div>
+ </transition-group>
+ </draggable>
+
<table class="no-style" style="width: 100%;">
<tbody>
<tr class="unsortable">
- <td width="34"></td>
- <td ng-click="addEmptyTag()">
+ <td width="34"></td>
+ <td @click="addEmptyTag">
<button type="button" class="text-button">{{ trans('entities.tags_add') }}</button>
</td>
<td></td>
</tr>
</tbody>
</table>
+
</div>
</div>