mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-30 04:23:11 +03:00
Added AJAX-based search to books, Fixes #15
This commit is contained in:
31
resources/assets/js/book-sidebar.js
Normal file
31
resources/assets/js/book-sidebar.js
Normal file
@ -0,0 +1,31 @@
|
||||
var bookDashboard = new Vue({
|
||||
el: '#book-dashboard',
|
||||
data: {
|
||||
searching: false,
|
||||
searchTerm: '',
|
||||
searchResults: ''
|
||||
},
|
||||
methods: {
|
||||
searchBook: function (e) {
|
||||
e.preventDefault();
|
||||
var term = this.searchTerm;
|
||||
if (term.length == 0) return;
|
||||
this.searching = true;
|
||||
this.searchResults = '';
|
||||
var searchUrl = this.$$.form.getAttribute('action');
|
||||
searchUrl += '?term=' + encodeURIComponent(term);
|
||||
this.$http.get(searchUrl, function (data) {
|
||||
this.$set('searchResults', data);
|
||||
});
|
||||
},
|
||||
checkSearchForm: function (e) {
|
||||
if (this.searchTerm.length < 1) {
|
||||
this.searching = false;
|
||||
}
|
||||
},
|
||||
clearSearch: function(e) {
|
||||
this.searching = false;
|
||||
this.searchTerm = '';
|
||||
}
|
||||
}
|
||||
});
|
@ -1,154 +1,122 @@
|
||||
|
||||
jQuery.fn.showSuccess = function(message) {
|
||||
var elem = $(this);
|
||||
var success = $('<div class="text-pos" style="display:none;"><i class="zmdi zmdi-check-circle"></i>'+message+'</div>');
|
||||
elem.after(success);
|
||||
success.slideDown(400, function() {
|
||||
setTimeout(function() {success.slideUp(400, function() {
|
||||
success.remove();
|
||||
})}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
jQuery.fn.showFailure = function(messageMap) {
|
||||
var elem = $(this);
|
||||
$.each(messageMap, function(key, messages) {
|
||||
var input = elem.find('[name="'+key+'"]').last();
|
||||
var fail = $('<div class="text-neg" style="display:none;"><i class="zmdi zmdi-alert-circle"></i>'+messages.join("\n")+'</div>');
|
||||
input.after(fail);
|
||||
fail.slideDown(400, function() {
|
||||
setTimeout(function() {fail.slideUp(400, function() {
|
||||
fail.remove();
|
||||
})}, 2000);
|
||||
});
|
||||
});
|
||||
window.ImageManager = new Vue({
|
||||
|
||||
};
|
||||
el: '#image-manager',
|
||||
|
||||
(function() {
|
||||
data: {
|
||||
images: [],
|
||||
hasMore: false,
|
||||
page: 0,
|
||||
cClickTime: 0,
|
||||
selectedImage: false
|
||||
},
|
||||
|
||||
var ImageManager = new Vue({
|
||||
created: function () {
|
||||
// Get initial images
|
||||
this.fetchData(this.page);
|
||||
},
|
||||
|
||||
el: '#image-manager',
|
||||
ready: function () {
|
||||
// Create dropzone
|
||||
this.setupDropZone();
|
||||
},
|
||||
|
||||
data: {
|
||||
images: [],
|
||||
hasMore: false,
|
||||
page: 0,
|
||||
cClickTime: 0,
|
||||
selectedImage: false
|
||||
methods: {
|
||||
fetchData: function () {
|
||||
var _this = this;
|
||||
this.$http.get('/images/all/' + _this.page, function (data) {
|
||||
_this.images = _this.images.concat(data.images);
|
||||
_this.hasMore = data.hasMore;
|
||||
_this.page++;
|
||||
});
|
||||
},
|
||||
|
||||
created: function() {
|
||||
// Get initial images
|
||||
this.fetchData(this.page);
|
||||
},
|
||||
|
||||
ready: function() {
|
||||
// Create dropzone
|
||||
this.setupDropZone();
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchData: function() {
|
||||
var _this = this;
|
||||
$.getJSON('/images/all/' + _this.page, function(data) {
|
||||
_this.images = _this.images.concat(data.images);
|
||||
_this.hasMore = data.hasMore;
|
||||
_this.page++;
|
||||
});
|
||||
},
|
||||
|
||||
setupDropZone: function() {
|
||||
var _this = this;
|
||||
var dropZone = new Dropzone(_this.$$.dropZone, {
|
||||
url: '/upload/image',
|
||||
init: function() {
|
||||
var dz = this;
|
||||
this.on("sending", function(file, xhr, data) {
|
||||
data.append("_token", document.querySelector('meta[name=token]').getAttribute('content'));
|
||||
setupDropZone: function () {
|
||||
var _this = this;
|
||||
var dropZone = new Dropzone(_this.$$.dropZone, {
|
||||
url: '/upload/image',
|
||||
init: function () {
|
||||
var dz = this;
|
||||
this.on("sending", function (file, xhr, data) {
|
||||
data.append("_token", document.querySelector('meta[name=token]').getAttribute('content'));
|
||||
});
|
||||
this.on("success", function (file, data) {
|
||||
_this.images.unshift(data);
|
||||
$(file.previewElement).fadeOut(400, function () {
|
||||
dz.removeFile(file);
|
||||
});
|
||||
this.on("success", function(file, data) {
|
||||
_this.images.unshift(data);
|
||||
$(file.previewElement).fadeOut(400, function() {
|
||||
dz.removeFile(file);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
imageClick: function(image) {
|
||||
var dblClickTime = 380;
|
||||
var cTime = (new Date()).getTime();
|
||||
var timeDiff = cTime - this.cClickTime;
|
||||
if(this.cClickTime !== 0 && timeDiff < dblClickTime && this.selectedImage === image) {
|
||||
// DoubleClick
|
||||
if(this.callback) {
|
||||
this.callback(image);
|
||||
}
|
||||
this.hide();
|
||||
} else {
|
||||
this.selectedImage = (this.selectedImage===image) ? false : image;
|
||||
});
|
||||
}
|
||||
this.cClickTime = cTime;
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
selectButtonClick: function() {
|
||||
if(this.callback) {
|
||||
this.callback(this.selectedImage);
|
||||
imageClick: function (image) {
|
||||
var dblClickTime = 380;
|
||||
var cTime = (new Date()).getTime();
|
||||
var timeDiff = cTime - this.cClickTime;
|
||||
if (this.cClickTime !== 0 && timeDiff < dblClickTime && this.selectedImage === image) {
|
||||
// DoubleClick
|
||||
if (this.callback) {
|
||||
this.callback(image);
|
||||
}
|
||||
this.hide();
|
||||
},
|
||||
|
||||
show: function(callback) {
|
||||
this.callback = callback;
|
||||
this.$$.overlay.style.display = 'block';
|
||||
},
|
||||
|
||||
overlayClick: function(e) {
|
||||
if(e.target.className==='overlay') {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.$$.overlay.style.display = 'none';
|
||||
},
|
||||
|
||||
saveImageDetails: function(e) {
|
||||
e.preventDefault();
|
||||
var _this = this;
|
||||
var form = $(_this.$$.imageForm);
|
||||
$.ajax('/images/update/' + _this.selectedImage.id, {
|
||||
method: 'PUT',
|
||||
data: form.serialize()
|
||||
}).done(function() {
|
||||
form.showSuccess('Image name updated');
|
||||
}).fail(function(jqXHR) {
|
||||
form.showFailure(jqXHR.responseJSON);
|
||||
})
|
||||
},
|
||||
|
||||
deleteImage: function(e) {
|
||||
e.preventDefault();
|
||||
var _this = this;
|
||||
var form = $(_this.$$.imageDeleteForm);
|
||||
$.ajax('/images/' + _this.selectedImage.id, {
|
||||
method: 'DELETE',
|
||||
data: form.serialize()
|
||||
}).done(function() {
|
||||
_this.images.splice(_this.images.indexOf(_this.selectedImage), 1);
|
||||
_this.selectedImage = false;
|
||||
$(_this.$$.imageTitle).showSuccess('Image Deleted');
|
||||
})
|
||||
} else {
|
||||
this.selectedImage = (this.selectedImage === image) ? false : image;
|
||||
}
|
||||
this.cClickTime = cTime;
|
||||
},
|
||||
|
||||
selectButtonClick: function () {
|
||||
if (this.callback) {
|
||||
this.callback(this.selectedImage);
|
||||
}
|
||||
this.hide();
|
||||
},
|
||||
|
||||
show: function (callback) {
|
||||
this.callback = callback;
|
||||
this.$$.overlay.style.display = 'block';
|
||||
},
|
||||
|
||||
overlayClick: function (e) {
|
||||
if (e.target.className === 'overlay') {
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.$$.overlay.style.display = 'none';
|
||||
},
|
||||
|
||||
saveImageDetails: function (e) {
|
||||
e.preventDefault();
|
||||
var _this = this;
|
||||
var form = $(_this.$$.imageForm);
|
||||
$.ajax('/images/update/' + _this.selectedImage.id, {
|
||||
method: 'PUT',
|
||||
data: form.serialize()
|
||||
}).done(function () {
|
||||
form.showSuccess('Image name updated');
|
||||
}).fail(function (jqXHR) {
|
||||
form.showFailure(jqXHR.responseJSON);
|
||||
})
|
||||
},
|
||||
|
||||
deleteImage: function (e) {
|
||||
e.preventDefault();
|
||||
var _this = this;
|
||||
var form = $(_this.$$.imageDeleteForm);
|
||||
$.ajax('/images/' + _this.selectedImage.id, {
|
||||
method: 'DELETE',
|
||||
data: form.serialize()
|
||||
}).done(function () {
|
||||
_this.images.splice(_this.images.indexOf(_this.selectedImage), 1);
|
||||
_this.selectedImage = false;
|
||||
$(_this.$$.imageTitle).showSuccess('Image Deleted');
|
||||
})
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
window.ImageManager = ImageManager;
|
||||
|
||||
|
||||
})();
|
||||
});
|
||||
|
43
resources/assets/js/jquery-extensions.js
vendored
Normal file
43
resources/assets/js/jquery-extensions.js
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
jQuery.fn.smoothScrollTo = function() {
|
||||
if(this.length === 0) return;
|
||||
$('body').animate({
|
||||
scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin
|
||||
}, 800); // Adjust to change animations speed (ms)
|
||||
return this;
|
||||
};
|
||||
$.expr[":"].contains = $.expr.createPseudo(function(arg) {
|
||||
return function( elem ) {
|
||||
return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
|
||||
};
|
||||
});
|
||||
|
||||
jQuery.fn.showSuccess = function (message) {
|
||||
var elem = $(this);
|
||||
var success = $('<div class="text-pos" style="display:none;"><i class="zmdi zmdi-check-circle"></i>' + message + '</div>');
|
||||
elem.after(success);
|
||||
success.slideDown(400, function () {
|
||||
setTimeout(function () {
|
||||
success.slideUp(400, function () {
|
||||
success.remove();
|
||||
})
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
jQuery.fn.showFailure = function (messageMap) {
|
||||
var elem = $(this);
|
||||
$.each(messageMap, function (key, messages) {
|
||||
var input = elem.find('[name="' + key + '"]').last();
|
||||
var fail = $('<div class="text-neg" style="display:none;"><i class="zmdi zmdi-alert-circle"></i>' + messages.join("\n") + '</div>');
|
||||
input.after(fail);
|
||||
fail.slideDown(400, function () {
|
||||
setTimeout(function () {
|
||||
fail.slideUp(400, function () {
|
||||
fail.remove();
|
||||
})
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
};
|
Reference in New Issue
Block a user