Difficulty understanding code which retrieves a filename from a file control - javascript

I have this code in a project. I understand that it outputs the file from a file input control. The issue is that I don't understand the working of var filename = e.target.files[0].name. Please help me out, if you can.
$(document).ready(function() {
$('input[type="file"]').change(function(e) {
var fileName = e.target.files[0].name;
$('#choose').html(fileName);
});
});

Breaking the line e.target.files[0].name down in to sections:
e is the Event object passed to the jQuery event handler function as an argument.
target is the property which contains a reference to the element which raised the event
files is a collection of the files selected within the input type="file" control. If the control has the multiple attribute set on it, it's possible for there to be more than 1 file selected, in which case you would need a loop.
[0] retrieves only the first selected file from the files collection - in the same manner as you access an array by index.
name gets the filename of that file.

Related

Filepond with multiple instances on one page: only the last instance uploads correctly

I am using Filepond, an otherwise amazing plugin, but when I try to place multiple instances on the same page, only the last instance uploads correctly. All the other ones display correctly, but only upload to the "tmp" folder: the files never making it to the "uploads" folder.
The code I'm using is the following, that was actually found in a previous SO question (the only difference is my "define server location" at the end):
How do I set up multiple FilePond file input elements on the same page?
Here it is:
<input type="file" class="filepond">
<input type="file" class="filepond">
<input type="file" class="filepond">
<script>
// get a collection of elements with class filepond
const inputElements = document.querySelectorAll('input.filepond');
// loop over input elements
Array.from(inputElements).forEach(inputElement => {
// create a FilePond instance at the input element location
FilePond.create(inputElement);
// define the server location
FilePond.setOptions({
server: 'http://localhost:8080/wp12-fidusalaire/wp-content/plugins/one-shot-form/',
});
})
</script>
Thank you dearly!
Sorry that this answer is coming late. Just do it like this below
const inputElements = document.querySelectorAll('input.filepond');
// loop over input elements
Array.from(inputElements).forEach(inputElement => {
const pond = FilePond.create(inputElement, options);
// define the server location
pond.setOptions({
server: 'http://localhost:8080/wp12-fidusalaire/wp-content/plugins/one-shot-form/',
});
});

CKEditor Plug-In: Getting text of drop-down item

I created a plug-in for CKEditor that opens a dialog with a drop-down. In that drop-down is a list of files the user has uploaded outside of CKEditor. The plan is to insert a "tag" into the text containing that filename, something like [[myfile.pdf]] and then when I display the actual page, I will insert a link to that file.
The problem is that the drop-down box being created by CKEditor is listing the filename (properly) but when I select it, it inserts the file's SIZE into the text rather than the filename. When the plug-in runs, it does an ajax call and grabs a directory listing of the user's files, which is where that number comes from; I think it's confusing it with a file ID.
Here's the meat of the plug-in. I left out the ajax call for brevity. It populates the variable "items."
EDIT: I modified the results returned from the ajax call to just return the filename, and then to return the filename (twice) using two different column names (name and filename) and in both cases, the inserted value was NULL. It just doesn't want to insert a text value it seems.
I also tried changing the values of id: under contents and also under elements (alternately) between tab-basic and linkType, and I got an error in the JS console about cannot read property getValue of undefined. Curses, foiled again!
ANOTHER EDIT: I tried putting the names of the files in a database table and I return that to the plug-in instead of the directory listing. If I select filename, attachmentid (in that order), the OPTION box lists the attachmentid, and inserts the filename. If I select attatchmentid, filename it will do it the exact opposite. So then I thought, gee, what if I selected the filename twice? So I did select filename, filename as filename2. And it works! This still isn't an ideal solution so I'm hoping somebody will know the proper way to do it.
CKEDITOR.dialog.add('attachfileDialog',function(editor){
return {
title:'Attach File',
minWidth:400,
minHeight:200,
contents:[{
id:'tab-basic',
label:'Choose File',
elements:[{
type:'select',
id:'linkType',
label:'Choose File',
items:items,
'default':''
}]
}],
onOk:function(data){
var dialog = this;
var componentType = dialog.getValueOf('tab-basic','linkType');
var selectedText = editor.getSelection().getSelectedText();
if(componentType != ''){
editor.insertText('[[' + componentType + ']]');
}
}
};
});
I actually copied this from another plug-in and modified it to suit, so I'll admit I don't much know what I'm doing here. I've dug through the CKEditor docs but they aren't particularly helpful.
The variable componentType is coming back with the file size. I'm just not sure how to make it grab the text instead of the value; if you view the source, the has the value of the file size, and the text is the filename.
Any ideas? Thank you!

