Почему всплывающее окно не закрывается нажатием клавиши ввода - PullRequest
1 голос
/ 09 марта 2019

У меня проблема с закрытием всплывающего окна, а navigating с keyboard arrow

Как воспроизвести:

  1. нажмите клавишу вверх / вниз, чтобы строка была выделена красным цветом
  2. нажмите клавишу ввода, и появится всплывающее окно

  3. нажмите клавишу ввода еще раз (всплывающее окно должно закрыться, как этого добиться?).

Вопрос: Всплывающее окно не закрывается нажатием Enter, я хочу закрыть его.

Для лучшего обзора я сделал кодовый шарик: https://codepen.io/anon/pen/ZPypBM

function showErrorAlert(msg){
     $.alertable.alert(msg);
}


$(function(){
    var li = $('.rtable tbody tr');
    var liSelected;
    $(window).keydown(function(e){
       
      // code for enter key press
      
      if(e.which == 13){
           showErrorAlert('Some Unknown Error Has Occured.');
           return false;
       }
     
        if(e.which === 40){
            if(liSelected){
                liSelected.removeClass('selected');
                next = liSelected.next();
                if(next.length > 0){
                    liSelected = next.addClass('selected');
                }else{
                    liSelected = li.eq(0).addClass('selected');
                }
            }else{
                liSelected = li.eq(0).addClass('selected');
            }
        }else if(e.which === 38){
            if(liSelected){
                liSelected.removeClass('selected');
                next = liSelected.prev();
                if(next.length > 0){
                    liSelected = next.addClass('selected');
                }else{
                    liSelected = li.last().addClass('selected');
                }
            }else{
                liSelected = li.last().addClass('selected');
            }
        }
    });
});



// alertable plugin

//
// jquery.alertable.js - Minimal alert, confirmation, and prompt alternatives.
//
// Developed by Cory LaViska for A Beautiful Site, LLC
//
// Licensed under the MIT license: http://opensource.org/licenses/MIT
//
if(jQuery) (function($) {
  'use strict';

  var modal;
  var overlay;
  var okButton;
  var cancelButton;
  var activeElement;

  function show(type, message, options) {
    var defer = $.Deferred();

    // Remove focus from the background
    activeElement = document.activeElement;
    activeElement.blur();

    // Remove other instances
    $(modal).add(overlay).remove();

    // Merge options
    options = $.extend({}, $.alertable.defaults, options);

    // Create elements
    modal = $(options.modal).hide();
    overlay = $(options.overlay).hide();
    okButton = $(options.okButton);
    cancelButton = $(options.cancelButton);

    // Add message
    if(options.html) {
      modal.find('.alertable-message').html(message);
    } else {
      modal.find('.alertable-message').text(message);
    }

    // Add prompt
    if(type === 'prompt') {
      modal.find('.alertable-prompt').html(options.prompt);
    } else {
      modal.find('.alertable-prompt').remove();
    }

    // Add buttons
    $(modal).find('.alertable-buttons')
    .append(type === 'alert' ? '' : cancelButton)
    .append(okButton);

    // Add to container
    $(options.container).append(overlay).append(modal);

    // Show it
    options.show.call({
      modal: modal,
      overlay: overlay
    });

    // Set focus
    if(type === 'prompt') {
      // First input in the prompt
      $(modal).find('.alertable-prompt :input:first').focus();
    } else {
      // OK button
      $(modal).find(':input[type="submit"]').focus();
    }

    // Watch for submit
    $(modal).on('submit.alertable', function(event) {
      var i;
      var formData;
      var values = [];

      event.preventDefault();

      if(type === 'prompt') {
        formData = $(modal).serializeArray();
        for(i = 0; i < formData.length; i++) {
          values[formData[i].name] = formData[i].value;
        }
      } else {
        values = null;
      }

      hide(options);
      defer.resolve(values);
    });

    // Watch for cancel
    cancelButton.on('click.alertable', function() {
      hide(options);
      defer.reject();
    });

    // Cancel on escape
    $(document).on('keydown.alertable', function(event) {
      if(event.keyCode === 27) {
        event.preventDefault();
        hide(options);
        defer.reject();
      }
    });

    // Prevent focus from leaving the modal
    $(document).on('focus.alertable', '*', function(event) {
      if(!$(event.target).parents().is('.alertable')) {
        event.stopPropagation();
        event.target.blur();
        $(modal).find(':input:first').focus();
      }
    });

    return defer.promise();
  }

  function hide(options) {
    // Hide it
    options.hide.call({
      modal: modal,
      overlay: overlay
    });

    // Remove bindings
    $(document).off('.alertable');
    modal.off('.alertable');
    cancelButton.off('.alertable');

    // Restore focus
    activeElement.focus();
  }

  // Defaults
  $.alertable = {
    // Show an alert
    alert: function(message, options) {
      return show('alert', message, options);
    },

    // Show a confirmation
    confirm: function(message, options) {
      return show('confirm', message, options);
    },

    // Show a prompt
    prompt: function(message, options) {
      return show('prompt', message, options);
    },

    defaults: {
      // Preferences
      container: 'body',
      html: false,

      // Templates
      cancelButton: '<button class="alertable-cancel" type="button">Cancel</button>',
      okButton: '<button class="alertable-ok" type="submit">OK</button>',
      overlay: '<div class="alertable-overlay"></div>',
      prompt: '<input class="alertable-input" type="text" name="value">',
      modal:
        '<form class="alertable">' +
        '<div class="alertable-message"></div>' +
        '<div class="alertable-prompt"></div>' +
        '<div class="alertable-buttons"></div>' +
        '</form>',

      // Hooks
      hide: function() {
        $(this.modal).add(this.overlay).fadeOut(100);
      },
      show: function() {
        $(this.modal).add(this.overlay).fadeIn(100);
      }
    }
  };
})(jQuery);
.selected{
    background:red;
}


