#ajax 버튼을 클릭 할 때 JS 확인 팝업을 추가하는 방법


10

#ajax를 사용하는 기본 FAPI 버튼 입력이 있고 제대로 작동하지만 JS "Are you sure?"를 추가하고 싶습니다. 코드가 실제로 실행되기 전에 버튼을 클릭하면 확인 팝업이 표시되며 FAPI의 JS가 클릭을 먹기 전에 클릭을 먹는 것처럼 보이기 때문에 어떻게 해야할지 모르겠습니다.

인라인 onclick 핸들러를 추가하려고 시도했습니다.

$form['search_filters']['channels']['channel_delete_' . $channel->nid] = array(
  '#type' => 'button',
  '#name' => 'channel_delete_' . $channel->nid,
  '#value' => 'Delete',
  '#attributes' => array(
    'class' => array('confirm'),
    'onclick' => "return confirm('Are you sure you want to delete that?')"
  ),
  '#button_type' => 'no-submit',
  '#ajax' => array(
    'callback' => 'delete_channel_callback',
    'wrapper' => 'channel_container_' . $channel->nid
  ),
);

... 도움이되지 않으며 추가를 시도했습니다.

$('.confirm').click(function(e) {
  e.preventDefault();
  alert('Is this recognized')? // never runs
});

내 모듈의 JS에서도 무시됩니다.

다른 아이디어가 있습니까? Drupal #ajax가 인식 할 스택의 맨 위에 제출 핸들러를 추가하는 방법이 있습니까?

답변:


15

Drupal은 PHP 프레임 워크이며, AAPI와 FAPI를 사용할 수있는 멋진 기능을 제공합니다. 그러나 한계가 있으며 이와 같은 유스 케이스의 경우 사용자 정의 JavaScript를 사용하는 것이 좋습니다. 또한 일반적으로 JavaScript 대화 상자를 사용하는 대신 jQuery UI를 사용하여 대신 대화 가능한 대화 상자를 작성할 수 있습니다.

어쨌든 제출 버튼에서 AJAX를 사용하기 때문에 직면 한 문제가 발생했을 수 있습니다. 실제 삭제 호출에 AJAX를 사용하고 있기 때문에 preventDefault작동하지 않습니다.

당신이해야 할 일은 이와 같은 것입니다. (이는 널리 테스트되지는 않았지만 작동해야합니다.)

Drupal.behaviors.module = {
  attach: function() {

    var events = $('.confirm').data('events'); // Get the jQuery events.
    $('.confirm').unbind('click'); // Remove the click events.
    $('.confirm').click(function () {
      if (confirm('Are you sure you want to delete that?')) {
        $.each(events.click, function() {
          this.handler(); // Invoke the click handlers that was removed.
        });
      }
      // Prevent default action.
      return false;
    });
  }
}

나는 또한 $ ( '. confirm'). unbind ( 'mousedown'); 드루팔 리스터는 '마우스 다운'이벤트도합니다.
milkovsky

사용자가 확인 대화 상자를 취소 한 다음 다시 클릭하면 버튼이 끊어지지 않습니까? (왜냐하면 $('.confirm').unbind('click');) ... 또는 내가 잘못 읽고 있습니까? 에 익숙하지 않아 죄송합니다unbind
ErichBSchulz

1
@ErichBSchulz Unbind는 페이지로드시 호출되는 attach 메소드에 의해 한 번만 호출됩니다.
googletorp

gist.github.com/guoxiangke/0dffa7722a67f052c7ce Uncaught TypeError : undefined의 'click'속성을 읽을 수 없습니다 ?????? 나는 노드 / 추가 / 콘텐츠 형식에 양식을 가지고, 나는, 사용 JS 유효성 검사를 아약스
bluesky_still

4

Jeroen이 Googletorp의 코드를 수정하고 있음을 확인합니다.

그러나, 나는 "mousedown"타입의 짝수를 금지하고 다시 묶어야한다는 것을 스스로 발견했다. 그래서 나를 위해 일한 코드는 다음과 같습니다.

(function ($) {
  Drupal.behaviors.confirm = {
    attach: function(context, settings) {
      var events =  $('.form-submit-delete').clone(true).data('events');// Get the jQuery events.
      $('.form-submit-delete').unbind('mousedown'); // Remove the click events.
      $('.form-submit-delete').mousedown(function () {
    if (confirm('Are you sure you want to delete that?')) {
      $.each(events.mousedown, function() {
        this.handler(); // Invoke the mousedown handlers that was removed.
      });
    }
    // Prevent default action.
    return false;
      });
    }
  }
})(jQuery);

