From f88d886332dcf709a517632ce5fad5212d39ad53 Mon Sep 17 00:00:00 2001 From: Nolwenn LAVIELLE Date: Tue, 18 Feb 2020 09:35:58 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20livre=20et=20suppression=20de=20li?= =?UTF-8?q?vre=20sans=20recharger=20la=20page=20d=E2=80=99index=20OK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 1 + Gemfile.lock | 3 + app/assets/javascripts/application.js | 4 +- app/assets/javascripts/emprunts.coffee | 3 + app/assets/javascripts/jquery.tabledit.js | 1188 +++++++++--------- app/assets/javascripts/livres.coffee | 37 - app/assets/javascripts/livres.js | 47 + app/assets/javascripts/rails.tabledit.js | 613 +++++++++ app/assets/stylesheets/_mixin.sass | 4 +- app/assets/stylesheets/application.sass | 2 + app/assets/stylesheets/emprunts.scss | 3 + app/assets/stylesheets/scaffolds.scss | 1 + app/controllers/emprunts_controller.rb | 74 ++ app/controllers/livres_controller.rb | 54 +- app/helpers/emprunts_helper.rb | 2 + app/helpers/livres_helper.rb | 9 + app/models/emprunt.rb | 2 + app/views/emprunts/_emprunt.json.jbuilder | 2 + app/views/emprunts/_form.html.erb | 27 + app/views/emprunts/edit.html.erb | 6 + app/views/emprunts/index.html.erb | 29 + app/views/emprunts/index.json.jbuilder | 1 + app/views/emprunts/new.html.erb | 5 + app/views/emprunts/show.html.erb | 14 + app/views/emprunts/show.json.jbuilder | 1 + app/views/layouts/application.html.erb | 1 + app/views/livres/_form.html.erb | 15 +- app/views/livres/_livre.html.erb | 11 + app/views/livres/_livre.json.jbuilder | 2 + app/views/livres/create.js.erb | 3 + app/views/livres/destroy.js.erb | 3 + app/views/livres/index.html.erb | 45 +- app/views/livres/index.json.jbuilder | 1 + app/views/livres/new.js.erb | 1 + app/views/livres/show.html.erb | 29 + app/views/livres/show.json.jbuilder | 1 + config/initializers/assets.rb | 1 + config/routes.rb | 4 +- db/migrate/20200217133444_create_emprunts.rb | 10 + db/schema.rb | 9 +- test/controllers/emprunts_controller_test.rb | 48 + test/fixtures/emprunts.yml | 9 + test/models/emprunt_test.rb | 7 + test/system/emprunts_test.rb | 45 + 44 files changed, 1691 insertions(+), 686 deletions(-) create mode 100644 app/assets/javascripts/emprunts.coffee delete mode 100644 app/assets/javascripts/livres.coffee create mode 100644 app/assets/javascripts/livres.js create mode 100644 app/assets/javascripts/rails.tabledit.js create mode 100644 app/assets/stylesheets/emprunts.scss create mode 100644 app/assets/stylesheets/scaffolds.scss create mode 100644 app/controllers/emprunts_controller.rb create mode 100644 app/helpers/emprunts_helper.rb create mode 100644 app/models/emprunt.rb create mode 100644 app/views/emprunts/_emprunt.json.jbuilder create mode 100644 app/views/emprunts/_form.html.erb create mode 100644 app/views/emprunts/edit.html.erb create mode 100644 app/views/emprunts/index.html.erb create mode 100644 app/views/emprunts/index.json.jbuilder create mode 100644 app/views/emprunts/new.html.erb create mode 100644 app/views/emprunts/show.html.erb create mode 100644 app/views/emprunts/show.json.jbuilder create mode 100644 app/views/livres/_livre.html.erb create mode 100644 app/views/livres/_livre.json.jbuilder create mode 100644 app/views/livres/create.js.erb create mode 100644 app/views/livres/destroy.js.erb create mode 100644 app/views/livres/index.json.jbuilder create mode 100644 app/views/livres/new.js.erb create mode 100644 app/views/livres/show.html.erb create mode 100644 app/views/livres/show.json.jbuilder create mode 100644 db/migrate/20200217133444_create_emprunts.rb create mode 100644 test/controllers/emprunts_controller_test.rb create mode 100644 test/fixtures/emprunts.yml create mode 100644 test/models/emprunt_test.rb create mode 100644 test/system/emprunts_test.rb diff --git a/Gemfile b/Gemfile index 382dc5e..d72a294 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,7 @@ gem 'jbuilder', '~> 2.5' gem 'bootsnap', '>= 1.1.0', require: false gem 'bootstrap', '~> 4.3.1' +gem 'font-awesome-rails' gem 'jquery-rails' gem 'jquery-ui-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 77aac66..4f23211 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -87,6 +87,8 @@ GEM eventmachine (1.2.7) execjs (2.7.0) ffi (1.12.2) + font-awesome-rails (4.7.0.5) + railties (>= 3.2, < 6.1) formatador (0.2.5) globalid (0.4.2) activesupport (>= 4.2.0) @@ -256,6 +258,7 @@ DEPENDENCIES capybara (>= 2.15) chromedriver-helper coffee-rails (~> 4.2) + font-awesome-rails guard-livereload guard-rails jbuilder (~> 2.5) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 5d993fd..9942c9c 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,6 +12,6 @@ // //= require rails-ujs //= require activestorage -//= require turbolinks +//= require jquery //= require jquery.tabledit -//= require_tree . +//= require turbolinks diff --git a/app/assets/javascripts/emprunts.coffee b/app/assets/javascripts/emprunts.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/emprunts.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/javascripts/jquery.tabledit.js b/app/assets/javascripts/jquery.tabledit.js index 21163e1..06738f6 100644 --- a/app/assets/javascripts/jquery.tabledit.js +++ b/app/assets/javascripts/jquery.tabledit.js @@ -11,602 +11,602 @@ */ if (typeof jQuery === 'undefined') { - throw new Error('Tabledit requires jQuery library.'); + throw new Error('Tabledit requires jQuery library.'); } (function($) { - 'use strict'; - - $.fn.Tabledit = function(options) { - if (!this.is('table')) { - throw new Error('Tabledit only works when applied to a table.'); - } - - var $table = this; - - var defaults = { - url: window.location.href, - inputClass: 'form-control input-sm', - toolbarClass: 'btn-toolbar', - groupClass: 'btn-group btn-group-sm', - dangerClass: 'danger', - warningClass: 'warning', - mutedClass: 'text-muted', - eventType: 'click', - rowIdentifier: 'id', - hideIdentifier: false, - autoFocus: true, - editButton: true, - deleteButton: true, - saveButton: true, - restoreButton: true, - buttons: { - edit: { - class: 'btn btn-sm btn-default', - html: '', - action: 'edit' - }, - delete: { - class: 'btn btn-sm btn-default', - html: '', - action: 'delete' - }, - save: { - class: 'btn btn-sm btn-success', - html: 'Save' - }, - restore: { - class: 'btn btn-sm btn-warning', - html: 'Restore', - action: 'restore' - }, - confirm: { - class: 'btn btn-sm btn-danger', - html: 'Confirm' - } - }, - onDraw: function() { return; }, - onSuccess: function() { return; }, - onFail: function() { return; }, - onAlways: function() { return; }, - onAjax: function() { return; } - }; - - var settings = $.extend(true, defaults, options); - - var $lastEditedRow = 'undefined'; - var $lastDeletedRow = 'undefined'; - var $lastRestoredRow = 'undefined'; - - /** - * Draw Tabledit structure (identifier column, editable columns, toolbar column). - * - * @type {object} - */ - var Draw = { - columns: { - identifier: function() { - // Hide identifier column. - if (settings.hideIdentifier) { - $table.find('th:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + '), tbody td:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + ')').hide(); - } - - var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.identifier[0]) + 1) + ')'); - - $td.each(function() { - // Create hidden input with row identifier. - var span = '' + $(this).text() + ''; - var input = ''; - - // Add elements to table cell. - $(this).html(span + input); - - // Add attribute "id" to table row. - $(this).parent('tr').attr(settings.rowIdentifier, $(this).text()); - }); - }, - editable: function() { - for (var i = 0; i < settings.columns.editable.length; i++) { - var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.editable[i][0]) + 1) + ')'); - - $td.each(function() { - // Get text of this cell. - var text = $(this).text(); - - // Add pointer as cursor. - if (!settings.editButton) { - $(this).css('cursor', 'pointer'); - } - - // Create span element. - var span = '' + text + ''; - - // Check if exists the third parameter of editable array. - if (typeof settings.columns.editable[i][2] !== 'undefined') { - // Create select element. - var input = ''; - } else { - // Create text input element. - var input = ''; - } - - // Add elements and class "view" to table cell. - $(this).html(span + input); - $(this).addClass('tabledit-view-mode'); - }); - } - }, - toolbar: function() { - if (settings.editButton || settings.deleteButton) { - var editButton = ''; - var deleteButton = ''; - var saveButton = ''; - var restoreButton = ''; - var confirmButton = ''; - - // Add toolbar column header if not exists. - if ($table.find('th.tabledit-toolbar-column').length === 0) { - $table.find('tr:first').append(''); - } - - // Create edit button. - if (settings.editButton) { - editButton = ''; - } - - // Create delete button. - if (settings.deleteButton) { - deleteButton = ''; - confirmButton = ''; - } - - // Create save button. - if (settings.editButton && settings.saveButton) { - saveButton = ''; - } - - // Create restore button. - if (settings.deleteButton && settings.restoreButton) { - restoreButton = ''; - } - - var toolbar = '
\n\ -
' + editButton + deleteButton + '
\n\ - ' + saveButton + '\n\ - ' + confirmButton + '\n\ - ' + restoreButton + '\n\ -
'; - - // Add toolbar column cells. - $table.find('tbody>tr').append('' + toolbar + ''); - } - } - } - }; - - /** - * Change to view mode or edit mode with table td element as parameter. - * - * @type object - */ - var Mode = { - view: function(td) { - // Get table row. - var $tr = $(td).parent('tr'); - // Disable identifier. - $(td).parent('tr').find('.tabledit-input.tabledit-identifier').prop('disabled', true); - // Hide and disable input element. - $(td).find('.tabledit-input').blur().hide().prop('disabled', true); - // Show span element. - $(td).find('.tabledit-span').show(); - // Add "view" class and remove "edit" class in td element. - $(td).addClass('tabledit-view-mode').removeClass('tabledit-edit-mode'); - // Update toolbar buttons. - if (settings.editButton) { - $tr.find('button.tabledit-save-button').hide(); - $tr.find('button.tabledit-edit-button').removeClass('active').blur(); - } - }, - edit: function(td) { - Delete.reset(td); - // Get table row. - var $tr = $(td).parent('tr'); - // Enable identifier. - $tr.find('.tabledit-input.tabledit-identifier').prop('disabled', false); - // Hide span element. - $(td).find('.tabledit-span').hide(); - // Get input element. - var $input = $(td).find('.tabledit-input'); - // Enable and show input element. - $input.prop('disabled', false).show(); - // Focus on input element. - if (settings.autoFocus) { - $input.focus(); - } - // Add "edit" class and remove "view" class in td element. - $(td).addClass('tabledit-edit-mode').removeClass('tabledit-view-mode'); - // Update toolbar buttons. - if (settings.editButton) { - $tr.find('button.tabledit-edit-button').addClass('active'); - $tr.find('button.tabledit-save-button').show(); - } - } - }; - - /** - * Available actions for edit function, with table td element as parameter or set of td elements. - * - * @type object - */ - var Edit = { - reset: function(td) { - $(td).each(function() { - // Get input element. - var $input = $(this).find('.tabledit-input'); - // Get span text. - var text = $(this).find('.tabledit-span').text(); - // Set input/select value with span text. - if ($input.is('select')) { - $input.find('option').filter(function() { - return $.trim($(this).text()) === text; - }).attr('selected', true); - } else { - $input.val(text); - } - // Change to view mode. - Mode.view(this); - }); - }, - submit: function(td) { - // Send AJAX request to server. - var ajaxResult = ajax(settings.buttons.edit.action); - - if (ajaxResult === false) { - return; - } - - $(td).each(function() { - // Get input element. - var $input = $(this).find('.tabledit-input'); - // Set span text with input/select new value. - if ($input.is('select')) { - $(this).find('.tabledit-span').text($input.find('option:selected').text()); - } else { - $(this).find('.tabledit-span').text($input.val()); - } - // Change to view mode. - Mode.view(this); - }); - - // Set last edited column and row. - $lastEditedRow = $(td).parent('tr'); - } - }; - - /** - * Available actions for delete function, with button as parameter. - * - * @type object - */ - var Delete = { - reset: function(td) { - // Reset delete button to initial status. - $table.find('.tabledit-confirm-button').hide(); - // Remove "active" class in delete button. - $table.find('.tabledit-delete-button').removeClass('active').blur(); - }, - submit: function(td) { - Delete.reset(td); - // Enable identifier hidden input. - $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); - // Send AJAX request to server. - var ajaxResult = ajax(settings.buttons.delete.action); - // Disable identifier hidden input. - $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); - - if (ajaxResult === false) { - return; - } - - // Add class "deleted" to row. - $(td).parent('tr').addClass('tabledit-deleted-row'); - // Hide table row. - $(td).parent('tr').addClass(settings.mutedClass).find('.tabledit-toolbar button:not(.tabledit-restore-button)').attr('disabled', true); - // Show restore button. - $(td).find('.tabledit-restore-button').show(); - // Set last deleted row. - $lastDeletedRow = $(td).parent('tr'); - }, - confirm: function(td) { - // Reset all cells in edit mode. - $table.find('td.tabledit-edit-mode').each(function() { - Edit.reset(this); - }); - // Add "active" class in delete button. - $(td).find('.tabledit-delete-button').addClass('active'); - // Show confirm button. - $(td).find('.tabledit-confirm-button').show(); - }, - restore: function(td) { - // Enable identifier hidden input. - $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); - // Send AJAX request to server. - var ajaxResult = ajax(settings.buttons.restore.action); - // Disable identifier hidden input. - $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); - - if (ajaxResult === false) { - return; - } - - // Remove class "deleted" to row. - $(td).parent('tr').removeClass('tabledit-deleted-row'); - // Hide table row. - $(td).parent('tr').removeClass(settings.mutedClass).find('.tabledit-toolbar button').attr('disabled', false); - // Hide restore button. - $(td).find('.tabledit-restore-button').hide(); - // Set last restored row. - $lastRestoredRow = $(td).parent('tr'); - } - }; - - /** - * Send AJAX request to server. - * - * @param {string} action - */ - function ajax(action) - { - var serialize = $table.find('.tabledit-input').serialize() - - if (!serialize) { - return false; - } - - serialize += '&action=' + action; - - var result = settings.onAjax(action, serialize); - - if (result === false) { - return false; - } - - var jqXHR = $.post(settings.url, serialize, function(data, textStatus, jqXHR) { - if (action === settings.buttons.edit.action) { - $lastEditedRow.removeClass(settings.dangerClass).addClass(settings.warningClass); - setTimeout(function() { - //$lastEditedRow.removeClass(settings.warningClass); - $table.find('tr.' + settings.warningClass).removeClass(settings.warningClass); - }, 1400); - } - - settings.onSuccess(data, textStatus, jqXHR); - }, 'json'); - - jqXHR.fail(function(jqXHR, textStatus, errorThrown) { - if (action === settings.buttons.delete.action) { - $lastDeletedRow.removeClass(settings.mutedClass).addClass(settings.dangerClass); - $lastDeletedRow.find('.tabledit-toolbar button').attr('disabled', false); - $lastDeletedRow.find('.tabledit-toolbar .tabledit-restore-button').hide(); - } else if (action === settings.buttons.edit.action) { - $lastEditedRow.addClass(settings.dangerClass); - } - - settings.onFail(jqXHR, textStatus, errorThrown); - }); - - jqXHR.always(function() { - settings.onAlways(); - }); - - return jqXHR; - } - - Draw.columns.identifier(); - Draw.columns.editable(); - Draw.columns.toolbar(); - - settings.onDraw(); - - if (settings.deleteButton) { - /** - * Delete one row. - * - * @param {object} event - */ - $table.on('click', 'button.tabledit-delete-button', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - // Get current state before reset to view mode. - var activated = $(this).hasClass('active'); - - var $td = $(this).parents('td'); - - Delete.reset($td); - - if (!activated) { - Delete.confirm($td); - } - - event.handled = true; - } - }); - - /** - * Delete one row (confirm). - * - * @param {object} event - */ - $table.on('click', 'button.tabledit-confirm-button', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - var $td = $(this).parents('td'); - - Delete.submit($td); - - event.handled = true; - } - }); - } - - if (settings.restoreButton) { - /** - * Restore one row. - * - * @param {object} event - */ - $table.on('click', 'button.tabledit-restore-button', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - Delete.restore($(this).parents('td')); - - event.handled = true; - } - }); - } - - if (settings.editButton) { - /** - * Activate edit mode on all columns. - * - * @param {object} event - */ - $table.on('click', 'button.tabledit-edit-button', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - var $button = $(this); - - // Get current state before reset to view mode. - var activated = $button.hasClass('active'); - - // Change to view mode columns that are in edit mode. - Edit.reset($table.find('td.tabledit-edit-mode')); - - if (!activated) { - // Change to edit mode for all columns in reverse way. - $($button.parents('tr').find('td.tabledit-view-mode').get().reverse()).each(function() { - Mode.edit(this); - }); - } - - event.handled = true; - } - }); - - /** - * Save edited row. - * - * @param {object} event - */ - $table.on('click', 'button.tabledit-save-button', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - // Submit and update all columns. - Edit.submit($(this).parents('tr').find('td.tabledit-edit-mode')); - - event.handled = true; - } - }); - } else { - /** - * Change to edit mode on table td element. - * - * @param {object} event - */ - $table.on(settings.eventType, 'tr:not(.tabledit-deleted-row) td.tabledit-view-mode', function(event) { - if (event.handled !== true) { - event.preventDefault(); - - // Reset all td's in edit mode. - Edit.reset($table.find('td.tabledit-edit-mode')); - - // Change to edit mode. - Mode.edit(this); - - event.handled = true; - } - }); - - /** - * Change event when input is a select element. - */ - $table.on('change', 'select.tabledit-input:visible', function(event) { - if (event.handled !== true) { - // Submit and update the column. - Edit.submit($(this).parent('td')); - - event.handled = true; - } - }); - - /** - * Click event on document element. - * - * @param {object} event - */ - $(document).on('click', function(event) { - var $editMode = $table.find('.tabledit-edit-mode'); - // Reset visible edit mode column. - if (!$editMode.is(event.target) && $editMode.has(event.target).length === 0) { - Edit.reset($table.find('.tabledit-input:visible').parent('td')); - } - }); - } - - /** - * Keyup event on table element. - * - * @param {object} event - */ - $table.on('keyup', function(event) { - // Get input element with focus or confirmation button. - var $input = $table.find('.tabledit-input:visible'); - var $button = $table.find('.tabledit-confirm-button'); - - if ($input.length > 0) { - var $td = $input.parents('td'); - } else if ($button.length > 0) { - var $td = $button.parents('td'); - } else { - return; - } - - // Key? - switch (event.keyCode) { - case 9: // Tab. - if (!settings.editButton) { - Edit.submit($td); - Mode.edit($td.closest('td').next()); - } - break; - case 13: // Enter. - Edit.submit($td); - break; - case 27: // Escape. - Edit.reset($td); - Delete.reset($td); - break; - } - }); - - return this; - }; + 'use strict'; + + $.fn.Tabledit = function(options) { + if (!this.is('table')) { + throw new Error('Tabledit only works when applied to a table.'); + } + + var $table = this; + + var defaults = { + url: window.location.href, + inputClass: 'form-control input-sm', + toolbarClass: 'btn-toolbar', + groupClass: 'btn-group btn-group-sm', + dangerClass: 'danger', + warningClass: 'warning', + mutedClass: 'text-muted', + eventType: 'click', + rowIdentifier: 'id', + hideIdentifier: false, + autoFocus: true, + editButton: true, + deleteButton: true, + saveButton: true, + restoreButton: true, + buttons: { + edit: { + class: 'btn btn-sm btn-primary', + html: '', + action: 'edit' + }, + delete: { + class: 'btn btn-sm btn-primary', + html: '', + action: 'delete' + }, + save: { + class: 'btn btn-sm btn-success', + html: 'Save' + }, + restore: { + class: 'btn btn-sm btn-warning', + html: 'Restore', + action: 'restore' + }, + confirm: { + class: 'btn btn-sm btn-danger', + html: 'Confirm' + } + }, + onDraw: function() { return; }, + onSuccess: function() { return; }, + onFail: function() { return; }, + onAlways: function() { return; }, + onAjax: function() { return; } + }; + + var settings = $.extend(true, defaults, options); + + var $lastEditedRow = 'undefined'; + var $lastDeletedRow = 'undefined'; + var $lastRestoredRow = 'undefined'; + + /** + * Draw Tabledit structure (identifier column, editable columns, toolbar column). + * + * @type {object} + */ + var Draw = { + columns: { + identifier: function() { + // Hide identifier column. + if (settings.hideIdentifier) { + $table.find('th:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + '), tbody td:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + ')').hide(); + } + + var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.identifier[0]) + 1) + ')'); + + $td.each(function() { + // Create hidden input with row identifier. + var span = '' + $(this).text() + ''; + var input = ''; + + // Add elements to table cell. + $(this).html(span + input); + + // Add attribute "id" to table row. + $(this).parent('tr').attr(settings.rowIdentifier, $(this).text()); + }); + }, + editable: function() { + for (var i = 0; i < settings.columns.editable.length; i++) { + var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.editable[i][0]) + 1) + ')'); + + $td.each(function() { + // Get text of this cell. + var text = $(this).text(); + + // Add pointer as cursor. + if (!settings.editButton) { + $(this).css('cursor', 'pointer'); + } + + // Create span element. + var span = '' + text + ''; + + // Check if exists the third parameter of editable array. + if (typeof settings.columns.editable[i][2] !== 'undefined') { + // Create select element. + var input = ''; + } else { + // Create text input element. + var input = ''; + } + + // Add elements and class "view" to table cell. + $(this).html(span + input); + $(this).addClass('tabledit-view-mode'); + }); + } + }, + toolbar: function() { + if (settings.editButton || settings.deleteButton) { + var editButton = ''; + var deleteButton = ''; + var saveButton = ''; + var restoreButton = ''; + var confirmButton = ''; + + // Add toolbar column header if not exists. + if ($table.find('th.tabledit-toolbar-column').length === 0) { + $table.find('tr:first').append(''); + } + + // Create edit button. + if (settings.editButton) { + editButton = ''; + } + + // Create delete button. + if (settings.deleteButton) { + deleteButton = ''; + confirmButton = ''; + } + + // Create save button. + if (settings.editButton && settings.saveButton) { + saveButton = ''; + } + + // Create restore button. + if (settings.deleteButton && settings.restoreButton) { + restoreButton = ''; + } + + var toolbar = '
\n\ +
' + editButton + deleteButton + '
\n\ + ' + saveButton + '\n\ + ' + confirmButton + '\n\ + ' + restoreButton + '\n\ +
'; + + // Add toolbar column cells. + $table.find('tbody>tr').append('' + toolbar + ''); + } + } + } + }; + + /** + * Change to view mode or edit mode with table td element as parameter. + * + * @type object + */ + var Mode = { + view: function(td) { + // Get table row. + var $tr = $(td).parent('tr'); + // Disable identifier. + $(td).parent('tr').find('.tabledit-input.tabledit-identifier').prop('disabled', true); + // Hide and disable input element. + $(td).find('.tabledit-input').blur().hide().prop('disabled', true); + // Show span element. + $(td).find('.tabledit-span').show(); + // Add "view" class and remove "edit" class in td element. + $(td).addClass('tabledit-view-mode').removeClass('tabledit-edit-mode'); + // Update toolbar buttons. + if (settings.editButton) { + $tr.find('button.tabledit-save-button').hide(); + $tr.find('button.tabledit-edit-button').removeClass('active').blur(); + } + }, + edit: function(td) { + Delete.reset(td); + // Get table row. + var $tr = $(td).parent('tr'); + // Enable identifier. + $tr.find('.tabledit-input.tabledit-identifier').prop('disabled', false); + // Hide span element. + $(td).find('.tabledit-span').hide(); + // Get input element. + var $input = $(td).find('.tabledit-input'); + // Enable and show input element. + $input.prop('disabled', false).show(); + // Focus on input element. + if (settings.autoFocus) { + $input.focus(); + } + // Add "edit" class and remove "view" class in td element. + $(td).addClass('tabledit-edit-mode').removeClass('tabledit-view-mode'); + // Update toolbar buttons. + if (settings.editButton) { + $tr.find('button.tabledit-edit-button').addClass('active'); + $tr.find('button.tabledit-save-button').show(); + } + } + }; + + /** + * Available actions for edit function, with table td element as parameter or set of td elements. + * + * @type object + */ + var Edit = { + reset: function(td) { + $(td).each(function() { + // Get input element. + var $input = $(this).find('.tabledit-input'); + // Get span text. + var text = $(this).find('.tabledit-span').text(); + // Set input/select value with span text. + if ($input.is('select')) { + $input.find('option').filter(function() { + return $.trim($(this).text()) === text; + }).attr('selected', true); + } else { + $input.val(text); + } + // Change to view mode. + Mode.view(this); + }); + }, + submit: function(td) { + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.edit.action); + + if (ajaxResult === false) { + return; + } + + $(td).each(function() { + // Get input element. + var $input = $(this).find('.tabledit-input'); + // Set span text with input/select new value. + if ($input.is('select')) { + $(this).find('.tabledit-span').text($input.find('option:selected').text()); + } else { + $(this).find('.tabledit-span').text($input.val()); + } + // Change to view mode. + Mode.view(this); + }); + + // Set last edited column and row. + $lastEditedRow = $(td).parent('tr'); + } + }; + + /** + * Available actions for delete function, with button as parameter. + * + * @type object + */ + var Delete = { + reset: function(td) { + // Reset delete button to initial status. + $table.find('.tabledit-confirm-button').hide(); + // Remove "active" class in delete button. + $table.find('.tabledit-delete-button').removeClass('active').blur(); + }, + submit: function(td) { + Delete.reset(td); + // Enable identifier hidden input. + $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.delete.action); + // Disable identifier hidden input. + $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); + + if (ajaxResult === false) { + return; + } + + // Add class "deleted" to row. + $(td).parent('tr').addClass('tabledit-deleted-row'); + // Hide table row. + $(td).parent('tr').addClass(settings.mutedClass).find('.tabledit-toolbar button:not(.tabledit-restore-button)').attr('disabled', true); + // Show restore button. + $(td).find('.tabledit-restore-button').show(); + // Set last deleted row. + $lastDeletedRow = $(td).parent('tr'); + }, + confirm: function(td) { + // Reset all cells in edit mode. + $table.find('td.tabledit-edit-mode').each(function() { + Edit.reset(this); + }); + // Add "active" class in delete button. + $(td).find('.tabledit-delete-button').addClass('active'); + // Show confirm button. + $(td).find('.tabledit-confirm-button').show(); + }, + restore: function(td) { + // Enable identifier hidden input. + $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.restore.action); + // Disable identifier hidden input. + $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); + + if (ajaxResult === false) { + return; + } + + // Remove class "deleted" to row. + $(td).parent('tr').removeClass('tabledit-deleted-row'); + // Hide table row. + $(td).parent('tr').removeClass(settings.mutedClass).find('.tabledit-toolbar button').attr('disabled', false); + // Hide restore button. + $(td).find('.tabledit-restore-button').hide(); + // Set last restored row. + $lastRestoredRow = $(td).parent('tr'); + } + }; + + /** + * Send AJAX request to server. + * + * @param {string} action + */ + function ajax(action) + { + var serialize = $table.find('.tabledit-input').serialize() + + if (!serialize) { + return false; + } + + serialize += '&action=' + action; + + var result = settings.onAjax(action, serialize); + + if (result === false) { + return false; + } + + var jqXHR = $.post(settings.url, serialize, function(data, textStatus, jqXHR) { + if (action === settings.buttons.edit.action) { + $lastEditedRow.removeClass(settings.dangerClass).addClass(settings.warningClass); + setTimeout(function() { + //$lastEditedRow.removeClass(settings.warningClass); + $table.find('tr.' + settings.warningClass).removeClass(settings.warningClass); + }, 1400); + } + + settings.onSuccess(data, textStatus, jqXHR); + }, 'json'); + + jqXHR.fail(function(jqXHR, textStatus, errorThrown) { + if (action === settings.buttons.delete.action) { + $lastDeletedRow.removeClass(settings.mutedClass).addClass(settings.dangerClass); + $lastDeletedRow.find('.tabledit-toolbar button').attr('disabled', false); + $lastDeletedRow.find('.tabledit-toolbar .tabledit-restore-button').hide(); + } else if (action === settings.buttons.edit.action) { + $lastEditedRow.addClass(settings.dangerClass); + } + + settings.onFail(jqXHR, textStatus, errorThrown); + }); + + jqXHR.always(function() { + settings.onAlways(); + }); + + return jqXHR; + } + + Draw.columns.identifier(); + Draw.columns.editable(); + Draw.columns.toolbar(); + + settings.onDraw(); + + if (settings.deleteButton) { + /** + * Delete one row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-delete-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Get current state before reset to view mode. + var activated = $(this).hasClass('active'); + + var $td = $(this).parents('td'); + + Delete.reset($td); + + if (!activated) { + Delete.confirm($td); + } + + event.handled = true; + } + }); + + /** + * Delete one row (confirm). + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-confirm-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + var $td = $(this).parents('td'); + + Delete.submit($td); + + event.handled = true; + } + }); + } + + if (settings.restoreButton) { + /** + * Restore one row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-restore-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + Delete.restore($(this).parents('td')); + + event.handled = true; + } + }); + } + + if (settings.editButton) { + /** + * Activate edit mode on all columns. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-edit-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + var $button = $(this); + + // Get current state before reset to view mode. + var activated = $button.hasClass('active'); + + // Change to view mode columns that are in edit mode. + Edit.reset($table.find('td.tabledit-edit-mode')); + + if (!activated) { + // Change to edit mode for all columns in reverse way. + $($button.parents('tr').find('td.tabledit-view-mode').get().reverse()).each(function() { + Mode.edit(this); + }); + } + + event.handled = true; + } + }); + + /** + * Save edited row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-save-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Submit and update all columns. + Edit.submit($(this).parents('tr').find('td.tabledit-edit-mode')); + + event.handled = true; + } + }); + } else { + /** + * Change to edit mode on table td element. + * + * @param {object} event + */ + $table.on(settings.eventType, 'tr:not(.tabledit-deleted-row) td.tabledit-view-mode', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Reset all td's in edit mode. + Edit.reset($table.find('td.tabledit-edit-mode')); + + // Change to edit mode. + Mode.edit(this); + + event.handled = true; + } + }); + + /** + * Change event when input is a select element. + */ + $table.on('change', 'select.tabledit-input:visible', function(event) { + if (event.handled !== true) { + // Submit and update the column. + Edit.submit($(this).parent('td')); + + event.handled = true; + } + }); + + /** + * Click event on document element. + * + * @param {object} event + */ + $(document).on('click', function(event) { + var $editMode = $table.find('.tabledit-edit-mode'); + // Reset visible edit mode column. + if (!$editMode.is(event.target) && $editMode.has(event.target).length === 0) { + Edit.reset($table.find('.tabledit-input:visible').parent('td')); + } + }); + } + + /** + * Keyup event on table element. + * + * @param {object} event + */ + $table.on('keyup', function(event) { + // Get input element with focus or confirmation button. + var $input = $table.find('.tabledit-input:visible'); + var $button = $table.find('.tabledit-confirm-button'); + + if ($input.length > 0) { + var $td = $input.parents('td'); + } else if ($button.length > 0) { + var $td = $button.parents('td'); + } else { + return; + } + + // Key? + switch (event.keyCode) { + case 9: // Tab. + if (!settings.editButton) { + Edit.submit($td); + Mode.edit($td.closest('td').next()); + } + break; + case 13: // Enter. + Edit.submit($td); + break; + case 27: // Escape. + Edit.reset($td); + Delete.reset($td); + break; + } + }); + + return this; + }; }(jQuery)); diff --git a/app/assets/javascripts/livres.coffee b/app/assets/javascripts/livres.coffee deleted file mode 100644 index 5f1d18f..0000000 --- a/app/assets/javascripts/livres.coffee +++ /dev/null @@ -1,37 +0,0 @@ -# Place all the behaviors and hooks related to the matching controller here. -# All this logic will automatically be available in application.js. -# You can use CoffeeScript in this file: http://coffeescript.org/ - -$('#livres').Tabledit({ - url: '/livres/index', - editButton: true, - buttons: { - edit: { - class: 'btn btn-sm btn-default', - html: '', - action: 'edit' - }, - delete: { - class: 'btn btn-sm btn-default', - html: '', - action: 'delete' - }, - save: { - class: 'btn btn-sm btn-success', - html: 'Save' - }, - restore: { - class: 'btn btn-sm btn-warning', - html: 'Restore', - action: 'restore' - }, - confirm: { - class: 'btn btn-sm btn-danger', - html: 'Confirm' - } - }, - columns: { - identifier: [0, 'id'], - editable: [[1, 'titre'], [2, 'auteur'], [3, 'synopsis'], [4, 'style'], [5, 'isbn']] - } -}); diff --git a/app/assets/javascripts/livres.js b/app/assets/javascripts/livres.js new file mode 100644 index 0000000..84bd3d7 --- /dev/null +++ b/app/assets/javascripts/livres.js @@ -0,0 +1,47 @@ +$('#livres').Tabledit({ + url: '/livres/tabledit', + editButton: true, + deleteButton: true, + buttons: { + edit: { + class: 'btn btn-dark', + html: ' Edit', + action: '/livres/tabledit' + }, + delete: { + class: 'btn btn-dark', + html: ' Delete', + action: 'delete' + }, + save: { + class: 'btn btn-success btn-sm', + html: ' Save', + action: '/livres/update' + }, + restore: { + class: 'btn btn-warning', + html: ' Restore', + action: 'restore' + }, + confirm: { + class: 'btn btn-danger btn-sm', + html: ' Confirm' + } + }, + hideIdentifier: true, + columns: { + identifier: [0, 'id'], + editable: [[1, 'titre'], [2, 'auteur'], [3, 'synopsis'], [4, 'style'], [5, 'isbn']] + }, + onSuccess: function(data, textStatus, jqXHR) { + console.log('onSuccess(data, textStatus, jqXHR)'); + console.log(data); + console.log(textStatus); + console.log(jqXHR); + }, + onAjax: function(action, serialize) { + console.log('onAjax(action, serialize)'); + console.log(action); + console.log(serialize); + } +}); diff --git a/app/assets/javascripts/rails.tabledit.js b/app/assets/javascripts/rails.tabledit.js new file mode 100644 index 0000000..88908ed --- /dev/null +++ b/app/assets/javascripts/rails.tabledit.js @@ -0,0 +1,613 @@ +/*! + * Tabledit v1.2.3 (https://github.com/markcell/jQuery-Tabledit) + * Copyright (c) 2015 Celso Marques + * Licensed under MIT (https://github.com/markcell/jQuery-Tabledit/blob/master/LICENSE) + */ + +/** + * @description Inline editor for HTML tables compatible with Bootstrap 4 and Rails + * @version 1.0 + * @author Nolwenn Lavielle + * @origin jQuery-Tabledit + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Tabledit requires jQuery library.'); +} + +(function($) { + 'use strict'; + + $.fn.Tabledit = function(options) { + if (!this.is('table')) { + throw new Error('Tabledit only works when applied to a table.'); + } + + var $table = this; + + var defaults = { + url: window.location.href, + inputClass: 'form-control input-sm', + toolbarClass: 'btn-toolbar', + groupClass: 'btn-group btn-group-sm', + dangerClass: 'danger', + warningClass: 'warning', + mutedClass: 'text-muted', + eventType: 'click', + rowIdentifier: 'id', + hideIdentifier: false, + autoFocus: true, + editButton: true, + deleteButton: true, + saveButton: true, + restoreButton: true, + buttons: { + edit: { + class: 'btn btn-sm btn-primary', + html: '', + action: 'edit' + }, + delete: { + class: 'btn btn-sm btn-primary', + html: '', + action: 'delete' + }, + save: { + class: 'btn btn-sm btn-success', + html: 'Save' + }, + restore: { + class: 'btn btn-sm btn-warning', + html: 'Restore', + action: 'restore' + }, + confirm: { + class: 'btn btn-sm btn-danger', + html: 'Confirm' + } + }, + onDraw: function() { return; }, + onSuccess: function() { return; }, + onFail: function() { return; }, + onAlways: function() { return; }, + onAjax: function() { return; } + }; + + var settings = $.extend(true, defaults, options); + + var $lastEditedRow = 'undefined'; + var $lastDeletedRow = 'undefined'; + var $lastRestoredRow = 'undefined'; + + /** + * Draw Tabledit structure (identifier column, editable columns, toolbar column). + * + * @type {object} + */ + var Draw = { + columns: { + identifier: function() { + // Hide identifier column. + if (settings.hideIdentifier) { + $table.find('th:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + '), tbody td:nth-child(' + parseInt(settings.columns.identifier[0]) + 1 + ')').hide(); + } + + var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.identifier[0]) + 1) + ')'); + + $td.each(function() { + // Create hidden input with row identifier. + var span = '' + $(this).text() + ''; + var input = ''; + + // Add elements to table cell. + $(this).html(span + input); + + // Add attribute "id" to table row. + $(this).parent('tr').attr(settings.rowIdentifier, $(this).text()); + }); + }, + editable: function() { + for (var i = 0; i < settings.columns.editable.length; i++) { + var $td = $table.find('tbody td:nth-child(' + (parseInt(settings.columns.editable[i][0]) + 1) + ')'); + + $td.each(function() { + // Get text of this cell. + var text = $(this).text(); + + // Add pointer as cursor. + if (!settings.editButton) { + $(this).css('cursor', 'pointer'); + } + + // Create span element. + var span = '' + text + ''; + + // Check if exists the third parameter of editable array. + if (typeof settings.columns.editable[i][2] !== 'undefined') { + // Create select element. + var input = ''; + } else { + // Create text input element. + var input = ''; + } + + // Add elements and class "view" to table cell. + $(this).html(span + input); + $(this).addClass('tabledit-view-mode'); + }); + } + }, + toolbar: function() { + if (settings.editButton || settings.deleteButton) { + var editButton = ''; + var deleteButton = ''; + var saveButton = ''; + var restoreButton = ''; + var confirmButton = ''; + + // Add toolbar column header if not exists. + if ($table.find('th.tabledit-toolbar-column').length === 0) { + $table.find('tr:first').append(''); + } + + // Create edit button. + if (settings.editButton) { + editButton = ''; + } + + // Create delete button. + if (settings.deleteButton) { + deleteButton = ''; + confirmButton = ''; + } + + // Create save button. + if (settings.editButton && settings.saveButton) { + saveButton = ''; + } + + // Create restore button. + if (settings.deleteButton && settings.restoreButton) { + restoreButton = ''; + } + + var toolbar = '
\n\ +
' + editButton + deleteButton + '
\n\ + ' + saveButton + '\n\ + ' + confirmButton + '\n\ + ' + restoreButton + '\n\ +
'; + + // Add toolbar column cells. + $table.find('tbody>tr').append('' + toolbar + ''); + } + } + } + }; + + /** + * Change to view mode or edit mode with table td element as parameter. + * + * @type object + */ + var Mode = { + view: function(td) { + // Get table row. + var $tr = $(td).parent('tr'); + // Disable identifier. + $(td).parent('tr').find('.tabledit-input.tabledit-identifier').prop('disabled', true); + // Hide and disable input element. + $(td).find('.tabledit-input').blur().hide().prop('disabled', true); + // Show span element. + $(td).find('.tabledit-span').show(); + // Add "view" class and remove "edit" class in td element. + $(td).addClass('tabledit-view-mode').removeClass('tabledit-edit-mode'); + // Update toolbar buttons. + if (settings.editButton) { + $tr.find('button.tabledit-save-button').hide(); + $tr.find('button.tabledit-edit-button').removeClass('active').blur(); + } + }, + edit: function(td) { + Delete.reset(td); + // Get table row. + var $tr = $(td).parent('tr'); + // Enable identifier. + $tr.find('.tabledit-input.tabledit-identifier').prop('disabled', false); + // Hide span element. + $(td).find('.tabledit-span').hide(); + // Get input element. + var $input = $(td).find('.tabledit-input'); + // Enable and show input element. + $input.prop('disabled', false).show(); + // Focus on input element. + if (settings.autoFocus) { + $input.focus(); + } + // Add "edit" class and remove "view" class in td element. + $(td).addClass('tabledit-edit-mode').removeClass('tabledit-view-mode'); + // Update toolbar buttons. + if (settings.editButton) { + $tr.find('button.tabledit-edit-button').addClass('active'); + $tr.find('button.tabledit-save-button').show(); + } + } + }; + + /** + * Available actions for edit function, with table td element as parameter or set of td elements. + * + * @type object + */ + var Edit = { + reset: function(td) { + $(td).each(function() { + // Get input element. + var $input = $(this).find('.tabledit-input'); + // Get span text. + var text = $(this).find('.tabledit-span').text(); + // Set input/select value with span text. + if ($input.is('select')) { + $input.find('option').filter(function() { + return $.trim($(this).text()) === text; + }).attr('selected', true); + } else { + $input.val(text); + } + // Change to view mode. + Mode.view(this); + }); + }, + submit: function(td) { + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.edit.action); + + if (ajaxResult === false) { + return; + } + + $(td).each(function() { + // Get input element. + var $input = $(this).find('.tabledit-input'); + // Set span text with input/select new value. + if ($input.is('select')) { + $(this).find('.tabledit-span').text($input.find('option:selected').text()); + } else { + $(this).find('.tabledit-span').text($input.val()); + } + // Change to view mode. + Mode.view(this); + }); + + // Set last edited column and row. + $lastEditedRow = $(td).parent('tr'); + } + }; + + /** + * Available actions for delete function, with button as parameter. + * + * @type object + */ + var Delete = { + reset: function(td) { + // Reset delete button to initial status. + $table.find('.tabledit-confirm-button').hide(); + // Remove "active" class in delete button. + $table.find('.tabledit-delete-button').removeClass('active').blur(); + }, + submit: function(td) { + Delete.reset(td); + // Enable identifier hidden input. + $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.delete.action); + // Disable identifier hidden input. + $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); + + if (ajaxResult === false) { + return; + } + + // Add class "deleted" to row. + $(td).parent('tr').addClass('tabledit-deleted-row'); + // Hide table row. + $(td).parent('tr').addClass(settings.mutedClass).find('.tabledit-toolbar button:not(.tabledit-restore-button)').attr('disabled', true); + // Show restore button. + $(td).find('.tabledit-restore-button').show(); + // Set last deleted row. + $lastDeletedRow = $(td).parent('tr'); + }, + confirm: function(td) { + // Reset all cells in edit mode. + $table.find('td.tabledit-edit-mode').each(function() { + Edit.reset(this); + }); + // Add "active" class in delete button. + $(td).find('.tabledit-delete-button').addClass('active'); + // Show confirm button. + $(td).find('.tabledit-confirm-button').show(); + }, + restore: function(td) { + // Enable identifier hidden input. + $(td).parent('tr').find('input.tabledit-identifier').attr('disabled', false); + // Send AJAX request to server. + var ajaxResult = ajax(settings.buttons.restore.action); + // Disable identifier hidden input. + $(td).parents('tr').find('input.tabledit-identifier').attr('disabled', true); + + if (ajaxResult === false) { + return; + } + + // Remove class "deleted" to row. + $(td).parent('tr').removeClass('tabledit-deleted-row'); + // Hide table row. + $(td).parent('tr').removeClass(settings.mutedClass).find('.tabledit-toolbar button').attr('disabled', false); + // Hide restore button. + $(td).find('.tabledit-restore-button').hide(); + // Set last restored row. + $lastRestoredRow = $(td).parent('tr'); + } + }; + + /** + * Send AJAX request to server. + * + * @param {string} action + */ + function ajax(action) + { + var serialize = $table.find('.tabledit-input').serialize() + + if (!serialize) { + return false; + } + + serialize += '&action=' + action; + + var result = settings.onAjax(action, serialize); + + if (result === false) { + return false; + } + + var jqXHR = $.post(settings.url, serialize, function(data, textStatus, jqXHR) { + if (action === settings.buttons.edit.action) { + $lastEditedRow.removeClass(settings.dangerClass).addClass(settings.warningClass); + setTimeout(function() { + //$lastEditedRow.removeClass(settings.warningClass); + $table.find('tr.' + settings.warningClass).removeClass(settings.warningClass); + }, 1400); + } + + settings.onSuccess(data, textStatus, jqXHR); + }, 'json'); + + jqXHR.fail(function(jqXHR, textStatus, errorThrown) { + if (action === settings.buttons.delete.action) { + $lastDeletedRow.removeClass(settings.mutedClass).addClass(settings.dangerClass); + $lastDeletedRow.find('.tabledit-toolbar button').attr('disabled', false); + $lastDeletedRow.find('.tabledit-toolbar .tabledit-restore-button').hide(); + } else if (action === settings.buttons.edit.action) { + $lastEditedRow.addClass(settings.dangerClass); + } + + settings.onFail(jqXHR, textStatus, errorThrown); + }); + + jqXHR.always(function() { + settings.onAlways(); + }); + + return jqXHR; + } + + Draw.columns.identifier(); + Draw.columns.editable(); + Draw.columns.toolbar(); + + settings.onDraw(); + + if (settings.deleteButton) { + /** + * Delete one row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-delete-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Get current state before reset to view mode. + var activated = $(this).hasClass('active'); + + var $td = $(this).parents('td'); + + Delete.reset($td); + + if (!activated) { + Delete.confirm($td); + } + + event.handled = true; + } + }); + + /** + * Delete one row (confirm). + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-confirm-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + var $td = $(this).parents('td'); + + Delete.submit($td); + + event.handled = true; + } + }); + } + + if (settings.restoreButton) { + /** + * Restore one row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-restore-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + Delete.restore($(this).parents('td')); + + event.handled = true; + } + }); + } + + if (settings.editButton) { + /** + * Activate edit mode on all columns. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-edit-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + var $button = $(this); + + // Get current state before reset to view mode. + var activated = $button.hasClass('active'); + + // Change to view mode columns that are in edit mode. + Edit.reset($table.find('td.tabledit-edit-mode')); + + if (!activated) { + // Change to edit mode for all columns in reverse way. + $($button.parents('tr').find('td.tabledit-view-mode').get().reverse()).each(function() { + Mode.edit(this); + }); + } + + event.handled = true; + } + }); + + /** + * Save edited row. + * + * @param {object} event + */ + $table.on('click', 'button.tabledit-save-button', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Submit and update all columns. + Edit.submit($(this).parents('tr').find('td.tabledit-edit-mode')); + + event.handled = true; + } + }); + } else { + /** + * Change to edit mode on table td element. + * + * @param {object} event + */ + $table.on(settings.eventType, 'tr:not(.tabledit-deleted-row) td.tabledit-view-mode', function(event) { + if (event.handled !== true) { + event.preventDefault(); + + // Reset all td's in edit mode. + Edit.reset($table.find('td.tabledit-edit-mode')); + + // Change to edit mode. + Mode.edit(this); + + event.handled = true; + } + }); + + /** + * Change event when input is a select element. + */ + $table.on('change', 'select.tabledit-input:visible', function(event) { + if (event.handled !== true) { + // Submit and update the column. + Edit.submit($(this).parent('td')); + + event.handled = true; + } + }); + + /** + * Click event on document element. + * + * @param {object} event + */ + $(document).on('click', function(event) { + var $editMode = $table.find('.tabledit-edit-mode'); + // Reset visible edit mode column. + if (!$editMode.is(event.target) && $editMode.has(event.target).length === 0) { + Edit.reset($table.find('.tabledit-input:visible').parent('td')); + } + }); + } + + /** + * Keyup event on table element. + * + * @param {object} event + */ + $table.on('keyup', function(event) { + // Get input element with focus or confirmation button. + var $input = $table.find('.tabledit-input:visible'); + var $button = $table.find('.tabledit-confirm-button'); + + if ($input.length > 0) { + var $td = $input.parents('td'); + } else if ($button.length > 0) { + var $td = $button.parents('td'); + } else { + return; + } + + // Key? + switch (event.keyCode) { + case 9: // Tab. + if (!settings.editButton) { + Edit.submit($td); + Mode.edit($td.closest('td').next()); + } + break; + case 13: // Enter. + Edit.submit($td); + break; + case 27: // Escape. + Edit.reset($td); + Delete.reset($td); + break; + } + }); + + return this; + }; +}(jQuery)); + diff --git a/app/assets/stylesheets/_mixin.sass b/app/assets/stylesheets/_mixin.sass index 15bdbc7..c313bc1 100644 --- a/app/assets/stylesheets/_mixin.sass +++ b/app/assets/stylesheets/_mixin.sass @@ -1,3 +1,3 @@ -$main-background: #AF6D36 +//$main-background: #AF6D36 -$link-color: #AF6D36 +//$link-color: #AF6D36 diff --git a/app/assets/stylesheets/application.sass b/app/assets/stylesheets/application.sass index 0828ece..828d534 100644 --- a/app/assets/stylesheets/application.sass +++ b/app/assets/stylesheets/application.sass @@ -1,7 +1,9 @@ /* + *= require font-awesome *= require_tree . *= require_self */ @import 'mixin' @import 'bootstrap' +@import 'font-awesome' diff --git a/app/assets/stylesheets/emprunts.scss b/app/assets/stylesheets/emprunts.scss new file mode 100644 index 0000000..cbd1fc2 --- /dev/null +++ b/app/assets/stylesheets/emprunts.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the Emprunts controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/scaffolds.scss b/app/assets/stylesheets/scaffolds.scss new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/app/assets/stylesheets/scaffolds.scss @@ -0,0 +1 @@ + diff --git a/app/controllers/emprunts_controller.rb b/app/controllers/emprunts_controller.rb new file mode 100644 index 0000000..fd2ee5f --- /dev/null +++ b/app/controllers/emprunts_controller.rb @@ -0,0 +1,74 @@ +class EmpruntsController < ApplicationController + before_action :set_emprunt, only: [:show, :edit, :update, :destroy] + + # GET /emprunts + # GET /emprunts.json + def index + @emprunts = Emprunt.all + end + + # GET /emprunts/1 + # GET /emprunts/1.json + def show + end + + # GET /emprunts/new + def new + @emprunt = Emprunt.new + end + + # GET /emprunts/1/edit + def edit + end + + # POST /emprunts + # POST /emprunts.json + def create + @emprunt = Emprunt.new(emprunt_params) + + respond_to do |format| + if @emprunt.save + format.html { redirect_to @emprunt, notice: 'Emprunt was successfully created.' } + format.json { render :show, status: :created, location: @emprunt } + else + format.html { render :new } + format.json { render json: @emprunt.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /emprunts/1 + # PATCH/PUT /emprunts/1.json + def update + respond_to do |format| + if @emprunt.update(emprunt_params) + format.html { redirect_to @emprunt, notice: 'Emprunt was successfully updated.' } + format.json { render :show, status: :ok, location: @emprunt } + else + format.html { render :edit } + format.json { render json: @emprunt.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /emprunts/1 + # DELETE /emprunts/1.json + def destroy + @emprunt.destroy + respond_to do |format| + format.html { redirect_to emprunts_url, notice: 'Emprunt was successfully destroyed.' } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_emprunt + @emprunt = Emprunt.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def emprunt_params + params.require(:emprunt).permit(:idlivre, :nombre) + end +end diff --git a/app/controllers/livres_controller.rb b/app/controllers/livres_controller.rb index 3327d6a..a1dfab2 100644 --- a/app/controllers/livres_controller.rb +++ b/app/controllers/livres_controller.rb @@ -2,7 +2,7 @@ class LivresController < ApplicationController before_action :set_livre, only: [:show, :edit, :update, :destroy] def index - @livres = Livre.all + @livres = Livre.order(id: :desc) end def new @@ -10,29 +10,61 @@ class LivresController < ApplicationController end def edit - @livre = Livre.find(params[:id]) end def create @livre = Livre.new(livre_params) - if @livre.save - redirect_to @livre, success: 'livre créé' - else - render new_livre_path + respond_to do |format| + if @livre.save(livre_params) + format.js + format.html { redirect_to livres_path, notice: 'livre was successfully added.' } + format.json { render :index, status: :ok, location: livres_path } + else + format.html { render :new } + format.json { render json: @livre.errors, status: :unprocessable_entity } + end end end def update - if @livre.update(livre_params) - redirect_to @livre, success: 'livre mis à jour' - else - render edit_livre_path(@livre) + respond_to do |format| + if @livre.update(livre_params) + format.js + format.html { redirect_to @livre, success: 'livre mis à jour' } + format.json { render :index, status: :ok, location: livres_path } + else + format.html { render edit_livre_path(@livre) } + format.json { render json: @livre.errors, status: :unprocessable_entity } + end end end + # interaction avec table-edit +=begin + def tabledit + if params[:edit] + @livre = Livre.find(params[:id]) + respond_to do |format| + if @livre.update(livre_params) + format.html { redirect_to @livre, notice: 'livre was successfully updated.' } + format.json { render :index, status: :ok, location: livres_path } + else + format.html { render :edit } + format.json { render json: @livre.errors, status: :unprocessable_entity } + end + end + end + end +=end + def destroy @livre.destroy - redirect_to livres_url, success: 'livre supprimé' + respond_to do |format| + format.js + format.html { redirect_to livres_url, success: 'livre supprimé' } + format.json { head :no_content } + end + #redirect_to livres_url, success: 'livre supprimé' end private diff --git a/app/helpers/emprunts_helper.rb b/app/helpers/emprunts_helper.rb new file mode 100644 index 0000000..09168bb --- /dev/null +++ b/app/helpers/emprunts_helper.rb @@ -0,0 +1,2 @@ +module EmpruntsHelper +end diff --git a/app/helpers/livres_helper.rb b/app/helpers/livres_helper.rb index 8b51735..395c7d0 100644 --- a/app/helpers/livres_helper.rb +++ b/app/helpers/livres_helper.rb @@ -1,2 +1,11 @@ module LivresHelper + def link_to_add_book(name, f, association) + new_object = f.object.send(association).klass.new + id = new_object.object_id + fields = f.fields_for(association, new_object, child_index: id) do |builder| + render(association.to_s.singularize + "_fields", f: builder) + end + + link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")}) + end end diff --git a/app/models/emprunt.rb b/app/models/emprunt.rb new file mode 100644 index 0000000..25bff92 --- /dev/null +++ b/app/models/emprunt.rb @@ -0,0 +1,2 @@ +class Emprunt < ApplicationRecord +end diff --git a/app/views/emprunts/_emprunt.json.jbuilder b/app/views/emprunts/_emprunt.json.jbuilder new file mode 100644 index 0000000..7f61ccb --- /dev/null +++ b/app/views/emprunts/_emprunt.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! emprunt, :id, :idlivre, :nombre, :created_at, :updated_at +json.url emprunt_url(emprunt, format: :json) diff --git a/app/views/emprunts/_form.html.erb b/app/views/emprunts/_form.html.erb new file mode 100644 index 0000000..fcd165f --- /dev/null +++ b/app/views/emprunts/_form.html.erb @@ -0,0 +1,27 @@ +<%= form_with(model: emprunt, local: true) do |form| %> + <% if emprunt.errors.any? %> +
+

