📄 multifileitem.js
字号:
return (this.foreignKeyValues && !isc.isAn.emptyObject(this.foreignKeyValues));},setForeignKeyValues : function (foreignKeyValues) { this.foreignKeyValues = foreignKeyValues;},clearData : function () { var forms = this.getForms(); for (var i = 0; i < forms.length; i++) this.removeUploadField(forms[i]); // preallocate the desired number of file upload fields for (var i = 0; i < this.minUploadFields; i++) this.addUploadField();},// add another upload form, called via buttonaddUploadField : function () { var form = this.createAutoChild("uploadForm", { dataSource: this.dataSource, cellPadding: 0, numCols: 1, colWidths: ['*'], width: 250, elementChanged : function () { this.Super("elementChanged", arguments); this.picker.dataChanged(); } }, isc.DynamicForm); var uploadFormLayout = this.createAutoChild("uploadFormLayout", { members: [form], height: 21 }, isc.HLayout); this.uploadLayout.addMember(uploadFormLayout); if (this.showUploadRemoveButton) { var removeButton = this.createAutoChild("uploadRemoveButton", { form: form, picker: this, contents: isc.emptyString, cursor: isc.Canvas.HAND, icon: "[SKIN]MultiFileItem/icon_remove_files.png", // title: "Remove", click: "this.picker.removeUploadField(this.form, true)", iconSpacing : 6, width: 22, // 16px icon + 6px icon spacing height: 20 }, isc.Label); uploadFormLayout.addMember(removeButton, 0); } if (this.maxUploadFields && this.maxUploadFields <= this.uploadLayout.getMembers().length) this.addAnotherFileButton.hide();},// remove one of the uploaded fields, called from buttonremoveUploadField : function (form, reAddToMin) { if (form._queueNum) { isc.rpc.cancelQueue(form._queueNum); this.transactionNum = null; if(this.progressMeter) this.progressMeter.hide(); } form.parentElement.destroy(); if (reAddToMin && this.uploadLayout.getMembers().length < this.minUploadFields) { this.addUploadField(); } if (this.maxUploadFields && this.maxUploadFields > this.uploadLayout.getMembers().length) { this.addAnotherFileButton.show(); } this.dataChanged();},// get all the forms in the editorgetForms : function () { return this.uploadLayout.getMembers().map("getMember", this.showUploadRemoveButton ? 1 : 0);},// observabledataChanged : function () {},hide : function () { this.Super("hide", arguments); this.hideClickMask();},// get data for display in the list of filesgetData : function () { var data = []; var forms = this.getForms(); for (var i = 0; i < forms.length; i++) { var form = forms[i]; var values = form.getValues(); // skip forms with no values (empty upload fields) if (isc.isAn.emptyObject(values)) continue; // store a pointer back to the form on the values object values._form = form; data[data.length] = values; } return data;},// save the first non-empty upload form. We upload each file serially, waiting for a server// response before proceeding to the next file by calling this method again.// Note that we could upload a maximum of two files at once (based on the HTTP 1.1 limit of 2// connections per server), but that would prevent any other kind of traffic, eg, progress// checks.saveData : function (callback) { if (!callback) callback = this.saveCallback; if (!callback) callback = this.getID()+".hide()"; this.saveCallback = callback; var forms = this.getForms(); // client or server validation error may have occurred, but we have the master record, so let // the user correct the problem and save. this.saveButton.setTitle(this.uploadWithPKButtonName); // find the first form with values // remove all forms with no values var form; var fileName; while (forms.length > 0) { form = forms[0]; fileName = form.getFields()[0].getValue(); if (!fileName) { this.removeUploadField(form); forms.remove(form); } else break; } if (forms.length == 0) { // done saving forms if (this.progressMeter) { this.progressMeter.hide(); } this.transactionNum = null; delete this.saveCallback; this.fireCallback(callback); this.clearData(); return; } if (!form.validate()) return; if (!this.progressMeter) { this.progressMeter = this.createAutoChild("progressMeter", { progressCheckFrequency : this.progressCheckFrequency }); this.addMember(this.progressMeter, 0); } fileName = fileName.replace(/.*(\\|\/)/g, isc.emptyString); this.progressMeter.setFileName(fileName); this.progressMeter.hideProgressBar(); this.progressMeter.show(); if (this.hasKeys()) { for (var key in this.foreignKeyValues) form.setValue(key, this.foreignKeyValues[key]); } var dsRequest = form.saveData(this.getID()+".saveDataCallback(dsRequest, dsResponse, data)", { params: {formID : form.getID(), singleUpload: "true"}, // we want to be notified of an error so we can kill the progressCheck thread willHandleError: true, form: form, showPrompt: false, saveDataCallback: callback, timeout: 0 } ); this.transactionNum = dsRequest.transactionNum; form._queueNum = this.transactionNum; this.progressCheck(form.getID(), this.transactionNum);},// called when we get a server response to an upload attempt. If it succeeded, proceeds to// upload next file.saveDataCallback : function (dsRequest, dsResponse, data) { var form = dsRequest.form; // if there was an error, kill the progressCheck thread if (dsResponse.status != isc.RPCResponse.STATUS_SUCCESS) { this.progressMeter.hide(); this.transactionNum = null; if (dsResponse.status == isc.RPCResponse.STATUS_VALIDATION_ERROR) { form.setErrors(dsResponse.errors, true); } else { isc.warn(data); } // form didn't save - bail out and let the user correct any errors return; } // the form saved successfully - remove it from the list form._queueNum = null; // don't cancelQueue() this.removeUploadField(form); // save the next form this.saveData(dsRequest.saveDataCallback); if (this.callingFormItem.fileUploaded) { this.callingFormItem.fileUploaded(dsRequest, dsResponse); }},// check the progress of a file upload via a DMI performed in parallel to the upload itself.// Calling progressCheck sets up a periodic polling of the server until all uploads completeprogressCheck : function (formID, origTransactionNum) { this.lastProgressCheckTime = new Date().getTime(); isc.DMI.callBuiltin({ methodName: "uploadProgressCheck", callback: this.getID()+".progressCallback(rpcRequest, rpcResponse, data, "+origTransactionNum+")", arguments: formID, requestParams : {willHandleError: true, showPrompt: false, formID: formID} });},progressCallback : function (rpcRequest, rpcResponse, data, origTransactionNum) { // delayed progess callback - upload may have completed var formID = rpcRequest.formID; var form = window[formID]; if (!form || this.transactionNum !== origTransactionNum) return; // assume transient failure - retry request immediately (single server failure in a server farm // is a common reason for this) if (rpcResponse.status != isc.RPCResponse.STATUS_SUCCESS) this.progressCheck(formID); // server reports validation errors - typically file too large. if (data.errors) { isc.rpc.cancelQueue(this.transactionNum); form.setErrors(data.errors, true); this.saveButton.show(); this.transactionNum = null; this.progressMeter.hide(); return; } this.progressMeter.setFileSize(data.totalBytes); // if the total size of the file is less than the configured amount for which we would show // a progress bar, just return - no further requests will be made for this file. if (data.totalBytes < this.minFileSizeForProgressBar) { this.progressMeter.hideProgressBar(); return; } // file is large enough for us to show a progress meter. Show it and schedule the next progressCheck this.progressMeter.setBytesReceived(data.bytesSoFar); this.progressMeter.showProgressBar(); this.progressMeter.setPercentDone(100 * data.bytesSoFar / data.totalBytes); var checkDelay = this.progressCheckFrequency - (new Date().getTime() - this.lastProgressCheckTime); if (checkDelay < 0) checkDelay = 0; this.delayCall("progressCheck", [formID, origTransactionNum], checkDelay);}});//!<Deferred// progress meter for reporting on progress of uploaded filesisc.defineClass("MultiFileProgressMeter", "VStack").addClassMethods({formatBytes : function (fileSize) { var suffix; if (fileSize < 1024) { fileSize = Math.round(fileSize/1024); suffix = "B"; } else if(fileSize < (1024*1024)) { fileSize = Math.round(fileSize/1024); suffix = "KB"; } else { fileSize = Math.round(fileSize/(1024*1024)*100)/100; suffix = "MB"; } return fileSize+" "+suffix;}});isc.MultiFileProgressMeter.addProperties({ height: 50});//!>Deferredisc.MultiFileProgressMeter.addMethods({initWidget : function () { this.Super("initWidget", arguments); this.addAutoChild("progressLabel", { height: 1, dynamicContentsVars: { progressMeter: this }, dynamicContents: true, contents: "<b><nobr>Saving ${progressMeter.fileName} ${progressMeter.getFormattedFileSize()}</nobr></b>" }, "Canvas");},setFileName : function (fileName) { this.fileName = fileName; delete this.fileSize; this.bytesSoFar = 0; this.bytesReceived = 0; this.progressLabel.markForRedraw(); if (this.progressBar) this.setPercentDone(0);},setFileSize : function (fileSize) { this.fileSize = fileSize; this.progressLabel.markForRedraw();},setBytesReceived : function (bytesReceived) { this.bytesSoFar = this.bytesReceived;; this.bytesReceived = bytesReceived; this.progressLabel.markForRedraw();},getFormattedFileSize : function () { if (!this.fileSize) return isc.emptyString; var result = "<br>"; if (this.bytesReceived) { result += isc.MultiFileProgressMeter.formatBytes(this.bytesReceived) + " of "; } result += isc.MultiFileProgressMeter.formatBytes(this.fileSize); if (this.bytesSoFar && this.progressCheckFrequency) { var delta = this.bytesReceived - this.bytesSoFar; delta = isc.MultiFileProgressMeter.formatBytes(delta * 1000 / this.progressCheckFrequency); result += " (" + delta + "/sec)"; } return result;},showProgressBar : function () { this.addAutoChild("progressBar", { overflow: "visible" }, "Progressbar"); this.progressBar.show();},hideProgressBar : function () { if (this.progressBar) this.progressBar.hide();},setPercentDone : function (percentDone) { this.progressBar.setPercentDone(percentDone);}});//!<Deferred}// Make old name available as a synonymisc.addGlobal("MultiUploadItem", isc.MultiFileItem);isc.addGlobal("MultiUploadPicker", isc.MultiFilePicker);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -