Angular js fileupload allow only image extensions - javascript

Here is my directive for uploading image profile. It is working fine but what I wanted to know is that how can we filter on this directive to allow only particular extensions, cause I wanted to allow only images. I am using fineupload by the way. Feel free to ask about the code below the image url is e.target.result.
app.directive('uploadProfile', function () {
return function (scope, element, attrs, $window) {
var $uploadCrop;
function readFile(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('.cropper').addClass('ready')
$window.alert("hi")
$uploadCrop.croppie('bind', {
url: e.target.result
}).then(function () {
console.log("do nothing")
});
}
reader.readAsDataURL(input.files[0]);
}
else {
swal("Sorry - you're browser doesn't support the FileReader API");
}
}
$(element).on("change", function () {
readFile(this)
});
$uploadCrop = $('.cropper').croppie({
url: "/static/img/yahshua.jpg",
viewport: {
width: 170,
height: 170,
type: 'circle',
},
enableExif: true,
enableZoom: true,
enforceBoundary: false
});
$(element).on('change', function () { readFile(this); });
$('#cropImage').on('click', function (ev) {
$uploadCrop.croppie('result', {
type: 'base64',
size: 'viewport'
}).then(function (resp) {
scope.record = {}
scope.record.cropped = resp
scope.main.upload_profile(resp)
});
});
};
})

I your html input of type 'file' you can add 'accept' attribute to limit file type to images only :
https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input/file
<input type="file"
id="avatar" name="avatar"
accept="image/png, image/jpeg">

Reviewed all of your code and commented
solution is to use just set the file input attribute to accept="image/*"
app.directive('uploadProfile', function () {
return function (scope, element, attrs, $window) {
var $uploadCrop;
function readFile(input) {
// if (input.files && input.files[0]) {
// files are always avalible nowdays
if (input.files[0]) {
// You don't need the FileReader... (we will use object urls)
// var reader = new FileReader();
// reader.onload = function (e) {
$('.cropper').addClass('ready')
$window.alert('hi')
$uploadCrop.croppie('bind', {
url: URL.createObjectURL(input.files[0])
}).then(function () {
console.log("do nothing")
});
// }
// reader.readAsDataURL(input.files[0]);
}
// All browswers support FileReader nowdays...
// else {
// swal("Sorry - you're browser doesn't support the FileReader API");
// }
}
// set file attribute's accept to "image/*"
// This will only allow users to only select images
element.accept = 'image/*'
$(element).on("change", function () {
readFile(this)
});
$uploadCrop = $('.cropper').croppie({
url: "/static/img/yahshua.jpg",
viewport: {
width: 170,
height: 170,
type: 'circle',
},
enableExif: true,
enableZoom: true,
enforceBoundary: false
});
// You are already doing this above
// $(element).on('change', function () { readFile(this); });
$('#cropImage').on('click', function (ev) {
$uploadCrop.croppie('result', {
type: 'base64', // I would encurage you to use blob & FormData instead
size: 'viewport'
}).then(function (resp) {
scope.record = {}
scope.record.cropped = resp
scope.main.upload_profile(resp)
});
});
};
})

Related

Bootstrap modal js is giving Synchronous XMLHttpRequest on the main thread is deprecated message

I am using Bootstrap Modal Js. However, whenever the modal pops up , I am getting this error
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
Also, in one page I am getting the erorr below when the modal launches using
if (auth=="False"){
setTimeout(function(){
if ($('#registerModal').hasClass('show')){
}else{
$('.register-btn').trigger('click');
}
}, 25000);
}
Error:
jquery.validate.unobtrusive.min.js:5 Uncaught TypeError: Cannot set property 'unobtrusive' of undefined
at jquery.validate.unobtrusive.min.js:5
at jquery.validate.unobtrusive.min.js:5
Here is the js
/*
django-bootstrap-modal-forms
version : 2.0.1
Copyright (c) 2020 Uros Trstenjak
https://github.com/trco/django-bootstrap-modal-forms
*/
(function ($) {
// Open modal & load the form at formURL to the modalContent element
var modalForm = function (settings) {
$(settings.modalID).find(settings.modalContent).load(settings.formURL, function () {
settings.asyncSettings=true;
settings.async = true;
$(settings.modalID).modal("show");
$(settings.modalForm).attr("action", settings.formURL);
addEventHandlers(settings);
});
};
var addEventHandlers = function (settings) {
// submitBtn click handler
$(settings.submitBtn).on("click", function (event) {
isFormValid(settings, submitForm);
});
// Modal close handler
$(settings.modalID).on("hidden.bs.modal", function (event) {
$(settings.modalForm).remove();
});
};
// Check if form.is_valid() & either show errors or submit it via callback
var isFormValid = function (settings, callback) {
$.ajax({
type: $(settings.modalForm).attr("method"),
url: $(settings.modalForm).attr("action"),
data: new FormData($(settings.modalForm)[0]),
contentType: false,
processData: false,
beforeSend: function () {
$(settings.submitBtn).prop("disabled", true);
},
success: function (response) {
if ($(response).find(settings.errorClass).length > 0) {
// Form is not valid, update it with errors
$(settings.modalID).find(settings.modalContent).html(response);
$(settings.modalForm).attr("action", settings.formURL);
// Reinstantiate handlers
addEventHandlers(settings);
} else {
// Form is valid, submit it
callback(settings);
}
}
});
};
// Submit form callback function
var submitForm = function (settings) {
if (!settings.asyncUpdate) {
$(settings.modalForm).submit();
} else {
var asyncSettingsValid = validateAsyncSettings(settings.asyncSettings);
var asyncSettings = settings.asyncSettings;
if (asyncSettingsValid) {
var formdata = new FormData($(settings.modalForm)[0]);
// Add asyncUpdate and check for it in save method of CreateUpdateAjaxMixin
formdata.append("asyncUpdate", "True");
$.ajax({
type: $(settings.modalForm).attr("method"),
url: $(settings.modalForm).attr("action"),
data: formdata,
contentType: false,
processData: false,
success: function (response) {
var body = $("body");
if (body.length === 0) {
console.error("django-bootstrap-modal-forms: <body> element missing in your html.");
}
body.prepend(asyncSettings.successMessage);
// Update page without refresh
$.ajax({
type: "GET",
url: asyncSettings.dataUrl,
dataType: "json",
success: function (response) {
// Update page
$(asyncSettings.dataElementId).html(response[asyncSettings.dataKey]);
// Add modalForm to trigger element after async page update
if (asyncSettings.addModalFormFunction) {
asyncSettings.addModalFormFunction();
}
if (asyncSettings.closeOnSubmit) {
$(settings.modalID).modal("hide");
} else {
// Reload form
$(settings.modalID).find(settings.modalContent).load(settings.formURL, function () {
$(settings.modalForm).attr("action", settings.formURL);
addEventHandlers(settings);
});
}
}
});
}
});
}
}
};
var validateAsyncSettings = function (settings) {
var missingSettings = [];
if (!settings.successMessage) {
missingSettings.push("successMessage");
console.error("django-bootstrap-modal-forms: 'successMessage' in asyncSettings is missing.");
}
if (!settings.dataUrl) {
missingSettings.push("dataUrl");
console.error("django-bootstrap-modal-forms: 'dataUrl' in asyncSettings is missing.");
}
if (!settings.dataElementId) {
missingSettings.push("dataElementId");
console.error("django-bootstrap-modal-forms: 'dataElementId' in asyncSettings is missing.");
}
if (!settings.dataKey) {
missingSettings.push("dataKey");
console.error("django-bootstrap-modal-forms: 'dataKey' in asyncSettings is missing.");
}
if (!settings.addModalFormFunction) {
missingSettings.push("addModalFormFunction");
console.error("django-bootstrap-modal-forms: 'addModalFormFunction' in asyncSettings is missing.");
}
if (missingSettings.length > 0) {
return false;
}
return true;
};
$.fn.modalForm = function (options) {
// Default settings
var defaults = {
modalID: "#modal",
modalContent: ".modal-content",
modalForm: ".modal-content form",
formURL: null,
errorClass: ".invalid",
submitBtn: ".submit-btn",
asyncUpdate: true,
asyncSettings: {
closeOnSubmit: false,
successMessage: null,
dataUrl: null,
dataElementId: null,
dataKey: null,
addModalFormFunction: null
}
};
// Extend default settings with provided options
var settings = $.extend(defaults, options);
this.each(function () {
// Add click event handler to the element with attached modalForm
$(this).click(function (event) {
// Instantiate new form in modal
modalForm(settings);
});
});
return this;
};
}(jQuery));