<%= pluralize(emprunt.errors.count, "error") %> prohibited this emprunt from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :idlivre %> + <%= form.number_field :idlivre %> +
+ +
+ <%= form.label :nombre %> + <%= form.number_field :nombre %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/emprunts/edit.html.erb b/app/views/emprunts/edit.html.erb new file mode 100644 index 0000000..3d57fe2 --- /dev/null +++ b/app/views/emprunts/edit.html.erb @@ -0,0 +1,6 @@ +

Editing Emprunt

+ +<%= render 'form', emprunt: @emprunt %> + +<%= link_to 'Show', @emprunt %> | +<%= link_to 'Back', emprunts_path %> diff --git a/app/views/emprunts/index.html.erb b/app/views/emprunts/index.html.erb new file mode 100644 index 0000000..23a78cd --- /dev/null +++ b/app/views/emprunts/index.html.erb @@ -0,0 +1,29 @@ +

<%= notice %>

+ +

Emprunts

+ + + + + + + + + + + + <% @emprunts.each do |emprunt| %> + + + + + + + + <% end %> + +
IdlivreNombre
<%= emprunt.idlivre %><%= emprunt.nombre %><%= link_to 'Show', emprunt %><%= link_to 'Edit', edit_emprunt_path(emprunt) %><%= link_to 'Destroy', emprunt, method: :delete, data: { confirm: 'Are you sure?' } %>
+ +
+ +<%= link_to 'New Emprunt', new_emprunt_path %> diff --git a/app/views/emprunts/index.json.jbuilder b/app/views/emprunts/index.json.jbuilder new file mode 100644 index 0000000..d9b7705 --- /dev/null +++ b/app/views/emprunts/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @emprunts, partial: "emprunts/emprunt", as: :emprunt diff --git a/app/views/emprunts/new.html.erb b/app/views/emprunts/new.html.erb new file mode 100644 index 0000000..1b851a5 --- /dev/null +++ b/app/views/emprunts/new.html.erb @@ -0,0 +1,5 @@ +

