Dropzone.js progressbar not updating on emit using s3.managedUpload - dropzone.js

I found a couple of examples on how to do AWS uploads with dropzone.js testing them independently and now I'm trying to combine them into a finished form for our website's image uploader.
The one example I found showed that you could trigger progress updates from the S3.managedUpload as follows:
file.s3upload.on('httpUploadProgress', function(progress) {
if (progress.total) {
var percent = ((progress.loaded * 100) / progress.total);
console.log('httpUploadProgress', percent, progress.loaded);
myDropzone.emit('uploadprogress', file, percent, progress.loaded);
}
});
With my console.log in there, I can see multiple loops of the httpUploadProgress with increasing percentage. But the {dropzone}.emit doesn't seem to update the progress bar.
I've tried using the external 'myDropzone' var as well as making my AWSSendFile function (where the above code is included) as a prototype of dropzone itself so I can refer to it with this.emit(). No luck.
The dropzone template is:
dropzoneTemplate:'
<div class="Item dropzone-previews">
<div class="Icon"><img data-dz-thumbnail /></div>
<div class="Description dz-preview dz-file-preview">
<span class="Filename" data-dz-name ></span><br/>
<div class="dz-progress"><span class="dz-upload dz-progress" data-dz-uploadprogress ></span></div>
</div>
</div>'
Full code with the prototyped functions:
// override the uploadFiles function to send via AWS SDK instead of xhr
Dropzone.prototype.uploadFiles = function (files) {
for (var j = 0; j < files.length; j++) {
var file = files[j];
this.AWSsendFile(file);
}
};
Dropzone.prototype.AWSsendFile = function(file) {
let dz = this;
file.s3upload.send(function(err, data) {
if (err) {
dz.emit("error", file, err.message);
} else {
dz.emit("complete", file);
}
});
// listen to the AWS httpUploadProgress event, and emit an equivalent Dropzone event
file.s3upload.on('httpUploadProgress', function(progress) {
if (progress.total) {
var percent = ((progress.loaded * 100) / progress.total);
console.log('httpUploadProgress', percent, progress.loaded);
dz.emit('uploadprogress', file, percent, progress.loaded);
}
});
};
function acceptCallback(file, done) {
// options for the managed upload for this accepted file
// define the bucket, and the S3 key the file will be stored as
let fullKey = userId + "/" + file.name;
let params = {
Bucket: bucket,
Key: fullKey,
Body: file,
Region: 'us-east-2'
};
// add an S3 managed upload instance to the file
file.s3upload = new AWS.S3.ManagedUpload({params: params});
done();
};
function abortUpload(file) {
if (file.s3upload) file.s3upload.abort();
};
example console.log data:
httpUploadProgress 97.33840304182509 49152
httpUploadProgress 100 50496
UPDATE:
I noticed one problem with the async embedded callbacks and modified the 'prototyped' functions above to show my changes. Setting a local variable for dz = this to hold the handle of the main dropzone object. This makes the progress bar work hunky-dory and it now goes to 100%, but now the 'complete' emit call doesn't seem to be telling it to show as complete.

Related

Dart component progress bar only updating at the end of loop

