jQuery Validate удаленный метод внутри JQuery UI Dialog работает только один раз - PullRequest
1 голос
/ 27 ноября 2011

Мне нужно использовать «удаленный» метод, чтобы проверить наличие названия компании, прежде чем вставлять указанную компанию

В настоящее время я использую jquery UI Dialog для ввода данных компании, поскольку мне нужно сделать это на той же странице, где я затем перечисляю все компании

В настоящее время он работает более или менее, но не так, как ожидалось, поскольку удаленный метод работает только в первый раз, в следующий раз, когда я пытаюсь открыть диалоговое окно и попытаться ввести имя, которое уже существует, «удаленный» метод просто больше не работает, и я не знаю, с чем это связано.

Редактировать : Я попытаюсь выяснить, смогу ли я это объяснить

Допустим, у меня есть 2 зарегистрированных компании: company1 и company2

  1. При первой загрузке страницы я открываю диалоговое окно, пытаясь повторно войти, скажем: 'company2' , метод 'remote' работает правильно ( WebMethod вызывается только тогда, когда 'txtName' теряет фокус и с этого момента каждый раз, когда изменяется содержимое) Я полагаю, что это нормальное поведение, не правда ли?
  2. Если я изменю текст и, скажем, вместо этого введу 'company20' , что не существует среди зарегистрированных компаний, на этот раз компания зарегистрирован правильно.
  3. Данная проблема возникает при повторной попытке ввести предыдущее значение ( company20 ), в этом случае WebMethod больше не звонил, позволяя вам зарегистрироваться 'company20' СНОВА, как будто не существует, что не соответствует действительности. Это как если бы 'company20' были сохранены в качестве действительного значения, с самого первого открытия диалога, но если я введу другое значение, оно действительно существует, например company1 или company2 , метод 'remote' снова работает правильно.

Я не знаю, хорошо ли я объяснил, так как это довольно запутанно, даже для меня, но я надеюсь, что вы меня поняли и что вы можете мне помочь.

Вот все JavaScript Я использую:

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">

    <script type="text/javascript">
     $(document).ready(function() {     

            var dialogFormValidator= $("#form2").validate({
                 rules: {
                   txtName: {
                      required: true,
                      remote: function(){
                        var result={
                            type: "POST", 
                            url: "RemoteMethod.aspx/IsUnique",
                            data: "{'name': '" + $('#txtName').val() + "'}" ,
                            contentType: "application/json; charset=utf-8",  
                            dataType: "json",                              
                            dataFilter: function(data) { 
                                  var x = (JSON.parse(data)).d;
                                  return JSON.stringify(x); 
                            }  

                        }
                        return result;
                      }
                  },
                  txtAddress: {
                      required: true
                  }
               },
               messages :{
                 txtName : {       
                    remote: " That name is already taken,please enter a different one."
                 }               

               }

            });
            $("#dialog-form").dialog({
                autoOpen: false,
                width: 350,
                height: 290,
                modal: true,
                beforeClose: function(event, ui) { 
                    $("#txtName").val("");
                    $("#txtAddress").val("");   
                    dialogFormValidator.resetForm();                    

                },
                buttons:
                {
                    "Add": function() {

                        var valid = dialogFormValidator.form(); 
                        if (valid) {
                            var name = $("#txtName").val();
                            var address = $("#txtAddress").val();


                            var params = new Object();
                            params.name = name;
                            params.address = address;
                            params = JSON.stringify(params);

                            $.ajax({
                                type: 'POST',
                                url: 'RemoteMethod.aspx/AddNewItem',
                                data: params,
                                contentType: "application/json; charset=utf-8",
                                dataType: "json",
                                success: function(msg) {
                                    if (msg.d) {

                                        <%=ClientScript.GetPostBackEventReference(UpdatePanel1,"") %>;
                                        $("#dialog-form").dialog("close");

                                    }
                                },
                                error: function(XMLHttpRequest, textStatus, errorThrown) {
                                    alert(textStatus + ": " + XMLHttpRequest.responseText);
                                }
                            });
                         } 


                        },
                        "Cancel": function() {                           
                            $(this).dialog("close");
                        }
                    }
            });

            $("#add").click(function(event) {
                event.preventDefault();
                $("#dialog-form").dialog("open");
            });
        });

    </script>    
</asp:Content>

