Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ecc4b0c2

Von Sven Schöling vor mehr als 3 Jahren hinzugefügt

  • ID ecc4b0c2ef75ebb81706fe00e61956e602ac13c4
  • Vorgänger b5a5c7f6
  • Nachfolger 90aba193

ImageUpload: local storage erste Version

Unterschiede anzeigen:

SL/Controller/ImageUpload.pm
my ($self) = @_;
$::request->layout->add_javascripts('kivi.File.js');
$::request->layout->add_javascripts('kivi.FileDB.js');
$::request->layout->add_javascripts('kivi.ImageUpload.js');
$self->render('image_upload/form');
$self->render('image_upload/local_list');
}
################# internal ###############
js/kivi.FileDB.js
namespace("kivi.FileDB", function(ns) {
"use strict";
const database = 'kivi';
const store = 'files';
const db_version = 1;
// IndexedDB
const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB;
// Create/open database
let db;
let request = indexedDB.open(database, db_version);
request.onupgradeneeded = (event) => {
ns.create_image_store(event.target.result);
};
request.onerror = ns.onerror;
request.onsuccess = () => {
db = request.result;
db.onerror = (event) => {
console.error("Error creating/accessing IndexedDB database");
console.error(event);
};
// Interim solution for Google Chrome to create an objectStore. Will be deprecated
if (db.setVersion) {
if (db.version != db_version) {
let setVersion = db.setVersion(db_version);
setVersion.onsuccess = () => {
ns.create_image_store(db);
};
}
}
};
ns.create_image_store = function (db) {
db.createObjectStore(store, { autoIncrement : true });
};
ns.store_image = function (blob, filename, success) {
let put_request = ns.open_store("readwrite").add(blob, filename);
put_request.onsuccess = success;
put_request.on_error = ns.onerror;
};
ns.retrieve_image = function(key, success) {
let get_request = ns.open_store().objectStore(store).get(key);
get_request.onsuccess = success;
get_request.onerror = request.onerror;
};
ns.retrieve_all = function(success) {
let request = ns.open_store().getAll();
request.onsuccess = (event) => { success(event.target.result); };
request.onerror = ns.error;
};
ns.retrieve_all_keys = function(success) {
let request = ns.open_store().getAllKeys();
request.onsuccess = (event) => { success(event.target.result); };
request.onerror = ns.error;
};
ns.delete_all= function() {
ns.retrieve_all_keys((keys) => {
keys.forEach((key) => ns.delete_key(key));
});
};
ns.delete_key= function(key, success) {
let request = ns.open_store("readwrite").delete(key);
request.onsuccess = (event) => { if (success) success(event.target.result); };
request.onerror = ns.error;
};
ns.open_store = function(mode = "readonly") {
return db.transaction([store], mode).objectStore(store);
};
ns.onerror = (event) => {
console.error("Error creating/accessing IndexedDB database");
console.error(event.errorState);
};
});
js/kivi.ImageUpload.js
namespace("kivi.ImageUpload", function(ns) {
"use strict";
ns.add_files = function(target) {
let files = [];
for (var i = 0; i < target.files.length; i++) {
files.push(target.files.item(i));
}
kivi.FileDB.store_image(files[0], files[0].name, () => {
ns.reload_images();
target.value = null;
});
};
ns.reload_images = function() {
kivi.FileDB.retrieve_all((data) => {
$('#stored-images').empty();
data.forEach(ns.create_thumb_row);
});
};
ns.create_thumb_row = function(file) {
let URL = window.URL || window.webkitURL;
let file_url = URL.createObjectURL(file);
let $row = $("<div>").addClass("row image-upload-row");
let $button = $("<a>")
.addClass("btn-floating btn-large waves-effect waves-light red")
.click((event) => ns.remove_image(event, file.name))
.append($("<i>delete</i>").addClass("material-icons"));
$row.append($("<div>").addClass("col s3").append($button));
let $image = $('<img>').attr("src", file_url).addClass("materialboxed responsive-img");
$row.append($("<div>").addClass("col s9").append($image));
$("#stored-images").append($row);
};
ns.remove_image = function(event, key) {
let $row = $(event.target).closest(".image-upload-row");
kivi.FileDB.delete_key(key, () => {
$row.remove();
});
};
ns.upload_selected_files = function(id,type,filetype,maxsize) {
kivi.FileDB.retrieve_all((myfiles) => {
let filesize = 0;
myfiles.forEach(file => {
filesize += file.size;
if (filesize > maxsize) {
$("#upload_result").html(kivi.t8("filesize too big: ") + filesize+ kivi.t8(" bytes, max=") + maxsize );
return;
}
let data = new FormData();
data.append(file);
data.append("action", "File/ajax_files_uploaded");
data.append("json", "1");
data.append("object_type", type);
data.append("object_id", id);
data.append("file_type", filetype);
$("#upload_result").html(kivi.t8("start upload"));
$.ajax({
url: "controller.pl",
data: data,
success: ns.attSuccess,
progress: ns.attProgress,
error: ns.attFailes,
abort: ns.attCanceled
});
});
});
};
ns.attProgress = function(event) {
if (event.lengthComputable) {
var percentComplete = (event.loaded / event.total) * 100;
$("#upload_result").html(percentComplete+" % "+ kivi.t8("uploaded"));
}
};
ns.attFailed = function() {
$('#upload_modal').modal('close');
$("#upload_result").html(kivi.t8("An error occurred while transferring the file."));
};
ns.attCanceled = function() {
$('#upload_modal').modal('close');
$("#upload_result").html(kivi.t8("The transfer has been canceled by the user."));
};
ns.attSuccess = function() {
$('#upload_modal').modal('close');
$("#upload_result").html(kivi.t8("Files have been uploaded successfully."));
};
ns.init = function() {
ns.reload_images();
};
});
$(kivi.ImageUpload.init);
js/kivi.Materialize.js
ns.init = function() {
ns.reinit_widgets();
}
};
ns.build_i18n = function(locale) {
ns.build_i18n = function() {
return {
months: [
kivi.t8('January'),
......
// Accessibility labels
labelMonthNext: kivi.t8('Next month'),
labelMonthPrev: kivi.t8('Previous month')
}
}
};
};
ns.reinit_widgets = function() {
$('.sidenav').sidenav();
......
i18n: ns.build_i18n()
});
$('.modal').modal();
$('.materialboxed').materialbox();
M.updateTextFields();
}
};
// alternative for kivi.popup_dialog.
// opens materialize modal instead.
//
// differences: M.modal can not load external content, so it needs to be fetched manually and inserted into the DOM.
ns.popup_dialog = function(params) {
console.log(params);
params = params || { };
let id = params.id || 'jqueryui_popup_dialog';
let $div;
......
// unlike classic layout, there is not fixed size, and M.modal is always... modal
onCloseStart: custom_close
},
// User supplied options:
// User supplied options:
params.dialog || { },
{ // Options that must not be changed:
// close options already work
......
params.data = undefined;
ns.popup_dialog(params);
},
error: function(x, status, error) { console.log(error); },
error: function(x, status, error) { console.error(error); },
dataType: 'text',
});
return 1;
......
if (params.html) {
$div = $('<div>');
$div.attr('id', id)
$div.attr('id', id);
$div.addClass("modal");
let $modal_content = $('<div>');
$modal_content.addClass('modal-content');
......
$div.append($modal_content);
$('body').append($div);
kivi.reinit_widgets();
dialog_params.onCloseEnd = function() { $div.remove(); }
dialog_params.onCloseEnd = function() { $div.remove(); };
$div.modal(dialog_params);
} else if(params.id) {
$div = $('#' + params.id);
} else {
......
$div.modal('open');
return true;
};
/**
* upload file to local storage for later sync
*
* should be used with P.M.file_upload(..., local=>1)
*/
ns.LocalFileUpload = function(options) {
this.storage_token = options.storage_token; // used in localstorage to retrieve the file
this.dom_selector = options.dom_selector; // file inputs to listen on
this.init();
};
ns.LocalFileUpload.prototype = {
init: function() {
$(this.dom_selector).change(this.handle_file_upload);
},
handle_file_upload: function() {
},
load_files: function() {
return JSON.parse(localStorage.getImte(this.storage_token));
},
save_files: function() {
return JSON.parse(localStorage.getImte(this.storage_token));
},
};
}
});
package.json
{
"name": "dev",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"doc": "doc"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kivitendo/kivitendo-erp.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/kivitendo/kivitendo-erp/issues"
},
"homepage": "https://github.com/kivitendo/kivitendo-erp#readme"
}
templates/mobile_webpages/image_upload/local_list.html
[%- USE LxERP -%] [%- USE L %]
[%- USE HTML %]
[%- USE P %]
[%- USE T8 %]
<h4>[% source.title | html %]</h4>
<div id="updoad_result"></div>
<div id="stored-images" class="container">
</div>
<div class="container">
<div class="row">
<div class="file-field input-field col">
<div class="btn m3 s12">
<span>[% 'Upload Image' | $T8 %]</span>
<input
name="uploadfiles[]" type="file" [% IF multiple %]multiple[% END %]
id="upload_files" accept="[% SELF.accept_types %]" capture="camera"
onchange="kivi.ImageUpload.add_files(this)">
</div>
<div class="file-path-wrapper m9 s12">
<input class="file-path validate" type="hidden">
</div>
</div>
</div>
<div class="row">
[% P.M.input_tag("object_number", "", label=LxERP.t8("Number")) %]
[% P.M.button_tag("submit", LxERP.t8("Upload")) %]
</div>
</div>
</div>
<div id="upload_modal" class="modal">
<div class="modal-content">
<h4>Uploading</h4>
<p>A bunch of text</p>
</div>
</div>

Auch abrufbar als: Unified diff