filetype validation before crop image using jQuery

I have this code for crop image using jquery croppie plugin and upload using bootstrap modal. in my case i work with FileReader
$(document).ready(function(){
$image_crop = $('#image_demo').croppie({
enableExif: true,
viewport: {
width:200,
height:300,
type:'square' //circle
},
boundary:{
width:300,
height:300
}
});
var fileTypes = ['jpg', 'jpeg', 'png'];
$('#upload_image').on('change', function(){
var reader = new FileReader();
reader.onload = function (event) {
$image_crop.croppie('bind', {
url: event.target.result
}).then(function(){
console.log('jQuery bind complete');
});
}
reader.readAsDataURL(this.files[0]);
$('#uploadimageModal').modal('show');
});
$('.crop_image').click(function(event){
$image_crop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function(response){
$.ajax({
url:"../account/edit/profileimage",
type: "POST",
//dataType:"json",
data:{"image": response},
success:function(data)
{
/*
if(response.status === 'error'){
$('#uploadimageModal').animate({ scrollTop: $('#uploaderror').offset().top }, 500);
$('#uploaderror').html(response.message);
}
else {
*/
$('#uploadimageModal').modal('hide');
$('#uploaded_image').html(data);
/*
}
*/
}
});
})
});
});
Now in action i need to check filetype validation and show alert before load modal box. how do can i show alert message?!
Have a look at the code below. Hope it helps
var fileTypes = ['jpg', 'jpeg', 'png'];
$('#upload_image').on('change', function() {
var reader = new FileReader();
var file = this.files[0]; // Get your file here
var fileExt = file.type.split('/')[1]; // Get the file extension
if (fileTypes.indexOf(fileExt) !== -1) {
reader.onload = function(event) {
$image_crop.croppie('bind', {
url: event.target.result
}).then(function() {
console.log('jQuery bind complete');
});
}
reader.readAsDataURL(file);
$('#uploadimageModal').modal('show');
} else {
alert('File not supported');
}
});

Angular JS File upload Content Disposition