I'm developing an app in angular dart and trying to animate a progress bar which shows progress of a file upload. I'm simply parsing the JSON from the file, and sending them off to a service with a _service.create(....) method.
I've put all of this code in an async method which is called when my submit button is clicked:
void uploadFile() async {
submitButton.attributes.addAll({ 'disabled': '' });
progress.value = 0;
FileList files = input.files;
if (files.isEmpty) {
_handleError("No file selected");
//handle error, probably a banner
return;
}
File file = files.item(0);
FileReader reader = new FileReader();
//reader.result
reader.onLoadEnd.listen((e) async {
Map map = json.decode(reader.result);
var combinations = map['combinations'];
progress.max = combinations.length;
int loopCount = 0;
combinations.forEach((e) async {
await _service.create(VJCombination.fromJSON(e)).then((_) {
combinationCount++;
progress.value++;
loopCount++;
if (loopCount == combinations.length) {
submitButton.attributes.remove('disabled');
}
});
});
isLoadSuccessful = true;
});
reader.onError.listen((evt) => print(evt));
reader.readAsText(file);
progress.value = 10;
}
I'm getting the progress and the submitButton elements with the #ViewChild annotations:
#ViewChild('progress')
ProgressElement progress;
#ViewChild('submit')
ButtonElement submitButton;
The code works. The progress bar starts off empty, and after the file is read and the service gets the data, the progress bar is full.
My issue is that the UI is only updated after all of the combinations have been sent to the _service. So it seemingly goes from empty to full in one frame.
This code
combinations.forEach((e) async {
does not make sense, because forEach does not care about the returned Future
Rather use
for(var e in combinations) {
Not sure if this fixes your problem, but such code definitely needs to be changed.

Add vimeo event listeners for multiple videos on same page

I have multiple Vimeo videos iframes on the same page. So I want to add event listeners for all the iframes. But somehow it is not working for me.
here is the code which I add on document.ready.
var iframes = document.querySelectorAll('iframe');
var player;
//loop through all and add event
for (i = 0; i < iframes.length; i++) {
// when vimeo player is ready add other events
player = $f(iframes[i]);
player.addEvent('ready', function () {
player.addEvent('play', onPlay);
player.addEvent('pause', onPause);
});
function onPlay(el) {
console.log('play');
}
function onPause(el) {
console.log('pause');
}
}
I get all the iframes in variable 'iframes', it also loops through all and add ready event. But cannot add play and pause events. Where am I going wrong?
The following code would help you with attaching events to your frames.
<script>
$(document).ready(function () {
var x = document.querySelectorAll("iframe");
var nodelist = x.length;
alert(nodelist);
for (i = 0; i < nodelist; i++) {
var player = new Vimeo.Player(x[i]);
player.on('play', function () {
console.log('played the video!');
});
player.on('ended', function () {
console.log('ended the video!');
});
}
});
</script>
Actually multiple videos play/pause issue as mentioned in my question got solved using froogaloop2.js. I am not writing any extra code for this now as specified by me in question. and my iframe src url does not append api=1 param.

Google apps script UI services to HTML services

I try to convert this simple google apps script code below to HTML services code.
The code below is written with the deprecated google apps script UI services!
Can anyone help me with HTML services example code in this usecase?
// Script with deprecated UI-services
// How to create this app with HTML-services?!!!?
//This script runs in a google website.
//It has one textobject and 1 button.
//when the button is pressed the value entered is stored in the spreadsheet
ssKey = 'sheetkey....';
function doGet(){
var app = UiApp.createApplication().setTitle('myApp');
//Create panels en grid
var MainPanel = app.createVerticalPanel();
var Vpanel1 = app.createVerticalPanel().setId('Vpanel2');
var grid = app.createGrid(4, 2).setId('myGrid');
//Vpanel1 widgets
var nameLabel = app.createLabel('Name');
var nameTextBox = app.createTextBox().setWidth('400px').setName('name').setId('name');
var submitButton = app.createButton('Verstuur').setId('submitButton');
grid.setWidget(0, 0, nameLabel)
.setWidget(0, 1, nameTextBox)
.setWidget(1, 1, submitButton);
//Set handlers en callbackelement
var handler = app.createServerClickHandler('InsertInSS');
handler.addCallbackElement(Vpanel1);
submitButton.addClickHandler(handler);
// build screen
Vpanel1.add(grid);
app.add(Vpanel1);
return app;
}
function InsertInSS(e){
var app =UiApp.getActiveApplication();
var collectedData = [new Date(), e.parameter.name] ;
var SS = SpreadsheetApp.openById(ssKey);
var Sheet = SS.getSheetByName('Contacts');
Sheet.getRange(Sheet.getLastRow()+1, 1, 1, collectedData.length).setValues([collectedData]);
app.getElementById('submitButton').setVisible(false);
//Reset fields on screen
app.getElementById('name').setText("");
return app;
}
Your Ui output looks like this:
Create an HTML file, and enter this code:
testForm.html
<div>
<div>
Name: <input id='idNameField' type='text'/>
</div>
<br/>
<input type='button' value='Verstuur' onmouseup='runGoogleScript()'/>
</div>
<script>
function onSuccess(argReturnValue) {
alert('was successful ' + argReturnValue);
//Reset fields on screen
Document.getElementById('idNameField').value = "";
}
function runGoogleScript() {
console.log('runGoogleScript ran!');
var inputValue = document.getElementById('idNameField').value;
google.script.run.withSuccessHandler(onSuccess)
.InsertInSS(inputValue);
};
</script>
Copy the follow code into:
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('testForm')
.evaluate() // evaluate MUST come before setting the NATIVE mode
.setTitle('The Name of Your Page')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
};
In a seperate .gs file add this code:
function InsertInSS(argPassedInName){
var ssKey = 'sheetkey....';
var SS = SpreadsheetApp.openById(ssKey);
var Sheet = SS.getSheetByName('Contacts');
Sheet.getRange(Sheet.getLastRow()+1, 1, 1, argPassedInName.length).setValue(argPassedInName);
}

Timeline Schedule Pages events - Servicenow

I'm starting to work using servicenow, and I've an issue with TimeLines and the doubleClick events.
I configured the schedule page and ScriptInclude (code as pseudo-code):
Schedule Page
glideTimeline.setReadOnly(true); glideTimeline.showLeftPane(true);
glideTimeline.registerEvent("getItems", "MyTimelineScriptInclude");
function doubleClickCustomFunction(evt) {
try {
alert('double click: ' + "evt: " + evt + ', target: ' + target );
action.setRedirectURL( 'my_application.do?sys_id=' + target );
catch (exception) {
gs.log(exception);
}
},
MyTimelineScriptInclude
var MyTimelineScriptInclude = Class.create();
MyTimelineScriptInclude.prototype = Object.extendsObject(AbstractTimelineSchedulePage, {
_getTickets: function(){
tickets = foo();
return tickets;
}
getItems: function() {
try {
var ticket_list = this._getTickets();
for (var ticket in ticket_list) {
this._representTicket(ticket_list[ticket].sys_id);
}
} catch(exception) {
this._debugLog(exception, "getItemsException");
}
},
_representTicket: function(sys_id) {
// ticket Object;
ticket_object = getTicket(sys_id);
var timelineItem = new TimelineItem('my_application' , ticket_object.sys_id);
_representSpans( timelineItem , ticket_object );
this.add(timelineItem);
},
_representSpans: function( timelineItem , ticket_object ) {
var timelineItemSpan1 = timelineItem.createTimelineSpan(''); // I'm not including any value into the span creator.
timelineItemSpan1.setTimeSpan( ticket_object.startDateTime1.getNumericValue() , ticket_object.endDateTime1.getNumericValue() );
timelineItemSpan1.setSpanText(ticket_object.spanText);
timelineItemSpan1.setSpanColor(ticket_object.spanColor);
timelineItemSpan1.setTooltip(ticket_object.spanTooltip);
var timelineItemSpan2 = timelineItem.createTimelineSpan(''); // I'm not including any value into the span creator.
timelineItemSpan2.setTimeSpan( ticket_object.startDateTime2.getNumericValue() , ticket_object.endDateTime2.getNumericValue() );
timelineItemSpan2.setSpanText(ticket_object.spanText);
timelineItemSpan2.setSpanColor(ticket_object.spanColor);
timelineItemSpan2.setTooltip(ticket_object.spanTooltip);
var timelineItemSpan3 = timelineItem.createTimelineSpan(''); // I'm not including any value into the span creator.
timelineItemSpan3.setTimeSpan( ticket_object.startDateTime2.getNumericValue() , ticket_object.endDateTime2.getNumericValue() );
timelineItemSpan3.setSpanText(ticket_object.spanText);
timelineItemSpan3.setSpanColor(ticket_object.spanColor);
timelineItemSpan3.setTooltip(ticket_object.spanTooltip);
},
});
The problem is when I double click on a timeline row, it triggers the doubleClickCustomFunction, but, it isn't able to get any evt data, so, It doesn't performs the redirection.
Best regards
 
Schedule Pages in ServiceNow use client-side script, so if the doubleClickCustomFunction is part of the schedule page client script, the server-side calls (action.setRedirect and gs.log) will fail.
The default double click function contains the following parameters: event, this, strRecordSysID, strUserSysID
I haven't used a custom doubleclick override, so I'm not sure if these parameters are automatically available. However, this is the case for other custom overrides written within the script include, such as elementMoveX
Other than that, you might try calling window.event within the function if it is a part of the client script

Adding events is not working correctly

I'm trying to add an event for all elements with "p" tag.
But instead of adding an event script colors all links in red
<script>
//create links
var code = ""
for (i=0;i<10;i++){
code += "<p><a href='#'>Link " + i + "</a></p>"
}
document.getElementById('links').innerHTML = code;
//add Events
for(i=0;i<document.getElementsByTagName("p").length;i++){
document.getElementsByTagName("p")[i].onmouseover = document.getElementsByTagName("p")[i].childNodes[0].style.color="green"
document.getElementsByTagName("p")[i].onmouseout = document.getElementsByTagName("p")[i].childNodes[0].style.color="red"
}
}
</script>
There is My code
Event handlers need to be functions. So you need something like this:
document.getElementsByTagName("p")[i].onmouseover = function() {
// You don't want to use i in a function in a loop since i will
// be different by the time the function gets called
// this is document.getElementsByTagName("p")[i]
this.childNodes[0].style.color="green"
}
You should probably also create the nodeList for the <p> tags outside of the loop so you're not traversing the DOM each time.
var paras = document.getElementsByTagName('p');
for(i=0;i<paras.length;i++){
paras[i].onmouseover = function() { /* */ };
paras[i].onmouseout = function() { /* */ };
}

Resources