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

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);
});

Related

couchdb views: return all fields in doc as map

I have a doc in couchDB:
{
"id":"avc",
"type":"Property",
"username":"user1",
"password":"password1",
"server":"localhost"
}
I want to write a view that returns a map of all these fields.
The map should look like this: [{"username","user1"},{"password","password1"},{"server","localhost"}]
Here's pseudocode of what I want -
HashMap<String,String> getProperties()
{
HashMap<String,String> propMap;
if (doc.type == 'Property')
{
//read all fields in doc one by one
//get value and add field/value to the map
}
return propMap;
}
I am not sure how to do the portion that I have commented above. Please help.
Note: right now, I want to add username, password and server fields and their values in the map. However, I might keep adding more later on. I want to make sure what I do is extensible.
I considered writing a separate view function for each field. Ex: emit("username",doc.username).
But this may not be the best way to do this. Also needs updates every time I add a new field.
First of all, you have to know:
In CouchDB, you'll index documents inside a view with a key-value pair. So if you index the property username and server, you'll have the following view:
[
{"key": "user1", "value": null},
{"key": "localhost", "value": null}
]
Whenever you edit a view, it invalidates the index so Couch has to rebuild the index. If you were to add new fields to that view, that's something you have to take into account.
If you want to query multiple fields in the same query, all those fields must be in the same view. If it's not a requirement, then you could easily build an index for every field you want.
If you want to index multiple fields in the same view, you could do something like this:
// We define a map function as a function which take a single parameter: The document to index.
(doc) => {
// We iterate over a list of fields to index
["username", "password", "server"].forEach((key, value) => {
// If the document has the field to index, we index it.
if (doc.hasOwnProperty(key)) {
// map(key,value) is the function you call to index your document.
// You don't need to pass a value as you'll be able to get the macthing document by using include_docs=true
map(doc[key], null);
}
});
};
Also, note that Apache Lucene allows to make full-text search and might fit better your needs.

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());
}

Filter a model within a range of IDs with Ember.JS

I have store that contains all of the images that the user has uploaded over time. When they upload a new group of images I receive each image's ID from the uploader. They are then moved to a new route where they need to update those newly uploaded images with meta data. I would like to use the previous store but filter out everything except the images they have uploaded.
So the question is... How do I filter a store by only a range of ids. For example, if my uploader returns [30, 31, 32]. I would like the view to only display those images.
I think the router should have a filter property like this but I'm not sure.
App.PhotosDetailsRoute = Ember.Route.extend( {
model: function(params) {
return this.get('content').filterBy('id', id >= params[0] );
}
});
Any help would be appreciated.
You'll want to use the filter function, I'm not positive what content is in this case, but this is how you use filter
model: function(params) {
this.store.find('photos');
return this.store.filter('photos', function(item){
return item.get('id') >= 10; // dummy parameter
});
}

Using jQuery to pull text from a specific <td>

I'm running an AJAX query on an external page, and am attempting to only return the data from the County . My current script is pulling the text from all of the table cells, but I cannot for the life of me get it to simply pull the county name.
The current script that is being run:
$( ".zipCode" ).each(function( intIndex ){
var zipCodeID = $(this).attr('id');
console.log('http://www.uscounties.org/cffiles_web/counties/zip_res.cfm?zip='+zipCodeID);
$.ajax({
url: 'http://www.uscounties.org/cffiles_web/counties/zip_res.cfm?zip='+zipCodeID,
type: 'GET',
success: function(res) {
var headline = $(res.responseText).find("p").text();
console.log(headline);
$('#'+zipCodeID).empty();
$('#'+zipCodeID).append(headline);
}
});
});
An example of the page that is being queried:
http://www.uscounties.org/cffiles_web/counties/zip_res.cfm?zip=56159
This should work for all entered ZIPS. The page layout is the same, I just can't get the function to return only the county. Any help or advice would be awesome. Thanks!
With the complete lack of ids and classes on that page, you don't really have much to go on. If you have access to the source of that page, stick an id or class on the cell and make your life so much easier. If not, you'll have to use what you know about the structure of the pages to find the county. Something like this will work specifically on that one page you linked to. If other pages have slight variations this will fail:
var headline = $(res.responseText).find("table > tr:eq(2) > td:eq(3)").text();
This assumes that there is only ever one table on the page and that the county is always in the 3rd cell of the 2nd row.
You're basically screen scraping. I somehow think you'll have issues with this due to cross domain and other things, but that is ancillary to the question.
You need to walk through the resultant page. Assuming there is only ever one page on the screen, it'll look like something this:
var retVal = [];
// Basically, for each row in the table...
$('tr').each(function(){
var pTR = $(this);
// Skip the header row.
if (pTR.find('th').length == 0)
{
// This is the array of TDs in the given row.
var pCells = $('td', pTR);
retVal.push({state:$(pCells[0]).text(), place:$(pCells[1]).text(), county:$(pCells[2]).text()});
}
});
// retVal now contains an array of objects, including county.
if (retVal.length > 0)
{
alert(retVal[0].county);
}
else
{
alert('Cannot parse output page');
}
The parsing code is written to be extensible, hence you get back all of the data. With postal codes, although you will likely only ever get back one county, you'll definitely get back more places. Also note... not every zip code has a county attached for a variety of reasons, but you should get back an empty string in that case.

Categories

Resources