I am new to Angular JS and trying my hands on File upload.
My requirement is to submit the multipart data on button click.
I read on ng-model not working on type="file", so I got to know the work around and i copied the directive. after working through that directive, while sending data there is no Content-disposition data set. I mean file name, content type etc which I want to read at server side.
that is why I am getting null at headerOfFilePart.getFileName()
what I am doing wrong. what is the right way to achieve things i described above in Angular JS.
<div ng-controller="uploadController">
<h2> Add Order </h2>
Enter your Name:
<input type="text" name="name" ng-model="myName"/>
<input type="file" fileread="vm.uploadme" />
<input type="button" name="button" ng-click='uploadFile()'/>
</div>
And this is my JS part
validationApp.controller('uploadController', function($scope,$http,$location,$window) {
$scope.uploadFile = function() {
var fd = new FormData();
//Take the first selected file
fd.append("file", $scope.vm.uploadme);
fd.append("name", $scope.myName);
uploadUrl = "http://localhost:8080/IPOCCService/rest/UserManager/upload1";
$http.post(uploadUrl, fd, {
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).
success(function(data, status, headers, config) {
alert(data);
}).
error(function(data, status, headers, config) {
alert("failure");
});
};
});
validationApp.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
};
reader.readAsDataURL(changeEvent.target.files[0]);
});
}
};
}]);
REST JAVA
#POST
#Path("/upload1")
#Produces({ MediaType.APPLICATION_JSON} )
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response responseMsg3(FormDataMultiPart form) {
System.out.println("File Uploaded");
FormDataBodyPart filePart1 = form.getField("name");
System.out.println(filePart1.getName() + " = " +filePart1.getValue());
FormDataBodyPart filePart = form.getField("file");
ContentDisposition headerOfFilePart = filePart.getContentDisposition();
InputStream fileInputStream = filePart.getValueAs(InputStream.class);
String filePath = SERVER_UPLOAD_LOCATION_FOLDER + headerOfFilePart.getFileName();
// save the file to the server
saveFile(fileInputStream, filePath);
String output = "File saved to server location : " + filePath;
return Response.status(200).entity("true").build();
}
When you use FileReader to read your files, only the contents of the file is assigned to your scope:
scope.fileread = loadEvent.target.result;
In your case, just simply assign the file to your scope:
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
scope.$apply(function(){
scope.fileread = changeEvent.target.files[0];
// changeEvent.target.files[0] is an HTML5 file object which contains ALL
// information about the file including fileName, contents,...
// scope.fileread is now assigned the selected file
});
});
}
app.directive('fileRead', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileread);
var modelSetter = model.assign;
element.bind('change', function(){
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.readAsDataURL(input.files[0]);
}
}
readURL(this);
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
<input type="file" file-read="vm.uploadme" />
this directive works for me.
You can use the module ng-file-upload it's a directive that do everythinh about file upload See here

get size of file jquery

My view I want to check file if it bigger than 500 kb give for example alert()
<img src="#Model.Value" width="95" height="80" id="down-load" data-id="#Model.Key" data upload="#Url.Action("AddPreview", "Images")" />
(function ($) {
$("[data-id]").each(function () {
var $this = $(this);
$($this).upload({
name: 'attachments',
action: $this.data("upload"),
enctype: 'multipart/form-data',
params: {},
autoSubmit: true,
onSubmit: function () { },
onSelect: function () {
var size = $('#down-load')[0].files[0].size;//do not work
},
onComplete: function (e) {
if (e.charAt(0) != '[') {
$.fn.showUserActionNotification(e, true);
return;
}
var data = JSON.parse(e);
if (data[0].Error) {
$.fn.showUserActionNotification(data[0].Error, true);
}
else if (data[0].Preview) {
$this.attr("src", data[0].Preview);
}
}
});
$this.parent().find("input").css("cursor", "pointer");
});
})(jQuery);
I want to get size on function onSelect to check it on big
Is any body can help me?
I have done function
var imageSize = function (e) {
return $.map(e.files, function (file) {
var name = file.name;
var size = file.size;
if (size > 512000) {
var alert = $(".valid-size-goods").text(name + ": " + (size / 1024).toFixed(2) + " kb");
alert.dialog({
title: alert.attr("dlgTitle"),
modal: true,
resizable: false,
buttons: [{ text: alert.attr("btn"), click: function () { $(this).dialog("close"); } }]
}); return false;
}
return true;
});
};
and put it to onSelect:imageSize(e)

Knockout JS: Fileupload event

