From 9247009f1c0c12bd4d786d56787fa3130e47bf24 Mon Sep 17 00:00:00 2001 From: FinnStutzenstein Date: Fri, 20 Jan 2017 15:03:45 +0100 Subject: [PATCH] Csv export for IE (closes #2898) --- openslides/agenda/static/js/agenda/csv.js | 9 +++----- openslides/core/static/css/app.css | 2 +- openslides/core/static/js/core/csv.js | 25 +++++++++++++++++++++ openslides/core/static/js/core/site.js | 1 + openslides/motions/static/js/motions/csv.js | 14 ++++-------- openslides/topics/static/js/topics/csv.js | 9 +++----- openslides/users/static/js/users/csv.js | 19 +++++++--------- 7 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 openslides/core/static/js/core/csv.js diff --git a/openslides/agenda/static/js/agenda/csv.js b/openslides/agenda/static/js/agenda/csv.js index 4aeef07c1..e0347d4b4 100644 --- a/openslides/agenda/static/js/agenda/csv.js +++ b/openslides/agenda/static/js/agenda/csv.js @@ -7,7 +7,8 @@ angular.module('OpenSlidesApp.agenda.csv', []) .factory('AgendaCsvExport', [ 'HumanTimeConverter', 'gettextCatalog', - function (HumanTimeConverter, gettextCatalog) { + 'CsvDownload', + function (HumanTimeConverter, gettextCatalog, CsvDownload) { var makeHeaderline = function () { var headerline = ['Title', 'Text', 'Duration', 'Comment', 'Internal item']; return _.map(headerline, function (entry) { @@ -31,11 +32,7 @@ angular.module('OpenSlidesApp.agenda.csv', []) row.push('"' + (item.is_hidden ? '1' : '') + '"'); csvRows.push(row); }); - - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'agenda-export.csv'; - element.target = '_blank'; + CsvDownload(csvRows, element, 'agenda-export.csv'); }, }; } diff --git a/openslides/core/static/css/app.css b/openslides/core/static/css/app.css index acb7e3a8d..c5748092d 100644 --- a/openslides/core/static/css/app.css +++ b/openslides/core/static/css/app.css @@ -145,7 +145,7 @@ img { left: 0; width: 100%; height: 100%; - max-height: 356px; + max-height: 340px; z-index: 1000; } #spinner-container div { diff --git a/openslides/core/static/js/core/csv.js b/openslides/core/static/js/core/csv.js new file mode 100644 index 000000000..0e9ef32ff --- /dev/null +++ b/openslides/core/static/js/core/csv.js @@ -0,0 +1,25 @@ +(function () { + +'use strict'; + +angular.module('OpenSlidesApp.core.csv', []) + +.factory('CsvDownload', [ + function () { + return function (contentRows, element, fileName) { + if (navigator.msSaveBlob && typeof navigator.msSaveBlob === 'function') { + // Bad browsers + var blob = new Blob([contentRows.join('\r\n')]); + navigator.msSaveBlob(blob, fileName); + } else { // Good browsers + // %0A is the url encoded linefeed character. Needed to be + // percentage encoded for the data url. + element.href = 'data:text/csv;charset=utf-8,' + contentRows.join('%0A'); + element.download = fileName; + element.target = '_blank'; + } + }; + } +]); + +}()); diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index 1122eda61..154d4f1e4 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -6,6 +6,7 @@ angular.module('OpenSlidesApp.core.site', [ 'OpenSlidesApp.core', 'OpenSlidesApp.core.start', + 'OpenSlidesApp.core.csv', 'OpenSlidesApp.poll.majority', 'ui.router', 'colorpicker.module', diff --git a/openslides/motions/static/js/motions/csv.js b/openslides/motions/static/js/motions/csv.js index 910c7e1c4..b5ffdc16d 100644 --- a/openslides/motions/static/js/motions/csv.js +++ b/openslides/motions/static/js/motions/csv.js @@ -6,7 +6,8 @@ angular.module('OpenSlidesApp.motions.csv', []) .factory('MotionCsvExport', [ 'gettextCatalog', - function (gettextCatalog) { + 'CsvDownload', + function (gettextCatalog, CsvDownload) { var makeHeaderline = function () { var headerline = ['Identifier', 'Title', 'Text', 'Reason', 'Submitter', 'Category', 'Origin']; return _.map(headerline, function (entry) { @@ -31,11 +32,7 @@ angular.module('OpenSlidesApp.motions.csv', []) row.push('"' + motion.origin + '"'); csvRows.push(row); }); - - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'motions-export.csv'; - element.target = '_blank'; + CsvDownload(csvRows, element, 'motions-export.csv'); }, downloadExample: function (element) { var csvRows = [makeHeaderline(), @@ -44,10 +41,7 @@ angular.module('OpenSlidesApp.motions.csv', []) ['B1', 'Title 2', 'Text 2', 'Reason 2', 'Submitter B', 'Category B', '' ], ['' , 'Title 3', 'Text 3', '' , '' , '' , '' ], ]; - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'motions-example.csv'; - element.target = '_blank'; + CsvDownload(csvRows, element, 'motions-example.csv'); }, }; } diff --git a/openslides/topics/static/js/topics/csv.js b/openslides/topics/static/js/topics/csv.js index 01b9389e4..6d552f5f3 100644 --- a/openslides/topics/static/js/topics/csv.js +++ b/openslides/topics/static/js/topics/csv.js @@ -6,7 +6,8 @@ angular.module('OpenSlidesApp.topics.csv', []) .factory('TopicsCsvExample', [ 'gettextCatalog', - function (gettextCatalog) { + 'CsvDownload', + function (gettextCatalog, CsvDownload) { var makeHeaderline = function () { var headerline = ['Title', 'Text', 'Duration', 'Comment', 'Internal item']; return _.map(headerline, function (entry) { @@ -22,11 +23,7 @@ angular.module('OpenSlidesApp.topics.csv', []) ['Demo 2', 'Demo text 2', '1:30', '', ''] ]; - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'agenda-example.csv'; - element.target = '_blank'; - + CsvDownload(csvRows, element, 'agenda-example.csv'); }, }; } diff --git a/openslides/users/static/js/users/csv.js b/openslides/users/static/js/users/csv.js index 725acafde..9d12ad936 100644 --- a/openslides/users/static/js/users/csv.js +++ b/openslides/users/static/js/users/csv.js @@ -7,7 +7,8 @@ angular.module('OpenSlidesApp.users.csv', []) .factory('UserCsvExport', [ 'Group', 'gettextCatalog', - function (Group, gettextCatalog) { + 'CsvDownload', + function (Group, gettextCatalog, CsvDownload) { var makeHeaderline = function () { var headerline = ['Title', 'Given name', 'Surname', 'Structure level', 'Participant number', 'Groups', 'Comment', 'Is active', 'Is present', 'Is a committee']; @@ -21,24 +22,23 @@ angular.module('OpenSlidesApp.users.csv', []) makeHeaderline() ]; _.forEach(users, function (user) { + var groups = _.map(user.groups_id, function (id) { + return gettextCatalog.getString(Group.get(id).name); + }).join(','); var row = []; row.push('"' + user.title + '"'); row.push('"' + user.first_name + '"'); row.push('"' + user.last_name + '"'); row.push('"' + user.structure_level + '"'); row.push('"' + user.number + '"'); - row.push('"' + user.groups_id.join(',') + '"'); + row.push('"' + groups + '"'); row.push('"' + user.comment + '"'); row.push(user.is_active ? '1' : '0'); row.push(user.is_present ? '1' : '0'); row.push(user.is_committee ? '1' : '0'); csvRows.push(row); }); - - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'users-export.csv'; - element.target = '_blank'; + CsvDownload(csvRows, element, 'users-export.csv'); }, downloadExample: function (element) { @@ -62,10 +62,7 @@ angular.module('OpenSlidesApp.users.csv', []) ['', '', 'Executive Board', '', '', '', '', '', '', '1'], ]; - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'users-example.csv'; - element.target = '_blank'; + CsvDownload(csvRows, element, 'users-example.csv'); } }; }