.rtable {
  /*!
  // IE needs inline-block to position scrolling shadows otherwise use:
  // display: block;
  // max-width: min-content;
  */
  display: inline-block;
  vertical-align: top;
  max-width: 100%;
  
  overflow-x: auto;
  
  // optional - looks better for small cell values
  white-space: nowrap;

  border-collapse: collapse;
  border-spacing: 0;
}

.rtable,
.rtable--flip tbody {
  // optional - enable iOS momentum scrolling
  -webkit-overflow-scrolling: touch;
  
  // scrolling shadows
  background: radial-gradient(left, ellipse, rgba(0,0,0, .2) 0%, rgba(0,0,0, 0) 75%) 0 center,
              radial-gradient(right, ellipse, rgba(0,0,0, .2) 0%, rgba(0,0,0, 0) 75%) 100% center;
  background-size: 10px 100%, 10px 100%;
  background-attachment: scroll, scroll;
  background-repeat: no-repeat;
}

// change these gradients from white to your background colour if it differs
// gradient on the first cells to hide the left shadow
.rtable td:first-child,
.rtable--flip tbody tr:first-child {
  background-image: linear-gradient(to right, rgba(255,255,255, 1) 50%, rgba(255,255,255, 0) 100%);
  background-repeat: no-repeat;
  background-size: 20px 100%;
}

// gradient on the last cells to hide the right shadow
.rtable td:last-child,
.rtable--flip tbody tr:last-child {
  background-image: linear-gradient(to left, rgba(255,255,255, 1) 50%, rgba(255,255,255, 0) 100%);
  background-repeat: no-repeat;
  background-position: 100% 0;
  background-size: 20px 100%;
}

.rtable th {
  font-size: 11px;
  text-align: left;
  text-transform: uppercase;
  background: #f2f0e6;
}

.rtable th,
.rtable td {
  padding: 6px 12px;
  border: 1px solid #d9d7ce;
}

.rtable--flip {
  display: flex;
  overflow: hidden;
  background: none;
}

.rtable--flip thead {
  display: flex;
  flex-shrink: 0;
  min-width: min-content;
}

.rtable--flip tbody {
  display: flex;
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
}

.rtable--flip tr {
  display: flex;
  flex-direction: column;
  min-width: min-content;
  flex-shrink: 0;
}

.rtable--flip td,
.rtable--flip th {
  display: block;
}

.rtable--flip td {
  background-image: none !important;
  // border-collapse is no longer active
  border-left: 0;
}

// border-collapse is no longer active
.rtable--flip th:not(:last-child),
.rtable--flip td:not(:last-child) {
  border-bottom: 0;
}


/* alertable plugin css code */

/*
//
// Tip: to integrate this plugin seamlessly into your application, use these styles as a starting
// point to build your own stylish alerts and confirmations!
//
*/

/* Modal */
.alertable {
  position: fixed;
  z-index: 9999;
  top: 38vh;
  left: calc(50% - 150px);
  width: 300px;
  background: white;
  border-radius: 4px;
  padding: 20px;
  margin: 0 auto;
}