New Emprunt

+ +<%= render 'form', emprunt: @emprunt %> + +<%= link_to 'Back', emprunts_path %> diff --git a/app/views/emprunts/show.html.erb b/app/views/emprunts/show.html.erb new file mode 100644 index 0000000..642f509 --- /dev/null +++ b/app/views/emprunts/show.html.erb @@ -0,0 +1,14 @@ +

<%= notice %>

+ +

+ Idlivre: + <%= @emprunt.idlivre %> +

+ +

+ Nombre: + <%= @emprunt.nombre %> +

+ +<%= link_to 'Edit', edit_emprunt_path(@emprunt) %> | +<%= link_to 'Back', emprunts_path %> diff --git a/app/views/emprunts/show.json.jbuilder b/app/views/emprunts/show.json.jbuilder new file mode 100644 index 0000000..521a4e0 --- /dev/null +++ b/app/views/emprunts/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "emprunts/emprunt", emprunt: @emprunt diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index cbf8168..525a372 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -30,5 +30,6 @@ <%= yield %> + <%#= javascript_include_tag 'livres.js' %> diff --git a/app/views/livres/_form.html.erb b/app/views/livres/_form.html.erb index ea84844..2df1c3e 100644 --- a/app/views/livres/_form.html.erb +++ b/app/views/livres/_form.html.erb @@ -14,20 +14,15 @@ <% end %> - <%= form.label :titre %> - <%= form.text_field :titre %> + <%= form.text_field :titre, placeholder: :titre %> - <%= form.label :auteur %> - <%= form.text_field :auteur %> + <%= form.text_field :auteur, placeholder: :auteur %> - <%= form.label :synopsis %> - <%= form.textarea_field :synopsis %> + <%= form.text_field :synopsis, placeholder: :synopsis %> - <%= form.label :style %> - <%= form.text_field :style %> + <%= form.text_field :style, placeholder: :style %> - <%= form.label :isbn %> - <%= form.text_field :isbn %> + <%= form.text_field :isbn, placeholder: :isbn %> <%= form.submit :submit %> <% end %> diff --git a/app/views/livres/_livre.html.erb b/app/views/livres/_livre.html.erb new file mode 100644 index 0000000..b535ebd --- /dev/null +++ b/app/views/livres/_livre.html.erb @@ -0,0 +1,11 @@ + + <%= livre.titre %> + <%= livre.auteur %> + <%= livre.synopsis[0..120] %> + <%= livre.style %> + <%= livre.isbn %> + + <%= link_to 'Edit', edit_livre_path(livre), remote: true %> + <%= link_to 'Destroy', livre, method: :delete, data: { confirm: 'Supprimer la donnée de façon définitive ?', remote: true }, class: 'delete' %> + + diff --git a/app/views/livres/_livre.json.jbuilder b/app/views/livres/_livre.json.jbuilder new file mode 100644 index 0000000..e0394de --- /dev/null +++ b/app/views/livres/_livre.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! livre, :id, :titre, :auteur, :synopsis, :style, :isbn +json.url livre_url(livre, format: :json) diff --git a/app/views/livres/create.js.erb b/app/views/livres/create.js.erb new file mode 100644 index 0000000..40267d5 --- /dev/null +++ b/app/views/livres/create.js.erb @@ -0,0 +1,3 @@ +$('table#livres > tbody form').remove(); +$('#new-book a').show(); +$('table#livres tbody').prepend('<%= j render @livre %>'); diff --git a/app/views/livres/destroy.js.erb b/app/views/livres/destroy.js.erb new file mode 100644 index 0000000..b27dd71 --- /dev/null +++ b/app/views/livres/destroy.js.erb @@ -0,0 +1,3 @@ +$('.delete').bind('ajax:success', function() { + $(this).closest('tr').fadeOut(); +}); diff --git a/app/views/livres/index.html.erb b/app/views/livres/index.html.erb index 0384340..74266d8 100644 --- a/app/views/livres/index.html.erb +++ b/app/views/livres/index.html.erb @@ -1,35 +1,26 @@