DOM 객체를 실제로 필요로하지 않는 한 복제하는 것은 실제로 리소스 낭비입니다.
googletorp

안녕하세요, 같은 질문을 만났지만 모두 잘 진행되었지만 js 오류가 발생했습니다. "Uncaught TypeError : 정의되지 않은 'click'속성을 읽을 수 없습니다.
bluesky_still

이것이 내가 일할 수있는 유일한 솔루션입니다. 여기서 복제가 핵심입니다. 클론이 없으면 확인을 클릭하면 경고가 즉시 다시 나타납니다.
Felix Eve

4

그 질문은 오래되었지만 나는 그것에 관심이있었습니다. 제 생각에 가장 쉬운 방법은 Drupal이 mousedown 이벤트를 기본값으로 사용하기 때문에 Ajax 정의에서 click 이벤트를 사용하는 것입니다.

$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('some value'),
  '#attributes' => array(
    'class' => array('some-class'),
    ),
  '#ajax' => array(
    'event' => 'click',    //add this line!
    'callback' => 'some_callback',
    'wrapper' => 'some-wrapper',
  ),
);

그런 다음 .mousedown()클릭 이벤트 전에 시작되므로 Javascript 파일의 버튼에 이벤트 를 추가하면 됩니다.

$('.some-class').mousedown(function() {
  //do something
});

여전히 mousedown 이벤트로 Ajax 요청을 호출하려면 사용자 정의 이벤트를 사용할 수 있습니다.

//change this line in the Ajax Defintion of your button
'event' => 'click',
//to
'event' => 'custom_event',

그런 다음 .mousedown()Javascript 파일 이있는 경우이 이벤트를 트리거 할 수 있습니다 .

$('.some-class').mousedown(function() {
  //do something
  $('.some-class').trigger('custom_event');
});

두 버전 모두 작동합니다!


네! 나는 이것이 당신이 원하는 것을하기 때문에 이것을 좋아합니다 : Drupal 기성품 프로세스에 대한 핸들을 제공하고 필요할 때 호출 할 수 있습니다. Nb. 나는이 필요 preventDefault여전히 양식의 제출을 일반 (비 JS)을 방지하기 위해 내 클릭 핸들러를.
artfulrobot 2016 년

0

Drupal 동작 내에서 JS를 실행 해 보셨습니까? Drupal 이후에 클릭 핸들러가 첨부 된 것일 수 있습니다.

두 가지 방법 중 하나를 사용하면 버튼에서 Drupal의 클릭 핸들러를 바인딩 해제 할 수 있어야하므로 먼저 호출되며 Drupal의 Ajax 클릭 핸들러를 수동으로 (조건부로) 호출 할 수 있습니다.


0

googletorp의 코드가 100 % 정확하지 않다는 점에 응답합니다.

이벤트가 저장된 라인을 다음과 같이 변경해야합니다.

var events = $('.confirm').clone(true).data('events'); // Get the jQuery events.

이런 식으로 객체 참조 문제를 제거하므로 클릭 이벤트를 바인딩 해제 할 때 var에서도 바인딩 해제되지 않습니다.)

또한 jQuery 1.8부터 .data () 메소드는 더 이상 사용되지 않습니다. 내부 데이터 구조를 통해 이벤트 데이터 가져 오기가 완료되었습니다.

.data ( "events") : jQuery는 이벤트 관련 데이터를 각 요소의 (대기) 이벤트라는 데이터 객체에 저장합니다. 이것은 내부 데이터 구조이므로 1.8에서는 사용자 데이터 네임 스페이스에서 제거되므로 동일한 이름의 항목과 충돌하지 않습니다. jQuery의 이벤트 데이터는 여전히 jQuery._data (element, "events")를 통해 액세스 할 수 있지만 이는 문서화되지 않았으며 수정해서는 안되는 내부 데이터 구조입니다.

출처 : http://blog.jquery.com/2011/11/08/building-a-slimmer-jquery/


0

위의 많은 유용한 답변을 찾았으며 양식을 작동시킬 수있었습니다. 이를 종합하면 다음과 같이 응용 프로그램에서 작동합니다. 확인 대화 상자와 AJAX 콜백이있는 양식 삭제 버튼으로 선택 목록의 내용을 수정하십시오.

자바 스크립트 :

