CodeIgniter - Multiple file uploads using dynamic field generation - codeigniter

Im using a jquery script to add new file upload fields to my form dynamically, as a result, all my file fields look like so
<input class="file-input-area" name="mpfile[]" type="file" size="32" value="" />
So in other words, if i click the 'add more file upload' link 5 times, i get 5 file upload fields that look exactly as the one above.
Iam quite new to codeigniter and have done some research which tells me that if uploading multiple files, i should use the [] after the field name ... i hope this is right.
My problem now is figuring the process to upload the files, and store their names to a database table.
I have tried normal PHP uploading but it doesnt seem to be working, im not sure what to put in my view, controller and model.
If someone can give me an example of how they would go about it, it would help me so much.
Cheers,

Use jQuery uploadify. The files are uploaded asynchronously, see some demos here.
Here's an implementation:
jQuery('#images').uploadify({
'uploader' : '/uploadify/uploadify.swf',
'script' : '/uploadify/uploadify.php',
'cancelImg' : '/uploadify/cancel.png',
'folder' : '/data/images',
'auto' : true,
'fileExt' : '*.jpg;*.gif;*.png;*.jpeg;*.tif',
'fileDesc' : 'Web Image Files (.JPG, .GIF, .PNG, .JPEG, .TIF)',
'queueID' : 'images-queue',
'onCancel' : function(event,ID,fileObj,data) {
jQuery.ajax({
type: "POST",
url: "uploadify/delete_image.php",
data: "filepath=/data/images/" + jQuery("#"+ID).val(),
success: function(){
jQuery("#"+ID).remove();
queueSize = data.fileCount;
jQuery('#status-message').text('Photo uploaded!');
}
});
},
'onSelect' :function (event, ID) {
if (queueSize < maxQueueSize)
queueSize++;
else{
alert("Max number of files is " + maxQueueSize);
jQuery('#images').uploadifyCancel(ID);
return false;
}
},
'onSelectOnce' : function(event,data) {
jQuery('#status-message').text('File is currently uploaded...');
},
'onComplete': function (evt, queueID, fileObj, response, data) {
jQuery('#status-message').text('H φωτογραφία φορτώθηκε!');
jQuery("#field_photos").append("<input id="+ queueID +" type='hidden' name='pics[]' value='" + response + "' />"); //adds hidden form field
},
'onAllComplete' : function(event,data) {
},
'onClearQueue' : function (a, b) {
queueSize = 0;
},
'multi' : true,
'simUploadLimit' : 3,
'removeCompleted': false,
'sizeLimit' : 1048576,
'queueSizeLimit' : 1
});
With this line:
jQuery("#field_photos").append("<input id="+ queueID +" type='hidden' name='pics[]' value='" + response + "' />"); //adds hidden form field
we store the filenames in the hidden array field "pics". When your form is submitted, you read these names using $this->input->post('pics') and store them into your database.

Related

Is FormData object required with Vuejs to upload file to laravel backend?

Is the FormData object absolutely necessary to work with files and to upload them to my backend made with laravel?
Secondly, would it be a good practice to wrap all form inputs in a FormData object, even non file input?
Currently I try this
<input type="file" #change="onVideoSelected" name="explenationVideo">
My method logic:
onVideoSelected(event) {
this.form.video = event.target.files[0];
}
My data structure
data() {
return {
form: {
name : '',
contentType : 'video',
imageGroup : [],
video : null,
difficulty : '',
}
}
}
And when I submit
axios.post('/backoffice/exercises', this.form)
.then(({data}) => {
this.messages.push('Exercice ajouté!');
});
But when I try to view the detail in the backend like
dd($request->file('video'));
I have a null value.

Filling a form in JSP with ajax

