Передача даних у діалогове вікно інтерфейсу jQuery


83

Я розробляю ASP.Net MVCсайт, і на ньому я перелічую деякі замовлення з запиту до бази даних у таблиці, ActionLinkщоб скасувати бронювання в певному рядку з таким, BookingIdяк це:

Мої бронювання

<table cellspacing="3">
    <thead>
        <tr style="font-weight: bold;">
            <td>Date</td>
            <td>Time</td>
            <td>Seats</td>      
            <td></td>              
            <td></td>
        </tr>
    </thead>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">13:00 - 14:00</td>
        <td style="width: 100px;">2</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/15">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/15">change</a></td>
    </tr>            
    <tr>
        <td style="width: 120px;">2008-12-27</td>
        <td style="width: 120px;">15:00 - 16:00</td>
        <td style="width: 100px;">3</td>
        <td style="width: 60px;"><a href="/Booking.aspx/Cancel/10">cancel</a></td>
        <td style="width: 80px;"><a href="/Booking.aspx/Change/10">change</a></td>
    </tr>  
</table>

Що було б непогано, якби я міг використати jQuery Dialogдля спливаючого повідомлення із запитанням, чи користувач впевнений, що хоче скасувати бронювання. Я намагався змусити це працювати, але я продовжую застрявати в тому, як створити функцію jQuery, яка приймає параметри, щоб я міг замінити

<a href="https://stackoverflow.com/Booking.aspx/Cancel/10">cancel</a>

з

<a href="#" onclick="ShowDialog(10)">cancel</a>.

ShowDialog функція відкриє діалогове вікно, а також передасть параметр 10 до діалогового вікна, так що якщо користувач натисне "так", тоді він опублікує href:/Booking.aspx/Change/10

Я створив діалогове вікно jQuery у такому сценарії:

$(function() {
    $("#dialog").dialog({
        autoOpen: false,
        buttons: {
            "Yes": function() {
                alert("a Post to :/Booking.aspx/Cancel/10 would be so nice here instead of the alert");},
            "No": function() {$(this).dialog("close");}
        },
        modal: true,
        overlay: {
            opacity: 0.5,
            background: "black"
        }
    });
});   

і саме діалогове вікно:

   <div id="dialog" title="Cancel booking">Are you sure you want to cancel your booking?</div>

Отже, нарешті, на моє запитання: як я можу це зробити? чи є кращий спосіб зробити це?

Відповіді:


45

Ви можете зробити це так:

  • позначте <a>класом, скажіть "скасувати"
  • налаштувати діалогове вікно, діючи на всі елементи з class = "cancel":

    $('a.cancel').click(function() { 
      var a = this; 
      $('#myDialog').dialog({
        buttons: {
          "Yes": function() {
             window.location = a.href; 
          }
        }
      }); 
      return false;
    });
    

(плюс ваші інші варіанти)

Ключові моменти тут:

  • зробити це якомога непомітнішим
  • якщо вам потрібна лише URL-адреса, ви вже маєте її у href.

Однак я рекомендую вам зробити це POST замість GET, оскільки дія скасування має побічні ефекти і, отже , не відповідає семантиці GET ...


Подяка за хорошу відповідь. Я спробую, одне питання. ви згадуєте, що краще зробити його POST, а не GET, що означає, що звичайний href, такий як href = "/ Booking.aspx / Cancel / 10", буде GET ist? і якщо так, то що б він хотів зробити таким постом?
Фредерік

Для того, щоб зробити його публікацією, замість зміни window.location, ви можете використовувати функцію jQuery $ .post () ajax. Див. Docs.jquery.com/Ajax/jQuery.post#examples
Франк

1
Я б не використовував $ .post (), такий підхід погано погіршується. Просто напишіть стандартну <форму> без будь-якого ajax, змусьте її працювати без підтвердження, а потім додайте підтвердження «зверху» вашої <форми>
Маурісіо Шеффер

Це також відоме як підхід "викрадення" ( domscripting.com/blog/display/41 )
Маурісіо Шеффер

Вам не потрібно використовувати повідомлення, але якщо ви використовуєте get для операції зміни бази даних, ви відкриваєте себе для атаки "підробка міжсайтових запитів" ... див .: en.wikipedia.org/wiki/Cross- site_request_forgery
strickli

273

jQuery надає метод, який зберігає дані для вас, не потрібно використовувати фіктивний атрибут або знаходити обхідні шляхи вирішення вашої проблеми.

Прив’язати подію кліку:

$('a[href*=/Booking.aspx/Change]').bind('click', function(e) {
    e.preventDefault();
    $("#dialog-confirm")
        .data('link', this)  // The important part .data() method
        .dialog('open');
});