Tableau de mes livres

<% if @livres.size > 0 %> - - - - - - - - - - - - - - - - <% @livres.each do |livre| %> +
+
#TitreAuteurSynopsisStyleISBNAction
+ - - - - - - - + + + + + + - <% end %> - -
<%= livre.id %><%= livre.titre %><%= livre.auteur %><%= livre.synopsis[0..120] %><%= livre.style %><%= livre.isbn %><%= link_to 'Edit', edit_livre_path(livre) %>TitreAuteurSynopsisStyleISBNAction
+ + + <%= render @livres %> + + + <% end %> -<%= link_to 'Nouveau livre', new_livre_path %> +
+ <%= link_to 'Nouveau livre', new_livre_path, remote: true %> +
diff --git a/app/views/livres/index.json.jbuilder b/app/views/livres/index.json.jbuilder new file mode 100644 index 0000000..0c6fae2 --- /dev/null +++ b/app/views/livres/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @livres, partial: "livres/livre", as: :livre diff --git a/app/views/livres/new.js.erb b/app/views/livres/new.js.erb new file mode 100644 index 0000000..fa0b5a8 --- /dev/null +++ b/app/views/livres/new.js.erb @@ -0,0 +1 @@ +$('#new-book a').hide().parent().append("<%= j render 'form', livre: @livre %>"); diff --git a/app/views/livres/show.html.erb b/app/views/livres/show.html.erb new file mode 100644 index 0000000..34b2998 --- /dev/null +++ b/app/views/livres/show.html.erb @@ -0,0 +1,29 @@ +