I know this kind of questions has already been asked, but I totally am a newbie with Ajax and JavaScript.
I have a field (codigo_caso) which I need to be the launcher for the form filling
<input id="codigo_caso" autofocus="autofocus" type="text" name="codigo_caso" value=""/>
I have to retrieve 4 variables after loosing focus on that field (or 1 variable if the other 4 are empty)
And the big problem after retrieving those 4 variables is how to work well with them.
JSP Web Page --> Script
This is the fragment i copied from the internet and modified to receive ONE field
$(document).ready(function() {
$("#codigo_caso").blur(function() {
var cod = $(this).val();
var dataString1 = {"codigo":cod};
$.ajax({
type: "GET",
url: "otros/codigoCasoDependienteNuevaTarea.jsp",
datatype: "json",
contentType: "application/json; charset=utf-8",
data: dataString1,
cache: false,
success: function(response) {
$(".linea_equipo").response("linea_equipo");
$("#selectArea").filter(function() {
return $(this).response("id_area") === response("area");
}).prop('selected', true);
$(".listaCentros").response("nombre_centro");
$("#listaRolNuevaTarea").filter(function() {
return $(this).response("id_rol") === response("rol");
}).prop('selected', true);
}
});
});
});
This is my JSP file launching the SQL [where i need to recover several variables]. I need to know how to return these 3 fields to my previous JSP
JSP FILE --> otros/codigoCasoDependienteNuevaTarea.jsp
String linea = "", centro = "", error = "No existe el caso indicado";
int area, rol;
Connection conex = (Connection) session.getAttribute("conexion");
Statement st = conex.createStatement();
String sql = "";
String cod = request.getParameter("codigo").toString();
if (cod != null && !cod.isEmpty() && !cod.equals("0")) {
sql = "SELECT t1.linea_equipo,t1.id_rol, t2.id_area,t2.nombre_centro "
+ " FROM gen_casos_prisma t1 LEFT OUTER JOIN gen_centros t2 ON "
+ " t1.id_centro = t2.id_centro "
+ " WHERE "
+ " t1.CODIGO_CASO = " + cod;
ResultSet rs = st.executeQuery(sql);
rs.beforeFirst();
if (rs.next()) {
linea = rs.getString("linea_equipo");
area = rs.getInt("id_area");
centro = rs.getString("nombre_centro");
rol = rs.getInt("id_rol");
JSONObject j = new JSONObject();
j.put("linea_equipo", linea);
j.put("id_area", area+"");
j.put("nombre_centro", centro);
j.put("id_rol", rol+"");
} else {
/* return variable error */
}
response.setContentType("application/json");
}
The next step after knowing how to receive these fields is to know what to do with them. i know how can i place linea_equipo in a text-field [with the code I posted in the script above the JAVA code] but i also need to set as "selected" one option in each of these lists (two are dropdown lists and the other is a datalist) taking into account that they are already filled; just need to place selected attribute in the value that matches the field that the form must receive from this ajax-jsp thing.
(selectArea - id_area, listaCentrosDeArea - nombre_centro, listaRolNuevaTarea - id_rol)
<select id="selectArea" >
<%out.print(f.getSelectAreas(conex));%>
</select>
<datalist id="listaCentrosDeArea" id="datalist1">
<% //out.print(f.selectCentrosNOUser(conex, updateTarea));%>
</datalist>
<select id="listaRolNuevaTarea" name="rol">
<% out.print(f.selectRolesNoUser(conex));%>
</select>
Sorry if it seems a bit tricky or heavy, but I've been requested to do this and I have no idea.
when you are doing
success: function(html) {
("#linea_equipo").val(html);
}
you are returning the value to the JSP, so just make sure that all the elements that you want filled in have an id like linea_equipo
In the success part of your code you can write the logic to populate data to your form.
success: function(response)
{
$("#ID").val("value");//find these value from your response
// if your response is JSON you can replace value like response.key
}
see what json is
For selecting a drop down by jQuery use
$('#dropdownid').val('selectedvalue');
//========
code to return response as json in java servlet
response.setContentType("application/json");
response.getWriter().write(jsonobject.toString());

Displaying uploaded files from server in dropzone js

