2014-11-04 2 views
2

Я знаю, что обычный JS способ принятия действия, только если окно подтверждения должен иметь подтверждение внутри функции, как в этом примере JQuery:Может ли javascript прослушать результат подтверждения диалога по отдельному методу?

<script type="text/javascript"> 
    $(function() { 
    $("#dropdown").change(function() { 
     var success = confirm('Are you sure want to change the Dropdown ????'); 

     if (success == true) { 
     // do something     
     } 
     else { 
     // Cancel the change event and keep the selected element 
     } 
    }); 
    }); 
</script> 

Этот не работает в моем случае, т.к. подтверждение является частью помощника рельсы:

<%= link_to "Delete", {:controller => 'foo', :action => 'delete', :id => @item.id}, 
    {:method => :post, :confirm => "Are you sure?", :class => "start_spinner"} %> 

Я хочу, чтобы запустить некоторые JavaScript на клик (скрыть ссылку для предотвращения двойного щелчка), но только если подтверждение верно. К сожалению, по крайней мере, в Rails 2.3.x невозможно использовать :onclick, если имеются опции :method или :confirm. (Такое поведение отмечено on ApiDock for the link_to helper и то же самое в моем приложении.)

EDIT: Я думаю, что я создал некоторую путаницу, включая пример из ApiDock вместо моего точного кода. Извини за это. Я изменил код ниже, чтобы отразить поведение, которое Rails имеет, когда включен параметр :method => :post, как это должно быть в моем коде. Разница между двумя выходами по-прежнему просто понижает метод destroyJsFunction, но есть целая куча других вещей, которые происходят в onclick, что, кажется, мешает реализации решений, предложенных Сукимой и агностером.

<%= link_to "Delete", {:controller => 'foo', :action => 'delete', :id => @item.id}, :method => :post, :confirm=>"Are you sure?", :onclick=>"destroyJsFunction()", :class => "start_spinner" %> 
# expected output 
# => <a href="/foo/delete/1" class='start_spinner' onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'CSRF_TOKEN'); f.appendChild(s);f.submit(); }; {destroyJsFunction()}; return false;">Delete</a> 
# actual output 
# => <a href="/foo/delete/1" class='start_spinner' onclick="if (confirm('Are you sure?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var s = document.createElement('input'); s.setAttribute('type', 'hidden'); s.setAttribute('name', 'authenticity_token'); s.setAttribute('value', 'CSRF_TOKEN'); f.appendChild(s);f.submit(); }; return false;">Delete</a> 

END EDIT

Так как я использую Rails для отправки POST запроса, я не могу просто переписать ссылку на простом HTML.

Хотелось бы запустить javascript при щелчке ссылки с классом start_spinner, но я не могу найти способ повторно отобразить ссылку, если подтверждение ложно. Есть ли способ, чтобы отдельный javascript прослушал результаты диалога подтверждения?

ответ

2

Все подтверждают, что в JavaScript есть HTML-код, который выполняет именно то, что вы описываете: запросите пользователя и отправьте форму на ответ об успешном завершении.

Если вы хотите сделать что-то другое, вам придется написать свой собственный метод подтверждения. Поскольку логика настолько проста, я уверен, что команда рельсов почувствовала, что если вы хотите больше, вы можете написать ее самостоятельно.

Сделайте функцию, которая выполняет логику подтверждения и if/else. Я хотел бы использовать свои собственные ненавязчивые JS, как с помощью JQuery, чтобы прикрепить событие щелчка, но вы также можете использовать рельсы link_to хелперов вариант :onclick как вы упомянули выше (лично я ненавижу эту опцию.)

JQuery Пример:

$(function() { 
 
    $('a.destroy').on('click', function(e) { 
 
    e.preventDefault(); 
 
    var $el  = $(this); 
 
    var response = confirm($el.data('confirm') || 'Are you sure?'); 
 

 
    if (!response) { return; } 
 

 
    $el.css({'pointer-events': 'none'}); 
 

 
    $.ajax({ 
 
     url: $el.attr('href'), 
 
     type: 'DELETE', 
 
     data: {_method: 'delete'} 
 
    }) 
 
    .then(function() { 
 
     alert('Deleted! we should do something here'); 
 
    }) 
 
    .fail(function() { 
 
     alert('Opps, it didn\'t delete, check the respose to see why.'); 
 
    }) 
 
    .always(function() { 
 
     $el.css({'pointer-events': 'auto'}); 
 
    }); 
 
    }); 
 

 
    // Only for SO example not needed for real code 
 
    $('#reset').on('click', function(e) { 
 
    e.preventDefault(); 
 
    $('a').css({'pointer-events': 'auto'}); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<a href="#/path/with/:id" class="destroy" data-confirm="Are your sure?">Confirm?</a> 
 
(<a href="#" id="reset" title="this is not need in real code">reset</a>)

+0

Ах, эта редакция работает для меня! Спасибо! Мне просто пришлось немного изменить параметры ajax; вы написали 'method', где вы имели в виду' type'. Благодаря! – joanwolk

+0

Исправлено. Также добавлен параметр '_method', поскольку некоторые браузеры не обрабатывают тип DELETE правильно. – Sukima

1

Короткий ответ: вид, сорт, но это немного Hacky.

Итак, вы хотите знать, был ли нажат на ссылку подтвержден или нет. Единственный способ сказать из других источников (без возможности ввода обратного вызова, который, по-видимому, является проблемой Rails), заключается в том, чтобы зафиксировать событие и проверить, было ли предотвращено действие по умолчанию (что и делает здесь return confirm()).

Использование JQuery вы могли бы добавить некоторые JS на странице так:

$('#confirm-link').click(function(e) { 
    if (e.isDefaultPrevented()) { 
    alert("I feel rejected") 
    } else { 
    alert("I feel confirmed") 
    } 
}) 

Я поиграл с JSFiddle. Однако это будет немного хрупким.

+0

Тем не менее, подход Sukima просто пропустить Rails вполне приятен, если вы можете это сделать, но похоже, что вам нужен Rails для отправки. Я не уверен, как это зацепилось, хотя это тоже прослушиватель по щелчку или что-то в этом роде? – agnoster

+0

Rails использует стандартную форму представления для всех действий, кроме DELETE, которые обычно выполняются через AJAX, поскольку [этот ответ] (http://stackoverflow.com/a/9234330/227176) предлагает. – Sukima

+0

Sukima: правый, но он вызывает форму без ссылки. Итак ... должен быть еще один слушатель или что-то в этом роде, верно? Как это работает? Эх, я на самом деле не человек Rails, для меня это слишком магия. Если ваш подход работает и не мешает каким-либо предположениям Rails, я бы предпочел это. Преимущество моего решения заключается в том, что он работает независимо от особенностей реализации Rails. :-) (Конечно, полагаясь на preventDefault, но мы видим это довольно ясно) – agnoster

0

Если вы вызываете ссылку на удаление как вызов Ajax, вы можете отобразить файл js.erb, который может обрабатывать отображение после подтверждения диалога. Например: триггер

AJAX в представлении:

<li id="post_<%= post.id %>"> 
    <%= link_to "Delete", post_path(post), method: :delete, data: { confirm: "Are you sure you want to remove this post?" }, remote: true %> 
</li> 

Контроллер:

# app/controller/posts_controller.rb 
class PostsController < ApplicationController 
    def destroy 
    @post = Post.find(params[:id]) 
    @post.destroy 
    end 
end 

Вынесено вид:

# app/views/posts/destroy.js.erb 
$('#post_<%= @post.id %>').hide() 
Смежные вопросы