I have this knockout js script for uploading file
This code triggers the upload event when the user selects a file in the upload control
Upload.html
$(function() {
var viewModel = {
filename: ko.observable(""),
};
ko.applyBindings(viewModel);
});
<form>
<input id="upload" name="upload"
data-bind="fileUpload: { property: 'filename', url: 'http://localhost/api/upload/PostFormData' }"
type="file" />
<button id="submitUpload">Upload</button>
</form>
FileUpload.js
ko.bindingHandlers.fileUpload = {
init: function (element, valueAccessor) {
$(element).after('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div><div class="progressError"></div>');
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor()),
property = ko.utils.unwrapObservable(options.property),
url = ko.utils.unwrapObservable(options.url);
if (property && url) {
$(element).change(function() {
if (element.files.length) {
var $this = $(this),
fileName = $this.val();
// this uses jquery.form.js plugin
$(element.form).ajaxSubmit({
url: url,
type: "POST",
dataType: "text",
headers: { "Content-Disposition": "attachment; filename=" + fileName },
beforeSubmit: function() {
$(".progress").show();
$(".progressError").hide();
$(".bar").width("0%")
$(".percent").html("0%");
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + "%";
$(".bar").width(percentVal)
$(".percent").html(percentVal);
},
success: function(data) {
//$(".progress").hide();
//$(".progressError").hide();
// set viewModel property to filename
$("label[for='upload']").text(data);
bindingContext.$data[property](data);
},
error: function(jqXHR, errorThrown) {
$(".progress").hide();
$("div.progressError").html(jqXHR.responseText);
}
});
}
});
}
}
}
Now, I want to move the triggering of upload event to the submit button
<button id="submitUpload">Upload</button>
How to do this? Right now this is where I'm at, I just move the upload event inside the click event of the button. But it's not working, and it doesn't call the ajax request to the API.
$('#submitUpload').click(function () {
if (element.files.length) {
var $this = $(element),
fileName = $this.val();
//alert(element.form);
// this uses jquery.form.js plugin
$(element.form).ajaxSubmit({
url: url,
type: "POST",
dataType: "text",
headers: { "Content-Disposition": "attachment; filename=" + fileName },
beforeSubmit: function() {
$(".progress").show();
$(".progressError").hide();
$(".bar").width("0%")
$(".percent").html("0%");
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + "%";
$(".bar").width(percentVal)
$(".percent").html(percentVal);
},
success: function(data) {
//$(".progress").hide();
//$(".progressError").hide();
// set viewModel property to filename
$("label[for='upload']").text(data);
bindingContext.$data[property](data);
},
error: function(jqXHR, errorThrown) {
$(".progress").hide();
$("div.progressError").html(jqXHR.responseText);
}
});
}
});
Instead of passing only name, URL to the bindinghandler pass third parameter (fileBinaryData) from your ViewModel Object then read the file Content in KO BindingHandler's Update method then update third observable (fileBinaryData) in update method.
Then you can use this filebinary data in you viewmodel
so for the button bind click event and access fileBinaryData observable which will have the file content.
BindingHandler:
ko.bindingHandlers.FileUpload = {
init: function (element, valueAccessor) {
$(element).change(function () {
var file = this.files[0];
if (ko.isObservable(valueAccessor())) {
valueAccessor()(file);
}
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var file = ko.utils.unwrapObservable(valueAccessor());
var bindings = allBindingsAccessor();
if (bindings.fileBinaryData && ko.isObservable(bindings.fileBinaryData)) {
if (!file) {
bindings.fileBinaryData(null);
} else {
var reader = new window.FileReader();
reader.onload = function (e) {
bindings.fileBinaryData(e.target.result);
};
reader.readAsBinaryString(file);
}
}
}
}
HTML:
<input type="file" id="fileUpload" class="file_input_hidden" data-bind="FileUpload: spFile, fileObjectURL: spFileObjectURL, fileBinaryData: spFileBinary" />
ViewModel:
var viewModel = {
filename: ko.observable(""),
url: ko.observable(),
spFileBinary:ko.observable(),
//Write your CLICK EVENTS
};
Hope This Helps :)
element is unknown at the moment of click. you need to find it on the form.
Start the first line of your click function with
element = $('#upload').get(0);
and replace your button tag with the following
<input type="button" id="submitUpload" value="Upload"></input>
because the button tag automatically submits the form.

Categories

Resources