From 308e8d63793761460b9d2a50d6f815403e106d83 Mon Sep 17 00:00:00 2001 From: Jörn Friedrich Dreyer Date: Thu, 8 May 2014 15:25:46 +0200 Subject: replace chosen with select2 to provide ajaxified user and group selection for files_external, fixes #7499 remove minified select2 js show avatars for users, simpler results remove unneeded users and groups from settings template fix css, escape user and group names --- apps/files_external/js/settings.js | 147 ++++++++++++++++++++++++++++++++++--- 1 file changed, 138 insertions(+), 9 deletions(-) (limited to 'apps/files_external/js/settings.js') diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 8a1bb2bec6f..69e99c03c89 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -42,9 +42,11 @@ OC.MountConfig={ } }); if ($('#externalStorage').data('admin') === true) { - var multiselect = $(tr).find('.chzn-select').val(); + var multiselect = $(tr).find('.applicableUsers').select2('val'); if (multiselect == null) { return false; + } else if (multiselect instanceof Array && multiselect.length === 0) { + multiselect.push('all'); } } if (addMountPoint) { @@ -166,8 +168,139 @@ OC.MountConfig={ }; $(document).ready(function() { - $('.chzn-select').chosen(); + //initialize hidden input field with list of users and groups + $('#externalStorage').find('tr:not(#addMountPoint)').each(function(i,tr) { + var applicable = $(tr).find('.applicable'); + if (applicable.length > 0) { + var groups = applicable.data('applicable-groups'); + var groupsId = []; + $.each(groups, function () { + groupsId.push(this+"(group)"); + }); + var users = applicable.data('applicable-users'); + if (users.indexOf('all') > -1) { + $(tr).find('.applicableUsers').val(''); + } else { + $(tr).find('.applicableUsers').val(groupsId.concat(users).join(',')); + } + } + }); + + var userListLimit = 30; + function addSelect2 ($elements) { + if ($elements.length > 0) { + $elements.select2({ + placeholder: t('files_external', 'All users. Type to select user or group.'), + allowClear: true, + multiple: true, + //minimumInputLength: 1, + ajax: { + url: OC.generateUrl('apps/files_external/applicable'), + dataType: 'json', + quietMillis: 100, + data: function (term, page) { // page is the one-based page number tracked by Select2 + return { + pattern: term, //search term + limit: userListLimit, // page size + offset: userListLimit*(page-1), // page number starts with 0 + }; + }, + results: function (data, page) { + if (data.status === "success") { + + var results = []; + var userCount = 0; // users is an object + + // add groups + $.each(data.groups, function(i, group) { + results.push({name:group+'(group)', displayname:group, type:'group' }); + }); + // add users + $.each(data.users, function(id, user) { + userCount++; + results.push({name:id, displayname:user, type:'user' }); + }); + + + var more = (userCount >= userListLimit) || (data.groups.length >= userListLimit); + return {results: results, more: more}; + } else { + //FIXME add error handling + } + } + }, + initSelection: function(element, callback) { + var promises = []; + + var results = []; + + $(element.val().split(",")).each(function (i,userId) { + var def = new $.Deferred(); + promises.push(def.promise()); + + var pos = userId.indexOf('(group)'); + if (pos !== -1) { + //add as group + results.push({name:userId, displayname:userId.substr(0, pos), type:'group'}); + def.resolve(); + } else { + $.ajax(OC.generateUrl('apps/files_external/applicable'), { + data: { + pattern: userId + }, + dataType: "json" + }).done(function(data) { + if (data.status === "success") { + if (data.users[userId]) { + results.push({name:userId, displayname:data.users[userId], type:'user'}); + } + def.resolve(); + } else { + //FIXME add error handling + } + }); + } + }); + $.when.apply(undefined, promises).then(function(){ + callback(results); + }); + }, + id: function(element) { + return element.name; + }, + formatResult: function (element) { + var $result = $('
'+escapeHTML(element.displayname)+''); + var $div = $result.find('.avatardiv') + .attr('data-type', element.type) + .attr('data-name', element.name) + .attr('data-displayname', element.displayname); + if (element.type === 'group') { + var url = OC.imagePath('core','places/contacts-dark'); // TODO better group icon + $div.html(''); + } + return $result.get(0).outerHTML; + }, + formatSelection: function (element) { + if (element.type === 'group') { + return ''+escapeHTML(element.displayname+' '+t('files_external', '(group)'))+''; + } else { + return ''+escapeHTML(element.displayname)+''; + } + }, + escapeMarkup: function (m) { return m; } // we escape the markup in formatResult and formatSelection + }).on("select2-loaded", function() { + $.each($(".avatardiv"), function(i, div) { + $div = $(div); + if ($div.data('type') === 'user') { + $div.avatar($div.data('name'),32); + } + }) + }); + } + } + addSelect2($('tr:not(#addMountPoint) .applicableUsers')); + $('#externalStorage').on('change', '#selectBackend', function() { var tr = $(this).parent().parent(); $('#externalStorage tbody').append($(tr).clone()); @@ -209,15 +342,11 @@ $(document).ready(function() { return false; } }); - // Reset chosen - var chosen = $(tr).find('.applicable select'); - chosen.parent().find('div').remove(); - chosen.removeAttr('id').removeClass('chzn-done').css({display:'inline-block'}); - chosen.chosen(); $(tr).find('td').last().attr('class', 'remove'); $(tr).find('td').last().removeAttr('style'); $(tr).removeAttr('id'); $(this).remove(); + addSelect2($('tr:not(#addMountPoint) .applicableUsers')); }); function suggestMountPoint(defaultMountPoint) { @@ -270,8 +399,8 @@ $(document).ready(function() { OC.MountConfig.saveStorage($(this).parent().parent().parent()); }); - $('#externalStorage').on('change', '.applicable .chzn-select', function() { - OC.MountConfig.saveStorage($(this).parent().parent()); + $('#externalStorage').on('change', '.applicable', function() { + OC.MountConfig.saveStorage($(this).parent()); }); $('#sslCertificate').on('click', 'td.remove>img', function() { -- cgit v1.2.3 From 393d136faf76da2b9e3870d9219710d3939c5a83 Mon Sep 17 00:00:00 2001 From: Jörn Friedrich Dreyer Date: Thu, 21 Aug 2014 15:11:21 +0200 Subject: fix deletion of shares --- apps/files_external/js/settings.js | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'apps/files_external/js/settings.js') diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 69e99c03c89..ebc95d64cfd 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -11,6 +11,14 @@ function updateStatus(statusEl, result){ } } +function getSelection($row) { + var values = $row.find('.applicableUsers').select2('val'); + if (!values || values.length === 0) { + values = ['all']; + } + return values; +} + OC.MountConfig={ saveStorage:function(tr, callback) { var mountPoint = $(tr).find('.mountPoint input').val(); @@ -42,12 +50,7 @@ OC.MountConfig={ } }); if ($('#externalStorage').data('admin') === true) { - var multiselect = $(tr).find('.applicableUsers').select2('val'); - if (multiselect == null) { - return false; - } else if (multiselect instanceof Array && multiselect.length === 0) { - multiselect.push('all'); - } + var multiselect = getSelection($(tr)); } if (addMountPoint) { var status = false; @@ -202,7 +205,7 @@ $(document).ready(function() { return { pattern: term, //search term limit: userListLimit, // page size - offset: userListLimit*(page-1), // page number starts with 0 + offset: userListLimit*(page-1) // page number starts with 0 }; }, results: function (data, page) { @@ -417,20 +420,18 @@ $(document).ready(function() { if ($('#externalStorage').data('admin') === true) { var isPersonal = false; - var multiselect = $(tr).find('.chzn-select').val(); - if (multiselect != null) { - $.each(multiselect, function(index, value) { - var pos = value.indexOf('(group)'); - if (pos != -1) { - var mountType = 'group'; - var applicable = value.substr(0, pos); - } else { - var mountType = 'user'; - var applicable = value; - } - $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal }); - }); - } + var multiselect = getSelection($(tr)); + $.each(multiselect, function(index, value) { + var pos = value.indexOf('(group)'); + if (pos != -1) { + var mountType = 'group'; + var applicable = value.substr(0, pos); + } else { + var mountType = 'user'; + var applicable = value; + } + $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal }); + }); } else { var mountType = 'user'; var applicable = OC.currentUser; -- cgit v1.2.3 From 6202ef3258c7db707f32c0bcaa17552b92fa15eb Mon Sep 17 00:00:00 2001 From: Jörn Friedrich Dreyer Date: Fri, 22 Aug 2014 16:07:48 +0200 Subject: use displayname lookup route in files_external settings --- apps/files_external/js/settings.js | 45 ++++++++++++-------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'apps/files_external/js/settings.js') diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index ebc95d64cfd..27ed0254dd3 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -233,41 +233,24 @@ $(document).ready(function() { } }, initSelection: function(element, callback) { - - var promises = []; - - var results = []; - - $(element.val().split(",")).each(function (i,userId) { - var def = new $.Deferred(); - promises.push(def.promise()); - - var pos = userId.indexOf('(group)'); - if (pos !== -1) { - //add as group - results.push({name:userId, displayname:userId.substr(0, pos), type:'group'}); - def.resolve(); - } else { - $.ajax(OC.generateUrl('apps/files_external/applicable'), { - data: { - pattern: userId - }, - dataType: "json" - }).done(function(data) { - if (data.status === "success") { - if (data.users[userId]) { - results.push({name:userId, displayname:data.users[userId], type:'user'}); - } - def.resolve(); - } else { - //FIXME add error handling + $.ajax(OC.generateUrl('displaynames'), { + data: { + users: element.val().split(",") + }, + dataType: "json" + }).done(function(data) { + var results = []; + if (data.status === "success") { + $.each(data.users, function(user, displayname) { + if (displayname !== false) { + results.push({name:user, displayname:displayname, type:'user'}); } }); + callback(results); + } else { + //FIXME add error handling } }); - $.when.apply(undefined, promises).then(function(){ - callback(results); - }); }, id: function(element) { return element.name; -- cgit v1.2.3 From f33312f76773a46acf084dd93830c739e44e9962 Mon Sep 17 00:00:00 2001 From: Lukas Reschke Date: Fri, 22 Aug 2014 18:16:55 +0200 Subject: Use AppFramework instead of custom controller --- apps/files_external/js/settings.js | 13 ++++++-- core/application.php | 53 ++++++++++++++++++++++++++++++ core/lostpassword/application.php | 44 ------------------------- core/routes.php | 7 ++-- core/user/controller.php | 31 ------------------ core/user/usercontroller.php | 66 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 83 deletions(-) create mode 100644 core/application.php delete mode 100644 core/lostpassword/application.php delete mode 100644 core/user/controller.php create mode 100644 core/user/usercontroller.php (limited to 'apps/files_external/js/settings.js') diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 27ed0254dd3..6c287d6a760 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -233,10 +233,17 @@ $(document).ready(function() { } }, initSelection: function(element, callback) { + var users = {}; + users['users'] = []; + var toSplit = element.val().split(","); + for (var i = 0; i < toSplit.length; i++) { + users['users'].push(toSplit[i]); + } + $.ajax(OC.generateUrl('displaynames'), { - data: { - users: element.val().split(",") - }, + type: 'POST', + contentType: 'application/json', + data: JSON.stringify(users), dataType: "json" }).done(function(data) { var results = []; diff --git a/core/application.php b/core/application.php new file mode 100644 index 00000000000..33801847758 --- /dev/null +++ b/core/application.php @@ -0,0 +1,53 @@ +getContainer(); + + /** + * Controllers + */ + $container->registerService('LostController', function($c) { + return new LostController( + $c->query('AppName'), + $c->query('Request'), + $c->query('ServerContainer')->getURLGenerator(), + $c->query('ServerContainer')->getUserManager(), + new \OC_Defaults(), + $c->query('ServerContainer')->getL10N('core'), + $c->query('ServerContainer')->getConfig(), + $c->query('ServerContainer')->getUserSession(), + \OCP\Util::getDefaultEmailAddress('lostpassword-noreply'), + \OC_App::isEnabled('files_encryption') + ); + }); + $container->registerService('UserController', function($c) { + return new UserController( + $c->query('AppName'), + $c->query('Request'), + $c->query('ServerContainer')->getUserManager(), + new \OC_Defaults() + ); + }); + } + + +} diff --git a/core/lostpassword/application.php b/core/lostpassword/application.php deleted file mode 100644 index ba2f3fc633b..00000000000 --- a/core/lostpassword/application.php +++ /dev/null @@ -1,44 +0,0 @@ -getContainer(); - - /** - * Controllers - */ - $container->registerService('LostController', function($c) { - return new LostController( - $c->query('AppName'), - $c->query('Request'), - $c->query('ServerContainer')->getURLGenerator(), - $c->query('ServerContainer')->getUserManager(), - new \OC_Defaults(), - $c->query('ServerContainer')->getL10N('core'), - $c->query('ServerContainer')->getConfig(), - $c->query('ServerContainer')->getUserSession(), - \OCP\Util::getDefaultEmailAddress('lostpassword-noreply'), - \OC_App::isEnabled('files_encryption') - ); - }); - } - - -} diff --git a/core/routes.php b/core/routes.php index 37eb2f8a56c..28a3680dd91 100644 --- a/core/routes.php +++ b/core/routes.php @@ -6,13 +6,14 @@ * See the COPYING-README file. */ -use OC\Core\LostPassword\Application; +use OC\Core\Application; $application = new Application(); $application->registerRoutes($this, array('routes' => array( array('name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'), array('name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'), array('name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'), + array('name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'), ) )); @@ -35,10 +36,6 @@ $this->create('core_ajax_share', '/core/ajax/share.php') // Translations $this->create('core_ajax_translations', '/core/ajax/translations.php') ->actionInclude('core/ajax/translations.php'); -// User display names -$this->create('core_user_displaynames', '/displaynames') - ->get() - ->action('OC\Core\User\Controller', 'getDisplayNames'); // Tags $this->create('core_tags_tags', '/tags/{type}') ->get() diff --git a/core/user/controller.php b/core/user/controller.php deleted file mode 100644 index cbcbd936183..00000000000 --- a/core/user/controller.php +++ /dev/null @@ -1,31 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace OC\Core\User; - -class Controller { - public static function getDisplayNames($args) { - \OC_JSON::checkLoggedIn(); - \OC_JSON::callCheck(); - - $users = $_GET['users']; - $result = array(); - $userManager = \OC::$server->getUserManager(); - - foreach ($users as $user) { - $userObject = $userManager->get($user); - if (is_object($userObject)) { - $result[$user] = $userObject->getDisplayName(); - } else { - $result[$user] = false; - } - } - - \OC_JSON::success(array('users'=>$result)); - } -} diff --git a/core/user/usercontroller.php b/core/user/usercontroller.php new file mode 100644 index 00000000000..2570e3b5b05 --- /dev/null +++ b/core/user/usercontroller.php @@ -0,0 +1,66 @@ + + * Copyright (c) 2014 Lukas Reschke + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Core\User; + +use \OCP\AppFramework\Controller; +use \OCP\AppFramework\Http\JSONResponse; +use \OCP\IRequest; + +class UserController extends Controller { + /** + * @var \OCP\IUserManager + */ + protected $userManager; + + /** + * @var \OC_Defaults + */ + protected $defaults; + + public function __construct($appName, + IRequest $request, + $userManager, + $defaults + ) { + parent::__construct($appName, $request); + $this->userManager = $userManager; + $this->defaults = $defaults; + } + + /** + * Lookup user display names + * + * @NoAdminRequired + * + * @param array $users + * + * @return JSONResponse + */ + public function getDisplayNames($users) { + $result = array(); + + foreach ($users as $user) { + $userObject = $this->userManager->get($user); + if (is_object($userObject)) { + $result[$user] = $userObject->getDisplayName(); + } else { + $result[$user] = $user; + } + } + + $json = array( + 'users' => $result, + 'status' => 'success' + ); + + return new JSONResponse($json); + + } +} -- cgit v1.2.3 From 0e8a973579c95053845153257b1bbe185f3b84b3 Mon Sep 17 00:00:00 2001 From: Robin McCorkell Date: Thu, 14 Aug 2014 17:48:34 +0100 Subject: Improve UI of external storage configuration * Highlight fields that need to be filled * Remove (required) and (optional) strings where possible * Focus first configuration field when creating new external storage * Add ability to force external storage re-check * Various jQuery improvements * Prevent wrapping of checkboxes in configuration --- apps/files_external/appinfo/app.php | 12 +++---- apps/files_external/css/settings.css | 3 ++ apps/files_external/js/settings.js | 66 ++++++++++++++++++++++++------------ core/css/styles.css | 4 +++ 4 files changed, 57 insertions(+), 28 deletions(-) (limited to 'apps/files_external/js/settings.js') diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 3b8793a075b..04c48187e37 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -62,9 +62,9 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\AmazonS3', array( 'key' => (string)$l->t('Access Key'), 'secret' => '*'.$l->t('Secret Key'), 'bucket' => (string)$l->t('Bucket'), - 'hostname' => '&'.$l->t('Hostname (optional)'), - 'port' => '&'.$l->t('Port (optional)'), - 'region' => '&'.$l->t('Region (optional)'), + 'hostname' => '&'.$l->t('Hostname'), + 'port' => '&'.$l->t('Port'), + 'region' => '&'.$l->t('Region'), 'use_ssl' => '!'.$l->t('Enable SSL'), 'use_path_style' => '!'.$l->t('Enable Path Style')), 'has_dependencies' => true)); @@ -108,15 +108,15 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\Swift', array( 'backend' => (string)$l->t('OpenStack Object Storage'), 'priority' => 100, 'configuration' => array( - 'user' => (string)$l->t('Username (required)'), - 'bucket' => (string)$l->t('Bucket (required)'), + 'user' => (string)$l->t('Username'), + 'bucket' => (string)$l->t('Bucket'), 'region' => '&'.$l->t('Region (optional for OpenStack Object Storage)'), 'key' => '*'.$l->t('API Key (required for Rackspace Cloud Files)'), 'tenant' => '&'.$l->t('Tenantname (required for OpenStack Object Storage)'), 'password' => '*'.$l->t('Password (required for OpenStack Object Storage)'), 'service_name' => '&'.$l->t('Service Name (required for OpenStack Object Storage)'), 'url' => '&'.$l->t('URL of identity endpoint (required for OpenStack Object Storage)'), - 'timeout' => '&'.$l->t('Timeout of HTTP requests in seconds (optional)'), + 'timeout' => '&'.$l->t('Timeout of HTTP requests in seconds'), ), 'has_dependencies' => true)); diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css index b78eec235d6..101c224c5f5 100644 --- a/apps/files_external/css/settings.css +++ b/apps/files_external/css/settings.css @@ -20,6 +20,9 @@ tr:hover>td.remove>img { visibility:visible; cursor:pointer; } #externalStorage td.backend { white-space: normal; } +#externalStorage td.configuration > * { + white-space: nowrap; +} #externalStorage td.configuration input.added { margin-right: 6px; diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js index 6c287d6a760..00d2a920cbf 100644 --- a/apps/files_external/js/settings.js +++ b/apps/files_external/js/settings.js @@ -2,7 +2,7 @@ function updateStatus(statusEl, result){ statusEl.removeClass('success error loading-small'); - if (result && result.status == 'success' && result.data.message) { + if (result && result.status === 'success' && result.data.message) { statusEl.addClass('success'); return true; } else { @@ -19,11 +19,23 @@ function getSelection($row) { return values; } +function highlightBorder(element, highlight) { + $(element).toggleClass('warning-input', highlight); + return highlight; +} + +function highlightInput(input) { + if ($(input).attr('type') === 'text' || $(input).attr('type') === 'password') { + return highlightBorder(input, + ($(input).val() === '' && !$(input).hasClass('optional'))); + } +} + OC.MountConfig={ saveStorage:function(tr, callback) { var mountPoint = $(tr).find('.mountPoint input').val(); var oldMountPoint = $(tr).find('.mountPoint input').data('mountpoint'); - if (mountPoint == '') { + if (mountPoint === '') { return false; } var statusSpan = $(tr).closest('tr').find('.status span'); @@ -35,7 +47,7 @@ OC.MountConfig={ } var classOptions = {}; $.each(configuration, function(index, input) { - if ($(input).val() == '' && !$(input).hasClass('optional')) { + if ($(input).val() === '' && !$(input).hasClass('optional')) { addMountPoint = false; return false; } @@ -295,13 +307,13 @@ $(document).ready(function() { addSelect2($('tr:not(#addMountPoint) .applicableUsers')); $('#externalStorage').on('change', '#selectBackend', function() { - var tr = $(this).parent().parent(); + var tr = $(this).closest("tr"); $('#externalStorage tbody').append($(tr).clone()); $('#externalStorage tbody tr').last().find('.mountPoint input').val(''); var selected = $(this).find('option:selected').text(); var backendClass = $(this).val(); - $(this).parent().text(selected); - if ($(tr).find('.mountPoint input').val() == '') { + $(tr).find('.backend').text(selected); + if ($(tr).find('.mountPoint input').val() === '') { $(tr).find('.mountPoint input').val(suggestMountPoint(selected)); } $(tr).addClass(backendClass); @@ -310,28 +322,32 @@ $(document).ready(function() { var configurations = $(this).data('configurations'); var td = $(tr).find('td.configuration'); $.each(configurations, function(backend, parameters) { - if (backend == backendClass) { + if (backend === backendClass) { $.each(parameters['configuration'], function(parameter, placeholder) { var is_optional = false; if (placeholder.indexOf('&') === 0) { is_optional = true; placeholder = placeholder.substring(1); } + var newElement; if (placeholder.indexOf('*') === 0) { var class_string = is_optional ? ' optional' : ''; - td.append(''); + newElement = $(''); } else if (placeholder.indexOf('!') === 0) { - td.append(''); + newElement = $(''); } else if (placeholder.indexOf('#') === 0) { - td.append(''); + newElement = $(''); } else { var class_string = is_optional ? ' optional' : ''; - td.append(''); + newElement = $(''); } + highlightInput(newElement); + td.append(newElement); }); - if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) { + if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length === 1) { OC.addScript('files_external', parameters['custom']); } + td.children().not('[type=hidden]').first().focus(); return false; } }); @@ -354,7 +370,7 @@ $(document).ready(function() { while (match && i < 20) { match = false; $('#externalStorage tbody td.mountPoint input').each(function(index, mountPoint) { - if ($(mountPoint).val() == defaultMountPoint+append) { + if ($(mountPoint).val() === defaultMountPoint+append) { match = true; return false; } @@ -369,9 +385,11 @@ $(document).ready(function() { return defaultMountPoint+append; } - $('#externalStorage').on('paste', 'td', function() { - var tr = $(this).parent(); + $('#externalStorage').on('paste', 'td input', function() { + var tr = $(this).closest("tr"); + var me = this; setTimeout(function() { + highlightInput($(me)); OC.MountConfig.saveStorage(tr); }, 20); }); @@ -380,7 +398,8 @@ $(document).ready(function() { $('#externalStorage').on('keyup', 'td input', function() { clearTimeout(timer); - var tr = $(this).parent().parent(); + var tr = $(this).closest("tr"); + highlightInput($(this)); if ($(this).val) { timer = setTimeout(function() { OC.MountConfig.saveStorage(tr); @@ -389,23 +408,26 @@ $(document).ready(function() { }); $('#externalStorage').on('change', 'td input:checkbox', function() { - OC.MountConfig.saveStorage($(this).parent().parent().parent()); + OC.MountConfig.saveStorage($(this).closest("tr")); }); $('#externalStorage').on('change', '.applicable', function() { - OC.MountConfig.saveStorage($(this).parent()); + OC.MountConfig.saveStorage($(this).closest("tr")); + }); + + $('#externalStorage').on('click', '.status>span', function() { + OC.MountConfig.saveStorage($(this).closest("tr")); }); $('#sslCertificate').on('click', 'td.remove>img', function() { - var $tr = $(this).parent().parent(); - var row = this.parentNode.parentNode; - $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id}); + var $tr = $(this).closest("tr"); + $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: $tr.attr('id')}); $tr.remove(); return true; }); $('#externalStorage').on('click', 'td.remove>img', function() { - var tr = $(this).parent().parent(); + var tr = $(this).closest('tr'); var mountPoint = $(tr).find('.mountPoint input').val(); if ($('#externalStorage').data('admin') === true) { diff --git a/core/css/styles.css b/core/css/styles.css index 7e41e904127..3f3afa44f2d 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -620,6 +620,10 @@ label.infield { color: black !important; } +.warning-input { + border-color: #cc3333 !important; +} + /* Fixes for log in page, TODO should be removed some time */ #body-login .update, #body-login .error { -- cgit v1.2.3