І ваше діалогове вікно:

$("#dialog-confirm").dialog({
    autoOpen: false,
    resizable: false,
    height:200,
    modal: true,
    buttons: {
        Cancel: function() {
            $(this).dialog('close');
        },
        'Delete': function() {
            $(this).dialog('close');
            var path = $(this).data('link').href; // Get the stored result
            $(location).attr('href', path);
        }
    }
});

15
Це чудове рішення. Я не знав, що ви можете встановлювати дані в діалоговому вікні за допомогою .data. Я встановлював глобальні змінні протягом століть, отримуючи доступ до них зі своїх діалогових вікон, а потім знищуючи їх!
Кевін Бредшоу

Щиро дякую за цю магію .data (). Зверніть увагу на наступне оновлення: "Починаючи з jQuery 1.7, метод .on () є найкращим методом для приєднання обробників подій до документа" api.jquery.com/bind
daniloquio

2
Параметр .data - це, безумовно, шлях. Дякую!
Андреас,

1
+1 Я шукав документацію інтерфейсу користувача jquery і не міг знайти, поки не зрозумів, що це метод із самого ядра jQuery. Дуже приємний улов
Тіві

@ boris-guery Привіт, я спробував, але не зумів змусити це працювати. Це просто не перешкоджає дії за замовчуванням, тому переходить до посилання замість того, щоб відкривати діалогове вікно. Будемо вдячні за будь-яку допомогу: я роблю jsfiddle: jsfiddle.net/sebababi/9zKcZ
Себастьян

2

Що стосується того, що ви робите з jQuery, я розумію, що ви можете зв'язати такі функції, як у вас, а внутрішні мають доступ до змінних із зовнішніх. Так само, як ваша функція ShowDialog (x) містить ці інші функції, ви можете повторно використовувати змінну x всередині них, і вона буде взята як посилання на параметр із зовнішньої функції.

Я погоджуюсь з mausch, ви дійсно повинні поглянути на використання POST для цих дій, який додасть <form>тег навколо кожного елемента, але зробить шанси автоматичного сценарію чи інструменту, що ініціюють подію Cancel, набагато меншими. Дія Змінити може залишитися такою, якою вона є, оскільки вона (імовірно, просто відкриває форму редагування).


1

Зараз я спробував ваші пропозиції і виявив, що це начебто працює,

  1. Діалоговий div завжди виписується у відкритому тексті
  2. У версії $ .post це насправді працює з точки зору того, що контролер викликається і фактично скасовує бронювання, але діалогове вікно залишається відкритим, а сторінка не оновлюється. З get version window.location = h.ref чудово працює.

Перегляньте мій "новий" сценарій нижче:

$('a.cancel').click(function() {
        var a = this;               
        $("#dialog").dialog({
            autoOpen: false,
            buttons: {
                "Ja": function() {
                    $.post(a.href);                     
                },
                "Nej": function() { $(this).dialog("close"); }
            },
            modal: true,
            overlay: {
                opacity: 0.5,

            background: "black"
        }
    });
    $("#dialog").dialog('open');
    return false;
});

});

Будь-які підказки?

о, і моє посилання Action тепер виглядає так:

<%= Html.ActionLink("Cancel", "Cancel", new { id = v.BookingId }, new  { @class = "cancel" })%>

Дивіться мої коментарі до моєї відповіді щодо використання $ .post () та підходу hijax
Маурісіо Шеффер

1

Переглядаючи ваш код, вам потрібно додати функціональність, щоб закрити вікно та оновити сторінку. У своїй функції "Так" ви повинні написати:

        buttons: {
            "Ja": function() {
                $.post(a.href);
                $(a). // code to remove the table row
                $("#dialog").dialog("close");
            },
            "Nej": function() { $(this).dialog("close"); }
        },

Код для видалення рядка таблиці не цікаво писати, тому я дозволю вам розібратися з дрібними деталями, але в основному вам потрібно сказати діалоговому вікні, що робити після того, як ви його опублікуєте. Це може бути розумний діалог, але він потребує якогось напрямку.


Подякуйте за вашу відповідь. Я спробую це, а також знайду спосіб прибрати рядок ...
Фредерік,

Я думав про це, якщо ви додасте ідентифікатор до тегу '<TR>', тоді ви можете отримати jQuery, щоб достатньо легко видалити цей рядок.
thaBadDawg

1

Після НІЖНИХ ГОДИН try / catch я нарешті прийшов з цим робочим прикладом, його робота над AJAX POST з новими рядками додається до ТАБЛИЦІ на льоту (це була моя справжня проблема):

Магія прийшла з посиланням:

<a href="#" onclick="removecompany(this);return false;" id="remove_13">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_14">remove</a>
<a href="#" onclick="removecompany(this);return false;" id="remove_15">remove</a>

Це остання робота з AJAX POST та Jquery Dialog:

  <script type= "text/javascript">/*<![CDATA[*/
    var $k = jQuery.noConflict();  //this is for NO-CONFLICT with scriptaculous
     function removecompany(link){
        companyid = link.id.replace('remove_', '');
    $k("#removedialog").dialog({
                bgiframe: true,
                resizable: false,
                height:140,
                autoOpen:false,
                modal: true,
                overlay: {
                    backgroundColor: '#000',
                    opacity: 0.5
                },
                buttons: {
                    'Are you sure ?': function() {
                        $k(this).dialog('close');
                        alert(companyid);
                        $k.ajax({
                              type: "post",
                              url: "../ra/removecompany.php",
                              dataType: "json",
                              data: {
                                    'companyid' : companyid
                                    },
                              success: function(data) {
                                    //alert(data);
                                    if(data.success)
                                    {
                                        //alert('success'); 
                                        $k('#companynew'+companyid).remove();
                                    }
                          }
                        }); // End ajax method
                    },
                    Cancel: function() {
                        $k(this).dialog('close');
                    }
                }
            });
            $k("#removedialog").dialog('open'); 
            //return false;
     }
    /*]]>*/</script>
    <div id="removedialog" title="Remove a Company?">
        <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
        This company will be permanently deleted and cannot be recovered. Are you sure?</p>
    </div>

1

Ця робота для мене:

<a href="#" onclick="sposta(100)">SPOSTA</a>

function sposta(id) {
        $("#sposta").data("id",id).dialog({
            autoOpen: true,
            modal: true,
            buttons: { "Sposta": function () { alert($(this).data('id')); } }
        });
    }

Коли ви натискаєте "Sposta" у діалоговому вікні попередження 100


0

Гаразд, перша проблема з тегом div була досить простою: я просто додав style="display:none;"до неї а потім перед тим, як показати діалогове вікно, я додав це у своєму діалоговому сценарії:

$("#dialog").css("display", "inherit");

Але для поштової версії мені все ще не щастить.


Дивіться мої коментарі до моєї відповіді щодо використання $ .post () та підходу hijax
Маурісіо Шеффер

0

Просто дайте вам якусь ідею, яка може вам допомогти, якщо ви хочете повністю контролювати діалогове вікно, ви можете спробувати уникнути використання параметрів кнопок за замовчуванням і додати кнопки самостійно у своєму #dialog div. Ви також можете помістити дані в якийсь фіктивний атрибут посилання, наприклад Click. зателефонуйте attr ("дані"), коли вам це потрібно.


0

Рішення, натхнене Борисом Гері, яке я використовував, виглядає так: Посилання:

<a href="#" class = "remove {id:15} " id = "mylink1" >This is my clickable link</a>

прив’язати до нього дію:

$('.remove').live({
        click:function(){
            var data = $('#'+this.id).metadata();
            var id = data.id;
            var name = data.name;
            $('#dialog-delete')
                .data('id', id)
                .dialog('open');    
            return false;
        }
    });

А потім отримати доступ до поля ідентифікатора (у цьому випадку зі значенням 15:

$('#dialog-delete').dialog({
    autoOpen: false,
    position:'top',
    width: 345,
    resizable: false,
    draggable: false,
    modal: true,
    buttons: {            
        Cancel: function() {

            $(this).dialog('close');
        },
        'Confirm delete': function() {
            var id = $(this).data('id');
            $.ajax({
                url:"http://example.com/system_admin/admin/delete/"+id,
                type:'POST',
                dataType: "json",
                data:{is_ajax:1},
                success:function(msg){

                }
            })
        }
    }
});

0

я сподіваюся, це допоможе

$("#dialog-yesno").dialog({
    autoOpen: false,
    resizable: false,
    closeOnEscape: false,
    height:180,
    width:350,
    modal: true,
    show: "blind",
    open: function() {
        $(document).unbind('keydown.dialog-overlay');
        },
    buttons: {
        "Delete": function() {
            $(this).dialog("close");
            var dir = $(this).data('link').href;
            var arr=dir.split("-");
            delete(arr[1]);
        },
    "Cancel": function() {
        $(this).dialog("close");
        }
    }
});



<a href="product-002371" onclick="$( '#dialog-yesno' ).data('link', this).dialog( 'open' ); return false;">Delete</a>

1
Привіт @ffernandez, мабуть, найкраще спробувати включити якийсь опис того, що ти робиш - а не просто кидати код на ОП.
thomasfedb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.