$form['my_form']['delete_button_js'] = array(
  '#markup' => '<script type="text/javascript">
  (function ($) {
     // override the default confirmation dialog behavior
     Drupal.behaviors.confirm = { 

      // Get the jQuery events.
      attach: function(context, settings) {
      var events =  $(\'.deleteButtonClass\').clone(true).data(\'events\'); 

      $(\'.deleteButtonClass\').unbind(\'mousedown\'); // Remove the mousedown event.

      $(\'.deleteButtonClass\').mousedown(function () { 
           // Popup the confirmation
           if (confirm(\'Are you sure you want to delete the Group?\')) {
             // if YES, then we fire the AJAX event 
             $(\'.deleteButtonClass\').trigger(\'deleteGroupEvent\'); 
           }
           // Override the default action.
           return false;
        });
    }
            }
  })(jQuery);
  </script>
  ',
);

수정할 양식 요소 (선택 목록) :

$form['my_form']['select_list'] = array(
         '#type' => 'select',
         '#title' => t('My Title'),
         '#options' =>  $optionsArray,
         '#size' => 5,
         '#prefix' => t('<div id="mySelectList">'),
         '#suffix' => t('</div>'),
    }

버튼 :

$form['my_form']['delete_button'] = array(
  '#type' => 'button',
  '#value' => 'Delete',

  '#attributes' => array( 
      'class' => array('deleteButtonClass'), 
    ),

  '#ajax' => array (

    // this is the custom event that will be fired from the jQuery function
    'event' => 'deleteGroupEvent', 

    'callback' => 'ajax_delete_callback',
    'wrapper' => 'mySelectList',
    ),

);

마지막으로 AJAX 콜백 :

function ajax_delete_callback ($form, $form_state) {

  // callback implementation code

  return $form['my_form']['select_list'];
}

-1

drupal misc / ajax.jx 파일을 수정하여이 문제를 해결했습니다.

ajax.js 파일의 사본을 작성하고 사용자 정의 모듈을 넣고 Drupal.ajax = function (base, element, element_settings) { beforeSend 에서 함수를 수정하십시오 .

beforeSend: function (xmlhttprequest, options) {

    if( ajax.url =='/?q=field_collection/ajax'){ // condition for when click on the Remove button
      if (confirm('Are you sure you want to remove this?')) {
       ajax.ajaxing = true;
       return ajax.beforeSend(xmlhttprequest, options);
      }
      xmlhttprequest.abort();
    } else{
        ajax.ajaxing = true;
        return ajax.beforeSend(`xmlhttprequest`, options);   
     }    
},

그것은 나를 위해 잘 작동합니다.


1
해킹 코어로 간주되므로 피해야합니다.
Mołot

1
그리고 완전히 불필요합니다 -en.wikipedia.org/wiki/Monkey_patch
Clive

이것이 이중 확인 상자를 표시하지 않고이 개념을 작동시킬 수있는 유일한 방법이었습니다. 한 가지 예외는 ajax.url == 'field_collection_remove_js'인지 if 문을 확인해야한다는 것입니다. 어쩌면 내가 사용하는 Drupal 버전 때문일 수 있습니까?
Richard

-1

어쩌면 조금 오래되었지만 왜 우리가 사용할 수 없는지 궁금합니다.

(function($, Drupal, window, document, undefined) {

Drupal.behaviors.oc_ua_pc = {
  attach: function(context, settings) {
    $('#button').click(function () {
      if(confirm('This action cannot be undone and you cannot change the form later. Do you want to submit?')) {
        return;
      }

      return false;
    });
  }
}
})(jQuery, Drupal, this, this.document);

Drupal은 mousedown 이벤트에 바인딩되므로 click 이벤트 핸들러는 실행되지 않습니다.
Felix Eve

Drupal은 PHP 나 JS의 작동 방식을 바꾸지 않습니다. 왜 클릭 이벤트를 수신하지 않습니까? 여기서 Drupal은 JS 코드를 첨부하는 데 사용됩니다. 사이트가로드되면 Drupal이 작업을 완료했습니다. JS 리스너가 모두 있습니다. ;)
schlicki 2016 년

당신은 좋은 질문을 제기하고 솔직히 클릭 이벤트가 발생하지 않는 이유를 모르겠습니다. 그러나 광범위한 테스트 후 나는 그렇지 않다는 것을 확인할 수 있습니다. 더 잘 이해하려면 Drupal의 ajax.js를 읽어야 할 것입니다.
Felix Eve
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.