Jquery exporting table to csv hidden table cells

I need to be able to export a HTML table to CSV. I found a snippet somewhere; it works but not entirely how I want it to.
In my table (in the fiddle) I have hidden fields, I just use quick n dirty inline styling and inline onclicks to swap between what you see.
What I want with the export is that it selects the table as currently displayed. so only the td's where style="display:table-cell". I know how to do this in normal JS.
document.querySelectorAll('td[style="display:table-cell"])');
but how can I do this using the code I have right now in the exportTableToCSV function?
(sorry but the text in the fiddle is in dutch as its a direct copy of the live version).
The fiddle:
http://jsfiddle.net/5hfcjkdh/
In your grabRow method you can filter out the hidden table cells using jQuery's :visible selector. Below is an example
function grabRow(i, row) {
var $row = $(row);
//for some reason $cols = $row.find('td') || $row.find('th') won't work...
//Added :visisble to ignore hidden ones
var $cols = $row.find('td:visible');
if (!$cols.length) $cols = $row.find('th:visible');
return $cols.map(grabCol)
.get().join(tmpColDelim);
}
Here's how i solved it. Decided to step away from a pure javascript solution to take processing stress off the client and instead handle it server side.
Because i already get the data from the database using a stored procedure i use this to just get the dataset again and convert it into an ViewExportModel so i have a TotalViewExport and a few trimmed variations (reuse most of them) based on a Selected variable i fill a different model.
Added to the excisting show function to update a Selected variable to keep track of the currently selected view.
When the user clicks Export table to excel it calls to the controller of the current page, IE. AlarmReport (so AlarmReportController) and i created the action ExportReports(int? SelectedView);
In addition i added CsvExport as a manager. This takes data results (so c# models/ iqueryables/ lists/ etc). and puts them into a Csv set. using the return type BinaryContent one can export a .csv file with this data.
The action ExportReports calls the stored procedure with the selectedview parameter. The result gets pumped into the correct model. this model is pumped into the CsvExport model as rows.
The filename is made based on the selected view + What object is selected + current date(yyyy-MM-dd). so for example "Total_Dolfinarium_2016-05-13". lets
lastly the action returns the .csv file as download using the BinaryContent Returntype and ExportToBytes from the CsvExport
The export part of this action is programmed like so(shortened to leave some checks out like multiple objects selected etc)(data and objectnames are gathred beforehand):
public ActionResult ExportCsv(CsvExport Data, string ObjectName, string Type){
var FileName = Type + "_" + ObjectName + "_" + DateTime.Now.ToString("yyyy/MM/dd");
return BinaryContent("text/csv", FileName + ".csv", Data.ExportToBytes());
}

fine-uploader unique but ascending ID in filename on submit and cancel

this issue relates to Widen Fine-Uploader ( https://github.com/Widen/fine-uploader )
i got this multipart upload form. no autoupload. i want to upload a couple of images and safe them under an unique name for each image.
eg. you pick 4 images. upload via fine-upload. i already got a gallery id. all images should be saved under a filename using the gallery-id and an unique ascending number. like this:
1234-1.jpg
1234-2.jpg
1234-3.jpg
1234-4.jpg
sounds easy, but there are two problems:
the image-id needs to be ascending without skipping any one. That may happen, if you cancel (remove) a file before upload. so the image-id needs to be set up AFTER selecting all files OR it needs to fill up empty IDs on removing a file.
the order of the images must be strictly adhered to the order you choose files on input. the first image you pick, becomes 1234-1.jpg, the second one 1234-2.jpg ... so i'm not able to set the ID at the imageHandler script after reload. It would grab the first complete image that must not be the first image in order, because i use several simultaneous connections on upload.
I tried something like that:
.on('submitted', function(event, id, name) {
var picId = id+1;
$(this).fineUploader('setParams', {
'currentGid': 1234,
'picId':picId
});
})
or
params: {
fileNum: function() {
return $(this).attr('id');
}
}
or using a fileCount++ but nothing works like i need..
Your application sounds a bit brittle, and it is probably in your best interests to address that.
You'll simply need to maintain a map of your unique ids along with the ids maintained for each file by Fine Uploader. In your "submitted" handler, add a key/value pair to the map. In a "cancel" handler, adjust the items in the map appropriately. In an "upload" handler, call the "setParams" API method. Your parameters will by the gallery ID, the unique ID you've been tracking in your map for that specific file, and be sure to pass the id of the file as your last parameter to the "setParams" call. This lets Fine Uploader know that this parameter is only for that specific file.
Please see the callbacks documentation for more info.
Here's a code example:
var fileIds = [];
$('#myFineuploaderContainer').fineUploader({
//set your options here
})
.on('submitted', function(event, id, name) {
fileIds.push(id);
})
.on('cancel', function(event, id, name) {
var fileIdPosition = $.inArray(id, fileIds);
fileIds.splice(fileIdPosition, 1);
})
.on('upload', function(event, id, name) {
var params = {
currentGid: 1234,
picId: $.inArray(id, fileIds)
};
$(this).fineUploader('setParams', params, id);
});

Expression Engine Extension Development - Add custom javascript to rendered entry

I'm working on an extension and one of the options available in the settings needs a custom javascript to be added to the document head when rendered. The problem I am having is with the parsing order. (There may also be a better way of doing the include too)
I am using the channel_entries_tagdata hook.
Inside this, once the settings are processed, I am doing the following:
// Add the required javascript
$jscript = "
<script type="text/javascript">
/*! etc......
</script></head>
";
// Add js
$tagdata = str_replace("</head>", $jscript, $tagdata);
I would like to be able to just keep my javascript in a separate file and include it somehow by reference, but I don't know how to do that at this stage.
The other issue I am running into is the parsing order of the EE variables. Inside the javascript, I am using the variables from the $tagdata. Something like this:
$.post("URL", { channel: "{channel}", entryId: "{entry_id}", urlTitle: "{url_title}", lastSegment: "{last_segment}", editDate: eo.editDate, field: eo.eleName }, function(data){...
How would I call/use the EE variables in this case?
Elaborated...
This extension is for the following:
In the Addons -> Extensions from the control panel, they will activate the extension. In the 'Settings' for that extension, they will be able to authorize, by Channel, the members or groups that can 'edit' entries in that channel.
The extension, after checking permissions, edits each custom field type before it is rendered and wraps it in a class element. The JavaScript file is for this functionality next. When that element is clicked, a modal is opened which will contain the custom field type as well as the channel/entry information, so it can save the field once edited.
Could you let the script in the <head> be a generic function and pass variables to it by calling it from inside your channel entries?
<head>
...
<script>
function W3bGuy_function(channel, entry_id, last_segment) {
...whatever...
}
</script>
</head>
<body>
...
{exp:channel:entries}
some action triggers: W3bGuy_function('{channel}', '{entry_id}', '{segment_3}');
{/exp:channel:entries}
...
channel_entries_tagdata contains the raw template code pulled from within each {exp:channel:entries} loop, and then has another variable ($row) which is an array of the actual data for that entry. (As per the docs.)
So first, you'll have to make sure your entire page template is within your Channel Entries loop if you want to add JS to the <head> in this manner - and that may not work if your <head> is inside an embed.
Second, I'd suggest dumping the $row data that's passed via that hook, to see if you can extract your data in your returned JS from there.
Hope that helps.

Categories

Resources