I am using the dropzone js plugin to upload files to a php server. It is working great. I am facilitating the user to update the uploaded files. So once the user clicks on update button, the dropzone appears, and I am able to display the uploaded files in it through a JQuery-AJAX call. But my problem is that though the files are displayed in the thumbnail format, the number of files in the dropzone counts to zero. I feel that the accept function is not being triggered.But if a new file is added to the displaying list the file count is 1 though there are files already existing in it.
I am using the following code to display the files in dropzone:
var mockFile = { name: "Filename", size: 12345 };
myDropzone.options.addedfile.call(myDropzone, mockFile);
myDropzone.options.thumbnail.call(myDropzone, mockFile, "/image/url");
Can anyone help me solve this?
I think you need to push the mockFile in the dropZone manually like this
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("complete", mockFile);
myDropzone.files.push(mockFile);
It's work for me... if you need more code just ask!
Mock file is not uploaded as explained here https://github.com/enyo/dropzone/issues/418
If you want to submit the form use myDropzone.uploadFiles([]); in init()
$('input[type="submit"]').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
var form = $(this).closest('#dropzone-form');
if (form.valid() == true) { //trigger ASP.NET MVC validation
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
myDropzone.uploadFiles([]);
}
}
});
example for U!
jQuery(function($) {
//文件上传
$(".dropzone").dropzone({
url : "pic_upload.jsp?id=<%=request.getParameter("id")%>",
addRemoveLinks : true,
dictRemoveLinks : "x",
dictCancelUpload : "x",
maxFiles : 5,
maxFilesize : 5,
acceptedFiles: "image/*",
init : function() {
//上传成功处理函数
this.on("success", function(file) {
alert("修改前:"+file.name);
});
this.on("removedfile", function(file) {
alert("File " + file.name + "removed");
//ajax删除数据库的文件信息
$.ajax({
type:'post',
url:'pic_delete.jsp?id='+file.name ,
cache:false,
success:function(data){
}
});
});
<%
if(null!=list){
for(PlaceImg img:list){%>
//add already store files on server
var mockFile = { name: "<%=img.getId()%>", size: <%=img.getFilesize()%> };
// Call the default addedfile event handler
this.emit("addedfile", mockFile);
// And optionally show the thumbnail of the file:
this.emit("thumbnail", mockFile, "<%=img.getImgUrl()%>");
<%}
}%>
}
});

AntiForgeryToken not being received when using plupload in form submission

I'm using Plupload to allow multiple images to be uploaded to an mvc3 web app.
the files upload OK, but when i introduce the AntiForgeryToken it doesn't work, and the error is that no token was supplied, or it was invalid.
I also cannot get the Id parameter to be accepted as an action parameter either, it always sends null. So have to extract it myself from the Request.UrlReferrer property manually.
I figure plupload is submitting each file within the upload manually and forging its own form post.
My form....
#using (#Html.BeginForm("Upload", "Photo", new { Model.Id }, FormMethod.Post, new { id = "formUpload", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Id)
<div id="uploader">
<p>You browser doesn't have HTML5, Flash or basic file upload support, so you wont be able to upload any photos - sorry.</p>
</div>
<p id="status"></p>
}
and the code that wires it up...
$(document).ready(function ()
{
$("#uploader").plupload({
// General settings
runtimes: 'html5,flash,html4',
url: '/Photo/Upload/',
max_file_size: '8mb',
// chunk_size: '1mb',
unique_names: true,
// Resize images on clientside if we can
resize: { width: 400, quality: 100 },
// Specify what files to browse for
filters: [
{ title: "Image files", extensions: "jpg,gif,png" }
],
// Flash settings
flash_swf_url: 'Content/plugins/plupload/js/plupload.flash.swf'
});
$("#uploader").bind('Error', function(up, err)
{
$('#status').append("<b>Error: " + err.code + ", Message: " + err.message + (err.file ? ", File: " + err.file.name : "") + "</b>");
});
// Client side form validation
$('uploadForm').submit(function (e)
{
var uploader = $('#uploader').pluploadQueue();
// Validate number of uploaded files
if (uploader.total.uploaded == 0)
{
// Files in queue upload them first
if (uploader.files.length > 0)
{
// When all files are uploaded submit form
uploader.bind('UploadProgress', function ()
{
if (uploader.total.uploaded == uploader.files.length)
$('form').submit();
});
uploader.start();
} else
alert('You must at least upload one file.');
e.preventDefault();
}
});
});
and here is the controller action that receives it...
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(int? id, HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var parts = Request.UrlReferrer.AbsolutePath.Split('/');
var theId = parts[parts.Length - 1];
var fileName = theId + "_" + Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
return Content("Success", "text/plain");
}
As you can see, i have had to make the id parameter nullable, and i extract this manually in the action method.
How can i ensure that the values are sent with each form post correctly?
short answer : YES!
use multipart_params options like this:
multipart_params:
{
__RequestVerificationToken: $("#modal-dialog input[name=__RequestVerificationToken]").val()
}
short answer: you can't.
What you can do in this case is pass your token either as another multipart paramenter (if using that), or as part of the URL as a GET parameter, but nothing from the form will be sent by plupload as it builds its own request.
Another possibility is using custom headers to pass back the token to the server (plupload has a headers option), but whichever is the method you use, you will have to process it on your backend to validate it.

Problem running multiple instances of a plugin

I developed a simple plugin to sent request to a JSON text file, retrieve a data containing image list and append the html in the element calling the plugin.
Now, the code is working fine while it is running on only one element, but when I am using it on more than one element, now the elements get loaded on the last element calling the plugin only.
Plugin Code:
$.fn.testPlugin = function(param) {
var options = {
url : "",
pause : 2000,
callback : 5000
};
this.each(function() {
elementId = $(this).attr("id");
options = $.extend(options,param);
if(options.url=="") { console.log("URL is not specified"); }
else {
$.post(
options.url,
function(data) {
$("#"+elementId).html("<ul></ul");
$.each(data.dashboard, function(k,v) {
html = '<li>';
html += '<a href="'+v.TargetUrl+'" target="'+v.Target+'">';
html += '<img src="' + v.ImageUrl + '" alt="' + v.Alt +'" title="' + v.OverlayText +'" />';
html += '</a><p>'+v.OverlayText+'</p></li>';
$("ul",$("#"+elementId)).append(html);
});
},
"json"
);
}
});
}
Plugin Initialization/Execution
$("#this").testPlugin({
url: 'test.txt'
});
$("#that").testPlugin({
url: 'text.txt'
});
HTML
<div id="this" style="border-style: solid;border-color: #09f;padding: 10px;">
This is a sample div.
</div>
<div id="that" style="border-style: solid;border-color: #09f;padding: 10px;">
Another div
</div>
UPDATE
I also found out that the problem is happening due to AJAX request. If I create static list and then append it on the div, this time this works with any number of instantiation. A demo of static call is here. Now, help me do the same by retrieving the list from an AJAX request.
UPDATE 2
Thanks to Groovek, Here is a demo of the actual problem. You can notice, that the elements of both requests are append to the last element.
You're assigning to elementID without declaring it. This means it'll be a global variable, which means it'll always be equal to the last thing assigned to it (in this case, #that). If you just keep a local reference to the element, the code will work. Here's a modified jsfiddle: http://jsfiddle.net/s9BDT/
Code inside the each 'loop':
var el = $(this);
el.html("<ul></ul>");
options = $.extend(options,param);
if(options.url=="") { console.log("URL is not specified"); }
else {
$.post(
//options.url,
"/echo/json/",
{json:'{"dashboard":[{"TargetUrl":"toto.html", "Alt" : "sample 1", "ImageUrl":"toto.png", "OverlayText":"toto"},{"TargetUrl":"titi.html", "Alt" : "sample 2", "ImageUrl":"titi.png", "OverlayText":"titi" }]}'},
function(data) {
//alert(data.dashboard);
html = '';
$.each(data.dashboard, function(k,v) {
html += '<li>';
html += '<a href="'+v.TargetUrl+'" target="'+v.Target+'">';
html += '<img src="' + v.ImageUrl + '" alt="' + v.Alt +'" title="' + v.OverlayText +'" />';
html += '</a><p>'+v.OverlayText+'</p></li>';
});
//alert(html);
$("ul",el).append(html);
},
"json"
);
}

Resources