<%= notice %>

+ +

+ Titre : + <%= @livre.titre %> +

+ +

+ Auteur : + <%= @livre.auteur %> +

+ +

+ Synopsis : + <%= @livre.synopsis %> +

+ +

+ Style : + <%= @livre.style %> +

+ +

+ ISBN : + <%= @livre.isbn %> +

+ +<%= link_to 'Edit', edit_livre_path(@livre) %> | +<%= link_to 'Back', livres_path %> diff --git a/app/views/livres/show.json.jbuilder b/app/views/livres/show.json.jbuilder new file mode 100644 index 0000000..b11ccd7 --- /dev/null +++ b/app/views/livres/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "livres/livre", livre: @livre diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 4b828e8..96babfb 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -12,3 +12,4 @@ Rails.application.config.assets.paths << Rails.root.join('node_modules') # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. # Rails.application.config.assets.precompile += %w( admin.js admin.css ) +Rails.application.config.assets.precompile += %w( livres.js ) diff --git a/config/routes.rb b/config/routes.rb index b479fc4..f76866c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ Rails.application.routes.draw do - get 'livres/index' + resources :emprunts # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html resources :livres - + post '/livres/tabledit' => 'livres#tabledit' end diff --git a/db/migrate/20200217133444_create_emprunts.rb b/db/migrate/20200217133444_create_emprunts.rb new file mode 100644 index 0000000..a0d73aa --- /dev/null +++ b/db/migrate/20200217133444_create_emprunts.rb @@ -0,0 +1,10 @@ +class CreateEmprunts < ActiveRecord::Migration[5.2] + def change + create_table :emprunts do |t| + t.integer :idlivre + t.integer :nombre + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4a17921..0344e74 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_02_03_130314) do +ActiveRecord::Schema.define(version: 2020_02_17_133444) do + + create_table "emprunts", force: :cascade do |t| + t.integer "idlivre" + t.integer "nombre" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end create_table "livres", force: :cascade do |t| t.string "titre" diff --git a/test/controllers/emprunts_controller_test.rb b/test/controllers/emprunts_controller_test.rb new file mode 100644 index 0000000..d0d485c --- /dev/null +++ b/test/controllers/emprunts_controller_test.rb @@ -0,0 +1,48 @@ +require 'test_helper' + +class EmpruntsControllerTest < ActionDispatch::IntegrationTest + setup do + @emprunt = emprunts(:one) + end + + test "should get index" do + get emprunts_url + assert_response :success + end + + test "should get new" do + get new_emprunt_url + assert_response :success + end + + test "should create emprunt" do + assert_difference('Emprunt.count') do + post emprunts_url, params: { emprunt: { idlivre: @emprunt.idlivre, nombre: @emprunt.nombre } } + end + + assert_redirected_to emprunt_url(Emprunt.last) + end + + test "should show emprunt" do + get emprunt_url(@emprunt) + assert_response :success + end + + test "should get edit" do + get edit_emprunt_url(@emprunt) + assert_response :success + end + + test "should update emprunt" do + patch emprunt_url(@emprunt), params: { emprunt: { idlivre: @emprunt.idlivre, nombre: @emprunt.nombre } } + assert_redirected_to emprunt_url(@emprunt) + end + + test "should destroy emprunt" do + assert_difference('Emprunt.count', -1) do + delete emprunt_url(@emprunt) + end + + assert_redirected_to emprunts_url + end +end diff --git a/test/fixtures/emprunts.yml b/test/fixtures/emprunts.yml new file mode 100644 index 0000000..0f7169e --- /dev/null +++ b/test/fixtures/emprunts.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + idlivre: 1 + nombre: 1 + +two: + idlivre: 1 + nombre: 1 diff --git a/test/models/emprunt_test.rb b/test/models/emprunt_test.rb new file mode 100644 index 0000000..24362ca --- /dev/null +++ b/test/models/emprunt_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class EmpruntTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/emprunts_test.rb b/test/system/emprunts_test.rb new file mode 100644 index 0000000..6ff1455 --- /dev/null +++ b/test/system/emprunts_test.rb @@ -0,0 +1,45 @@ +require "application_system_test_case" + +class EmpruntsTest < ApplicationSystemTestCase + setup do + @emprunt = emprunts(:one) + end + + test "visiting the index" do + visit emprunts_url + assert_selector "h1", text: "Emprunts" + end + + test "creating a Emprunt" do + visit emprunts_url + click_on "New Emprunt" + + fill_in "Idlivre", with: @emprunt.idlivre + fill_in "Nombre", with: @emprunt.nombre + click_on "Create Emprunt" + + assert_text "Emprunt was successfully created" + click_on "Back" + end + + test "updating a Emprunt" do + visit emprunts_url + click_on "Edit", match: :first + + fill_in "Idlivre", with: @emprunt.idlivre + fill_in "Nombre", with: @emprunt.nombre + click_on "Update Emprunt" + + assert_text "Emprunt was successfully updated" + click_on "Back" + end + + test "destroying a Emprunt" do + visit emprunts_url + page.accept_confirm do + click_on "Destroy", match: :first + end + + assert_text "Emprunt was successfully destroyed" + end +end