Как видите, после того, как все проверки пройдены, я немедленно обновляю содержимое UpdatePanel (вид в виде сетки, где я показываю все существующие компании) с помощью javascript (я использовал UpdatePanel просто для простоты)

И вот также WebMehod, используемый для проверки доступности названия компании:

 <WebMethod()> _
    Public Shared Function IsUnique(ByVal name As String) As Boolean
        Dim count As Integer = 0
        Using cn As New SqlConnection(My.Settings.Conexion.ToString())
            Dim sql As String = "SELECT COUNT(*) FROM Companies WHERE Name=@Name"
            cn.Open()
            Dim cmd As New SqlCommand(sql, cn)
            cmd.Parameters.AddWithValue("@Name", name)
            count = Convert.ToInt32(cmd.ExecuteScalar())
            cn.Close()
        End Using
        If count Then
            Return False
        Else
            Return True
        End If

    End Function

Редактировать: разметка ASP.net:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <div>
        <a href="#" id="add">Add New</a>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:GridView ID="gvSucursales" runat="server" AutoGenerateColumns="False" 
                    DataKeyNames="Id">                  
                    <Columns>
                        <asp:BoundField DataField="Id" HeaderText="Id">
                            <ItemStyle Width="50px" />
                        </asp:BoundField>
                        <asp:BoundField DataField="Nombre" HeaderText="Name">
                            <ItemStyle Width="200px" />
                        </asp:BoundField>
                        <asp:BoundField DataField="Direccion" HeaderText="Address">
                            <ItemStyle Width="300px" />
                        </asp:BoundField>
                    </Columns>                  
                </asp:GridView>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
    <div id="dialog-form" title="Add new Company">
        <p>
            All the fields are required.</p>
        <form id="form2">
        <table>
            <tr>
                <td>
                    <label for="txtName" id="lblName">
                        Name</label>
                </td>
                <td>
                    <input type="text" name="txtName" id="txtName" class="text ui-widget-content ui-corner-all" />
                </td>
            </tr>
            <tr>
                <td>
                    <label for="txtAddress" id="lblAddress">
                        Address</label>
                </td>
                <td>
                    <input type="text" name="txtAddress" id="txtAddress" class="text ui-widget-content ui-corner-all" />
                </td>
            </tr>
        </table>
        </form>
    </div>
</asp:Content>

Буду очень признателен за любые идеи, как решить эту проблему.

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

Как я и подозревал, плагин, кажется, кэширует значение и немного глохнет. Я обнаружил, что могу сделать кэш-память недействительной вручную, используя removeData("previousValue"), и это именно то, что я сделал:

$("#txtName").change(function () {
    $("#txtName").removeData("previousValue");
});

и угадайте, что ...? Работает!

1 голос
/ 29 ноября 2011

Во-первых, у меня есть один вопрос: ваш метод страницы AddNewItem получил удар?

Я создал небольшой проект на основе вашего кода. Для меня звонок на IsUnique все время был в порядке. У меня были проблемы при вызове метода страницы AddNewItem, но всегда возвращался Internal 500 Error.

Неверный способ передачи объекта params методу AddNewItem. Ваш код сгенерирует строку json, например:

var params = new Object();
params.name = name;
params.address = address;
params = JSON.stringify(params);

// params => '{"name": "xxx", "address": "ndndnd"}'

Но asp.net ожидает этого: '{"params": {"name": "xxx", "address": "ndndnd"}}' (при условии, что параметр для AddNewItem называется "params".

var oParams = new Object();
oParams.name = name;
oParams.address = address;

var oData = { 'params' : oParams };

$.ajax({
   ...
   data: JSON.stringify(oData),
   ...
});

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

Надеюсь, что это решение вашей проблемы ... Скажите, если это не соответствует вашим потребностям


Использование правила удаленной проверки и .form ()

Существует также возможный недостаток в вашем обработчике кнопки «Добавить». Вы делаете это:

 var valid = dialogFormValidator.form(); 
 if (valid) {

Проблема в том, что удаленному правилу требуется некоторое время для выполнения, и пока оно не выполнится полностью, поле будет считаться действительным.

Это означает, что if (valid) равно true до тех пор, пока не завершится выполнение удаленного правила, и если оно фактически аннулирует поле, будет слишком поздно.

Я нашел статью об этой проблеме: https://stackoverflow.com/...jquery-validation-waiting-for-remote-check-to-complete

Я не очень доволен решением while (), предложенным в статье, но оно может дать вам идеи.

...