/* Overlay */
.alertable-overlay {
  position: fixed;
  z-index: 9998;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, .5);
}

/* Message */
.alertable-message {
  margin-bottom: 20px;
}

/* Prompt */
.alertable-prompt {
  margin-bottom: 20px;
}

.alertable-input {
  width: 100%;
  border-radius: 4px;
  box-shadow: none;
  border: solid 1px #ccc;
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  padding: 6px 12px;
  display: block;
  box-sizing: border-box;
  margin-bottom: 10px;
}

/* Button group */
.alertable-buttons {
  text-align: right;
}

/* OK button */
.alertable-ok {
  background: #09d;
  border: solid 1px #09d;
  font-family: inherit;
  font-size: inherit;
  color: white;
  border-radius: 4px;
  padding: 6px 12px;
  margin-left: 4px;
  cursor: pointer;
}

.alertable-ok:hover,
.alertable-ok:focus,
.alertable-ok:active {
  background-color: #08c;
}

/* Cancel button */
.alertable-cancel {
  border: solid 1px #ddd;
  background: white;
  font-family: inherit;
  font-size: inherit;
  color: #888;
  border-radius: 4px;
  padding: 6px 12px;
  margin-left: 4px;
  cursor: pointer;
}

.alertable-cancel:hover,
.alertable-cancel:focus,
.alertable-cancel:active {
  background-color: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="rtable">
  <thead>
    <tr>
      <th>Browser</th>
      <th>Sessions</th>
      <th>Percentage</td>
      <th>New Users</th>
      <th>Avg. Duration</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Chrome</td>
      <td>9,562</td>
      <td>68.81%</td>
      <td>7,895</td>
      <td>01:07</td>
    </tr>
    <tr>
      <td>Firefox</td>
      <td>2,403</td>
      <td>17.29%</td>
      <td>2,046</td>
      <td>00:59</td>
    </tr>
    <tr>
      <td>Safari</td>
      <td>1,089</td>
      <td>2.63%</td>
      <td>904</td>
      <td>00:59</td>
    </tr>
    <tr>
      <td>Internet Explorer</td>
      <td>366</td>
      <td>2.63%</td>
      <td>333</td>
      <td>01:01</td>
    </tr>
    <tr>
      <td>Safari (in-app)</td>
      <td>162</td>
      <td>1.17%</td>
      <td>112</td>
      <td>00:58</td>
    </tr>
    <tr>
      <td>Opera</td>
      <td>103</td>
      <td>0.74%</td>
      <td>87</td>
      <td>01:22</td>
    </tr>
    <tr>
      <td>Edge</td>
      <td>98</td>
      <td>0.71%</td>
      <td>69</td>
      <td>01:18</td>
    </tr>
    <tr>
      <td>Other</td>
      <td>275</td>
      <td>6.02%</td>
      <td>90</td>
      <td>N/A</td>
    </tr>
  </tbody>
</table>

Пожалуйста, помогите мне заранее спасибо !!

Ответы [ 3 ]

2 голосов
/ 09 марта 2019

Добавьте это под '// Cancel on escape'

Я заметил, что нажатие escape уже работает

// Cancel on return
$(document).on('keydown.alertable', function(event) {
  if(event.keyCode === 13) {        
    hide(options);
    defer.reject();
    return false;
  }
});
1 голос
/ 09 марта 2019

Вы выполняете тот же блок кода при нажатии клавиши ввода, вам нужна какая-то переключаемая переменная.Я изменил ваш Codepen

В основном это можно сделать:

var shown = false;

if(e.which == 13){
   if(!shown){
     showErrorAlert('Some Unknown Error Has Occured.');           
   }else{
     // hide
     $(".alertable, .alertable-overlay").fadeOut(500)
   }
   shown = !shown;
   return false;
}
0 голосов
/ 09 марта 2019

Мне кажется, проблема в том, что у вас есть прослушиватель событий для клавиши "Enter", связанный с window. Поэтому, когда ваш модал всплывает и вы нажимаете ввод, прослушиватель событий на элементе window снова вызывает ваш модал.

Вы можете сделать что-то вроде этого, чтобы увидеть, если модальный виден:

if (e.which == 13 && !$(".alertable").is(":visible")){
   showErrorAlert('Some Unknown Error Has Occured.');
   return false;
}

Показывает модальный сигнал тревоги, только если он в данный момент не виден.

...