I'm trying to dynamically update the MaxFiles property each time a new image is uploaded/deleted.
By using the following code its not allowing any image to upload instead of limitize it to maxFiles. And it is not taking the value of the variable maxFile, but when i remove maxFile variable And put a number then it works fine.
got source code idea from this Answer.
!function ($) {
"use strict";
var Onyx = Onyx || {};
Onyx = {
init: function() {
var self = this,
obj;
for (obj in self) {
if ( self.hasOwnProperty(obj)) {
var _method = self[obj];
if ( _method.selector !== undefined && _method.init !== undefined ) {
if ( $(_method.selector).length > 0 ) {
_method.init();
}
}
}
}
},
userFilesDropzone: {
selector: 'form.dropzone',
init: function() {
var base = this,
container = $(base.selector);
base.initFileUploader(base, 'form.dropzone');
},
initFileUploader: function(base, target) {
var maxFile = $('.dropzone').attr('data-count');
var onyxDropzone = new Dropzone(target, {
url: ($(target).attr("action")) ? $(target).attr("action") : "data.php", // Check that our form has an action attr and if not, set one here
maxFiles: maxFile,
maxFilesize: 5,
acceptedFiles: ".JPG,.PNG,.JPEG",
// previewTemplate: previewTemplate,
// previewsContainer: "#previews",
clickable: true,
uploadMultiple: false,
});
onyxDropzone.on("success", function(file, response) {
let parsedResponse = JSON.parse(response);
file.upload_ticket = parsedResponse.file_link;
var imagecount = $('.dropzone').attr('data-count');
imagecount = imagecount - 1;
$('.dropzone').attr('data-count', imagecount);
});
},
}
}
}// JavaScript Document
function openImagePopup(id = null) {
$(".upload-images").show();
$.ajax({
url: 'fetch.php',
type: 'post',
data: {id: id},
dataType: 'json',
success:function(response) {
var imagecount = response.counts;
$('.dropzone').attr('data-count', imagecount);
}
});
}
HTML
<form action="data.php" class="dropzone files-container" data-count="">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
<input type="hidden" id="imageId" name="imageId">
</form>
UPDATED ANSWER
Once instanciated, the Dropzone plugin will remains with the same options unless you change the instance inner options directly.
To change options of a Dropzone, you can do this with the following line:
$('.dropzone')[0].dropzone.options.maxFiles = newValue;
$('.dropzone')[0] returns the first dropzone DOM element
.dropzone.options return the underlying plugin instance options of the Dropzone. You can now change any options directly on this object.
In you case, you will have to change the function that initiate the popup like follow
function openImagePopup(id = null) {
$(".upload-images").show();
$.ajax({
url: 'fetch.php',
type: 'post',
data: {id: id},
dataType: 'json',
success:function(response) {
var imagecount = response.counts;
$('.dropzone')[0].dropzone.options.maxFiles = imagecount;
}
});
}
And change the dropzone onSuccess event like this:
onyxDropzone.on("success", function(file, response) {
let parsedResponse = JSON.parse(response);
file.upload_ticket = parsedResponse.file_link;
var imagecount = $('.dropzone')[0].dropzone.options.maxFiles - 1;
$('.dropzone')[0].dropzone.options.maxFiles = imagecount;
});
As you can see, You can also remove the data-count="" attribute on you element and reuse the value from the plugin instance options.maxFiles
After spending a couple of hours of trials and errors I realized using the maxFiles setting from Dropzone is not exactly what is expected in many cases. That setting will only limit uploading files through the explorer / drag&drop, but after reload more files can be uploaded. It also does not reflect any failures to the upload on the serrver side (e.g. file size too big).
Changing the value of the maxFiles setting of an already initialized Dropzone from outside ot it is impossible. For example reseting the number of allowed files after removing some images with ajax will not work.
To really control the number of files that can be uploaded to the server the counting must take place on the server. Then in the Dropzone, in the success function, we should handle the ajax response:
success: function (file, response) {
var response_data = jQuery.parseJSON(response);
if(!response_data.success) {
$(file.previewElement).addClass('dz-error');
$(file.previewElement).addClass('dz- complete');
$(file.previewElement).find('.dz-error-message').text(response_data.error);
}
}
The response is the feedback information provided by the script assigned to the action attribute of the Dropzone <form>, e.g. <form action="/uploader">.
Related
I am using MVC.
I am having two drop down and one change of 'primaryspec' the 'primarysubspec' should get loaded.
Everything is working fine for passing values to controller and it got saved to DB.
When I am trying to retrieve the saved details,'primarysubspec' saved values are not getting displayed.
But displaying save data for 'primarySpec'.
Here is my .cshtml code:
#Html.DropDownListFor(m => m.PSpec, Model.PSpec, new { id = "ddUserSpec", style = "width:245px;height:25px;", data_bind = "event: {change: primaryChanged}" }, Model.IsReadOnly)
#Html.DropDownListFor(m => m.PSubspec, Model.PSubspec, new { id = "ddUserSubSpec", style = "width:245px;height:25px;", data_bind = "options: primarySubSpec,optionsText: 'Name',optionsValue: 'Id'" }, Model.IsReadOnly)
Here is my JS Code to retrieve the values for :
this.primarySubSpec = ko.observableArray([]);
this.primarySpecChanged = function () {
var val = $("#ddetailsPrimarySpec").val();
primarySubStartIndex = 0;
primarySubSpecialityUrl = '/PlatformUser/GetSpecandSubSpec?primarySpe=' + val+//model.primarySpecID() +'&secondarySpec=';
loadPrimarySubSpec();
};
function loadPrimarySubSpec() {
$.ajax({
type: 'GET',
url: primarySubSpecUrl,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
processdata: false,
cache: false,
success: function (data) {
primarySubSpec = [];
model.primarySubspec('0');
try {
if (data.length == 0) {
primarySubSpeacId.empty();
}
model.primarySubSpec(data);
},
error: function (request, status, error) {
primarySubSpeacId.prop("disabled", true);
}
});
}
Everything is working fine,but facing issue only while displaying the saved values from the DB.
Showing fine for 'primarySpec'
The values showing empty for 'PrimarySubSpec' instead of saved values in dropdown.
Please let me know what is the issue how can i show the saved value as selected value in 'primarySubSpec'dropdown.
The Problem:
when you load the page to view saved values, the change event is never called.
Why:
When your page is loaded with saved values, the select box has the saved value selected before knockout knows anything about it. Hens the change event isn't called.
Simplest solution:
change the primarySpecilaityChanged as follows
this.primarySpecilaityChanged = function () {
var val = $("#ddUserDetailsPrimarySpeciality").val();
if(val){
primarySubStartIndex = 0;
primarySubSpecialityUrl = '/' + NMCApp.getVirtualDirectoryName() + '/PlatformUser/GetSpecialitiesandSubSpecilaities?primarySpeciality=' + val+//model.primarySpecialityUID() +'&secondarySpeciality=';
loadPrimarySubSpecilaities();
}
};
then call primarySpecilaityChanged function after you call ko.applyBindings.
var viewModel = new YourViewModel();
ko.applyBindings(viewModel);
viewModel.primarySpecilaityChanged();
Trying to upload multiple files through ajax but after uploading its redirecting to another blank page automatically, showing only the name of upload files
Following is the html tag
Here is the javascript function
function upload(){
var projectId = document.getElementById("projectId").children[0].value;
var referenceNo = document.getElementById("referenceNo").value;
var createdBy = document.getElementById("initiatedBy").value;
if(projectId == null)
{
alert('Please select project first');
return;
}
var formData = new FormData();
var imageFiles = document.getElementById("fileId"),
filesLength = imageFiles.files.length;
for (var i = 0; i < filesLength; i++) {
document.write(imageFiles.files[i].name);
formData.append('files',imageFiles.files[i]);
}
$("#fileId").val('');
var methodName = 'uploadBPMFiles';
formData.append('refId',referenceNo);
formData.append('projectId',projectId);
formData.append('uploadedBy',createdBy);
formData.append('processType','EOT');
$.ajax({
url: webUrl+methodName,
data: formData,
processData: false,
type: 'POST',
cache:false,
dataType: "json",
contentType: false,
enctype : "multipart/form-data",
success: function(responseData) {
alert('success');
/**console.log('responseData: '+responseData);
console.log('responseData: '+responseData);
var obj = (responseData.downloadURLs);
console.log(obj)
for (var i in obj) {
console.log(obj[i]);
//$("response")World
//$('#response').append('Link');
}
//console.log($('#response').val());
//console.log('end');
**/
}
,
error: function (responseData) {
console.log('POST failed.');
}
});
}
Note: as document.write writes to the document stream, calling document.write on a closed (loaded) document automatically calls document.open which will clear the document.
document.write(imageFiles.files[i].name); will clear your document. You have to append a new Element with the names of your files to display them on your site. To do this you can create a new Element using jQuery
$("<span>").text(imageFiles.files[i].name).appendTo("body");
Actually I was writing the uploaded file names in document. So i've removed the below line
document.write(imageFiles.files[i].name);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
$(document).ready(function () {
$("#Button1").click(function (evt) {
var fileUpload = $('[id$=FileUpload1]')[0].value.split(",");
var data = new FormData();
for (var i = 0; i < fileUpload.length; i++) {
data.append(fileUpload[i].name, fileUpload[i]);
}
var options = {};
options.url = "Handler.ashx";
options.type = "POST";
options.data = data;
options.contentType = false;
options.processData = false;
options.success = function (result) { alert(result); };
options.error = function (err) { alert(err.statusText); };
$.ajax(options);
evt.preventDefault();
});
});
This was my jquery and below is my handler file code ......
till end i am getting value while debugging but in motto of making upload multiple images at a while i am unable to have any value in handle
handler code
public void ProcessRequest (HttpContext context) {
string filePath = "FileSave//";
foreach (string file in context.Request.Files)
{
HttpPostedFile filed = context.Request.Files[file];
filed.SaveAs(context.Server.MapPath(filePath + filed.FileName));
context.Response.Write("File uploaded");
}
}
You can try this way if you would like to.
$(document).ready(function () {
$("#Button1").click(function (evt) {
evt.preventDefault();
var formdata = new FormData();
var fileInput = $('#sliderFile'); //#sliderFile is the id of your file upload control
if ($(fileInput).get(0).files.length == 0)
{ //show error
return false;
}
else
{
$.each($(fileInput).get(0).files, function (index,value) {
formdata.append(value.name, value);
});
$.ajax({
url: 'Handler.ashx',
type: "POST",
dataType: 'json',
data: data,
processData: false,
contentType:false,
success: function (data) {
if (data.result) {
//return true or any thing you want to do here
}
else {
//return false and display error
}
},
error: function (data) {
//return false and display error
}
});
}
});//button click close
});//document.ready close
Try it and let me know
EDIT: Remember but, HTML5 FormData is not available in older browsers and your code will silently fail. If you need to support older browsers you might need to perform progressive enhancement by testing the capabilities of the browser and falling back to a standard form POST if the browser doesn't support FormData:
if(window.FormData === undefined) {
// The browser doesn't support uploading files with AJAX
// falling back to standard form upload
} else {
// The browser supports uploading files with AJAX =>
// we prevent the default form POST and use AJAX instead
e.preventDefault();
...
}
For more information on this you can see answer I have accepted for one of my questions. It's pretty much clear there what is the issue regarding. Here is the link
EDIT : Just adding these LINK1 and LINK2 for those who come looking for the answer.
use HttpContextBase[] instead of just HttpContext
I have an array called listArray() which contains two properties pageNumber and content.
The property content holds the container div html. This is useful because I have a pagination and I don't save that info into the database in real time, instead I insert into an array and only in the end is when I insert into the database.
$container = $('#container');
$.each(listArray, function(index, value){
// So, for each index in array
// it must empty the container
// to receive a new value
$container.empty();
$container.append(value.content); // value.content = pure html
html2canvas($container, {
height: $container.height() + 180,
onrendered: function(canvas) {
var data = canvas.toDataURL('image/png');
var file = dataURLtoBlob(data);
var formObjects = new FormData();
formObjects.append('file', file);
$.ajax({
url: 'ajax_saveImage',
type: 'POST',
data: formObjects,
processData: false,
contentType: false,
});
}
});
});
As you can see my final goal is to save two or three or even more images. My problem is that all the images are being saved BUT with the last index (of the array) content.
Solved.
The solution was not loop, but instead call the function the amount of times needed. The solution came to my mind after looking at this topic Looping html2canvas
var i = 0;
function saveIt(){
$container.empty();
if(i <= listArray.length - 1){
$container.append(listArray[i]['content']);
html2canvas($container, {
height: $container.height() + 180,
letterRendering: true,
onrendered: function(canvas) {
var data = canvas.toDataURL('image/png');
var file = dataURLtoBlob(data);
var formObjects = new FormData();
formObjects.append('file', file);
$.ajax({
url: 'ajax_saveImage',
type: 'POST',
data: formObjects,
processData: false,
contentType: false,
});
i++;
saveIt(); // Important! - call the function again
}
});
}
}
I'm trying to convert some of my code to reusable plugins.
Many times I'm filling selects with dynamic options that comes from Ajax request.
I've managed to create something like this:
$.fn.fillSelect = function fillSelect(options) {
var self = this;
options = $.extend({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Data.asmx/StatusList",
dataType: "json",
async: true,
success: function(data) {
var list = "";
$.each(data.d, function(i) {
list += '<option value='
+ data.d[i].ID + '>'
+ data.d[i].Nazwa
+ '</option>';
});
self.filter("select").each(function() {
$(this).empty();
$(this).append(list);
//use selectmenu
if ($.ui.selectmenu) $(this).selectmenu();
});
}//,
//error: function(result) {
// alert("Error loading data!");
//}
}, options);
$.ajax(options);
return self;
}
Idea behind this is to be able to fill multiple selects with the same data multiple times with one request.
I have default options for Ajax request, but I would like to add some more options to it.
For example:
clear - fill determinate if I want new options to replace existing ones or append.
Also I would like to add some callbacks to my function that I could pass as parameters.
If for example server request will fail I would like to specify a function that will be called after this error occurs - for example to show alert or disable my selects.
My question is how should I change my plugin or which pattern (boilerplate) I should use?
Every boilerplate I found is for creating plugins that will 'stay' inside selected item, so that it is possible to call method of that plugin later.
I need a simple plugin that will allow user to fill select and then it will end it's life :)
My main idea is to do only one request to server for all elements.
Here is jsfiddle demo: http://jsfiddle.net/JC7vX/2/
A basic plugin can be built as follows
(function ($){
$.fn.yourPlugin = function (options){
// this ensures that function chaining can continue
return this.each(function (){
// merge defaults and user defined options
var params = $.extend({},defaultOptions,options);
// your plugin code
});
}
/* these options will help define the standard functionality of the plugin,
* and also serves as a nice reference
*/
var defaultOptions = {
someProperty : true
}
})(jQuery)
There are other things that you can do to extend the functionality of your plugin and give public methods that retain the context, but that would be overkill for your example.
This is my version of answer http://jsfiddle.net/Misiu/ncWEw/
My plugin looks like this:
(function($) {
$.fn.ajaxSelect = function(options) {
var $this = this;
//options
var settings = $.extend({}, defaults, options);
//disable select
if ($.ui.selectmenu && settings.selectmenu && settings.disableOnLoad) {
$this.selectmenu('disable');
}
//ajax call
$.ajax({
type: settings.type,
contentType: settings.contentType,
url: settings.url,
dataType: settings.dataType,
data: settings.data
}).done(function(data) {
var n = data.d || data;
var list = "";
$.each(n, function(i) {
list += '<option value=' + n[i].Id + '>' + n[i].Nazwa + '</option>';
});
$this.filter("select").each(function() {
$(this).empty();
$(this).append(list);
if ($.ui.selectmenu && settings.selectmenu) {
$this.selectmenu();
}
settings.success.call(this);
});
}).fail(function() {
settings.error.call(this);
});
return this;
};
var defaults = {
type: "POST",
contentType: "application/json; charset=utf-8",
url: '/echo/json/',
dataType: 'json',
data: null,
async: true,
selectmenu: true,
disableOnLoad: true,
success: function() {},
error: function() {}
};
})(jQuery);
I understand that it is very simple, but it has all functionality that I needed:
-You can select multiple elements at one time
-It filters only selects from Your selected items
-It makes only one request to server
-First it builds option string and then append it instead of adding items in loop
-You can specify 2 callbacks: one for error and second for success
And it is my first plugin, so there is much places for improvements.
As always comments and hints are welcome!