Search code examples
jqueryasp.net-mvc-3validationjeditable

Apply MVC ValidationAttribute to jEditable


I am using MVC 3 and have a customize model class to apply the validation. It works well with "normal" form. But, I got another View which displaying the data in text and using the jEditable plugin to allow user edit any field inline.

I need to apply the same validation to the field as well, but I had tried to enclose the View with using.HtmlBeginForm() yet it still dint work. Following is the View which render in a table:

 @using (Html.BeginForm())
 {
<table id="stocktable" class="pretty">
<thead>
    <tr>
        <th class="name">
            Name
        </th>
        <th class="amount">
            Amount
        </th>
        <th>
            Unit
        </th>
        <th>
            Storage Date
        </th>
        <th>
            Expiry Date
        </th>
        <th>
            Food Type
        </th>
        <th>
        </th>
        <th>
        </th>
    </tr>
</thead>
<tbody>
    @foreach (var item in Model)
    {
     @*Plugin use id at tr tag to identify which row to delete*@
        <tr id="@(item.FoodID)">
            <td id="name@(item.FoodID)" class="namefield">
                @Html.DisplayFor(modelItem => item.FoodName)
            </td>
            <td id="amnt@(item.FoodID)" class="amountfield">
                @Html.DisplayFor(modelItem => item.FoodAmount)
            </td>
            <td id="unit@(item.FoodID)" class="unitdropdown" title="@(item.FoodTypeID)">
                @Html.Action("GetFoodUnitsName", "Stock", new { id = item.FoodUnitID })
            </td>
            <td id="sdat@(item.FoodID)" class="storagedatepicker">
                @String.Format("{0:ddd, d MMM yyyy}", item.StorageDate)
            </td>
            <td id="edat@(item.FoodID)" class="expirydatepicker">
                @String.Format("{0:ddd, d MMM yyyy}", item.ExpiryDate)
            </td>
            <td id="type@(item.FoodID)" class="dropdown" >
                @Html.DisplayFor(modelItem => item.FOODTYPE.FoodTypeName)
            </td>
            <td id="favitem">
                @* Call function to check is fav or not and display respective image *@
                @Html.Action("GetFavFlag", "Stock", new { id = item.FoodID })
            </td>
            <td id="min" title="@(item.FoodID)">
                @Html.Action("GetMinAmount", "Stock", new { id = item.FoodID })
            </td>
        </tr>
    }
</tbody>

And I am changing each type of field into editable like this:

 // Normal text field
    $('.namefield').editable('@(Url.Action("Edit", "Stock"))',
    {
        indicator: 'saving...',
        event: 'dblclick',
        tooltip: 'Double click to edit...',
        //style: 'inherit',
        submit: '<img src="../../Content/Add_in_Images/ok.png" alt="ok"/>',
        cancel: '<img src="../../Content/Add_in_Images/cancel.png" alt="cancel"/>',
        style: 'display:inline',
        height: '20px',
        width: '100px',
        onsubmit: function (settings, td) {
            var input = $(td).find('input');
            var original = input.val();

            if (original == "") {
                alert('Please enter a value');
                return false;
            }
            else {
                return true;
            }
        }

    });

(NOTE: For textfield, I able to did some validation by using the onsubmit method, my problem happen in datetime field, which the value is automatically submitted once user select any date from the datepicker, so I could not apply validation to it:

UPDATE: I tried with the following code, I get the alert in the if statement, but the value is still submitted, please help...

  $('.expirydatepicker').editable('@(Url.Action("Edit", "Stock"))',
    {
        type: 'datepicker',
        indicator: 'saving...',
        event: 'dblclick',
        tooltip: 'Double click to edit...',
        submit: '<img src="../../Content/Add_in_Images/ok.png" alt="ok"/>',
        cancel: '<img src="../../Content/Add_in_Images/cancel.png" alt="cancel"/>',
        style: 'inherit',
        onsubmit: function (settings, td) {
            var form = this;
            var tid = $(td).attr('id');
            var input = $(td).find('input');
            var newDate = input.val();
            alert('id' + tid);
            alert('newdate' + newDate);
            $.ajax({
                async: false,
                url: '/Stock/CompareDate',
                type: 'GET',
                data: { id: tid, inputDate: newDate },
                success: function (result) {
                    alert(result);
                    if (result < 0) {
                        alert("Expiry dare cannot be earlier than storage date");
                        return false;
                    }
                    else {
                        alert('else');
                        return true;
                    }
                }
            });
        }
    });

Do need help here... I could not afford to ignore the validation...

Appreciate any help...


Solution

  • The default MVC ModelBinder does not know how to integrate with jEditable so there is no server validation, and the EditorTemplate functionality also does not know how to integrate with jEditable (it requires an input written out), so you would need to write your own integration to handle both the server and client side validation pieces of your model.

    You will have to write your own custom validation in to the onsubmit manually for the forms, and also write custom checks in your save action. To get at least the server validation you could create your own model binder and send the errors back to the client in JSON and use something like whats suggested in this post to display the errors in the UI: Jeditable Async revert on error