1

I need to use the 'remote' method to check the availability of a company name before proceeding to insert the said company

I'm currently using jquery UI Dialog for entry of the company's data , since I need to do it on the same page where I then list all the companies

Currently I have it more or less working but not as expected, as the remote method works only the first time, the next time I try to open the dialog and try entering a name that already exists, the 'remote' method simply doesn't work anymore and I don't know what this is due to.

Edit : I gonna try and see if I can explain it

Let's say I have 2 registered companies : company1 and company2

  1. The first time the page is loaded I open the dialog trying to re-enter let's say: 'company2', the 'remote' method works correctly(The WebMethod is only called when 'txtName' loses focus and from there on, each time the content is changed) I suppose that is the normal behaviour, isn't it?
  2. If I change the text and, let's say, I enter 'company20' instead, which doesn't exist among the registered companies, this time the company is registered correctly.
  3. The problem in question occurs when trying again to re-enter the previous value (company20) , in this case the WebMethod is no longer called , allowing you to register 'company20' AGAIN, as if did not exist, which is not true.It is as if 'company20' were kept as a valid value, right from the first time the dialog was opened, but if I enter another value, that really exists such as company1 or company2, the 'remote' method works correctly again.

I do not know if I have explained it well , since it is rather confusing, even for me, but I hope you have understood me and that you can help me.

Here's all the javascript I use :

<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>

As you can see , once all the validations are met, I immediately refresh the UpdatePanel's content(a gridview where I show all the existing companies ) via javascript.( I used an UpdatePanel just for the sake of simplicity)

And here's also the WebMehod used to check the availability of a company name :

 <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

Edit : ASP.net markup :

<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>

Any ideas on how to solve this will be really appreciated

eddy
  • 4,373
  • 16
  • 60
  • 94
  • Is your #form2 element also in the updatepanel ? – Didier Ghys Nov 27 '11 at 18:06
  • @DidierG.- No, it isn't. The #form2 is in a ContentPlaceHolder, I've added that part so that you can get a better idea – eddy Nov 27 '11 at 18:13
  • I quickly checked but had not real trouble with same implementation (except the database call checking the name). What is exactly "not working anymore" ? Is the remote val. not called anymore ? Do you get an error ? – Didier Ghys Nov 28 '11 at 11:32
  • @DidierG. - I've tried to describe the problem in detail, please take a look at the original question – eddy Nov 28 '11 at 22:48

2 Answers2

2

As I suspected the plugin seems to cache the value and gloogling a little bit I found I can invalidate the cache manually using removeData("previousValue") and that's exactly what I did :

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

and guess what...? It works!

eddy
  • 4,373
  • 16
  • 60
  • 94
  • @DidierG. Thanks :D I really appreciate what you've been doing for me the past few days – eddy Dec 01 '11 at 23:28
1

First I've got one question: is your AddNewItem page method gets hit ?

I have created myself a little project based on your code. For me the call to IsUnique was all the time ok. I had troubles when calling the AddNewItem page method though, always got an Internal 500 Error returned.

The way you pass your params object to the AddNewItem method is not correct. Your code will generate a json string like this:

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

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

But asp.net expects this: '{"params": {"name": "xxx", "address": "ndndnd"}}' (assuming the parameter for AddNewItem is called "params".

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

var oData = { 'params' : oParams };

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

After changing that, my project works as expected, I can add new items and the IsUnique takes into consideration added items.

Hope this is the solution to your problem... Tell if it does not suit your needs


Using remote validation rule and .form()

There is also a possible flaw in your "Add" button handler. You are doing this:

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

The problem is that remote rule takes some time to execute and until it has completely executed, the field will be considered valid.

This meabns that if (valid) is true until the remote rule has ended executing, and if it actually invalidates the field, it'll be too late.

I found an article about this problem: https://stackoverflow.com/...jquery-validation-waiting-for-remote-check-to-complete

I'm not really happy with while() solution proposed in the article but it can give you ideas.

Community
  • 1
  • 1
Didier Ghys
  • 30,396
  • 9
  • 75
  • 81
  • I didn't have any problem with the `AddNewItem` method since my WebMethod **expected** two parameters:'name' and 'address', but I must admit that your suggestion is way more practical and was exactly the way I wanted to pass my parameters(**Once more, thank you**) but since I had absolutely no idea how to do it, I ended up passing the parameters one by one – eddy Nov 30 '11 at 23:10
  • Now, regarding the problem with `remote` method , I tried using the `remote_complete` variable and putting the `return result;` inside the `while`,but the problem remains I also noticed that the issue seems to get solved by its own if I refresh the page.. the problem is , that's exactly what I'm trying to avoid – eddy Nov 30 '11 at 23:40