Frage

I am able to display Flexigrid in a normal view called from my main menu. I am using this sample http://mvc4beginner.com/Sample-Code/Insert-Update-Delete/Asp-.Net-MVC-Ajax-Insert-Update-Delete-Using-Flexigrid.html to make it work and it works fine for me.

However, my idea is to use a bit more complex interface - have a regular view with the search controls and on pressing search button show the grid with data for the items I searched.

I tried couple of things so far and can not make it to work. Here is the latest Index view I tried:

@model CardNumbers.Objects.Client

@{
    ViewBag.Title = "Clients";
}

<h2>Clients</h2>

<br />
      @using (Ajax.BeginForm("Search", "Client",
    new AjaxOptions
    {
        HttpMethod = "POST",
        InsertionMode = InsertionMode.Replace,
        UpdateTargetId = "ClientsResults"

    }))
    {
    <fieldset>
        <legend>Search</legend>
        <label for="clientNo">Client No: </label>
        <input type="number" name="searchClientNo" class="numericOnly" /><br />
        <label for="clientName">Client Name: </label>
        <input type =  "text" size =25 data-autocomplete="@Url.Action("QuickSearch", "Client")"  name ="searchClientName" />
        <div>
       <input type="submit" value="Find / Refresh" />      


            @*<input type="button" value="Find / Refresh" id="ClientsSearch" data-url="@Url.Action("Client", "Client")" />

            @*<input type="submit" value="Find / Refresh" />*@
       @*     @Ajax.ActionLink("Find / Refresh", "Client", new AjaxOptions {UpdateTargetId = "ClientResults",
           InsertionMode = InsertionMode.Replace, HttpMethod = "POST"}) *@
          @*}*@

        </div>
    </fieldset>
          <div style="padding-left:150px; padding-top:50px; padding-bottom:50px;" id="ClientsResults">
@*@{Html.RenderPartial("_Client", Model); }*@
              @*<table id="flexClients" style="display:none"/>*@


</div>
      }


@*<br />*@

You can see all the commented attempts here also. So, the Search method in the Clients controller now has this code:

public ActionResult Search(int? searchClientNo = null, string searchClientName = null)
        {
            // Assume we want to select everything
            var clients = Db.Clients; // Should set type of clients to IQueryable<Clients>

            if ((searchClientNo ?? 0) != 0) //Number was supplied
                clients = clients.Where(c => (c.Number == searchClientNo));

            // If clientNo was supplied, clients is now filtered by that. If not, it still has the full list. The following will further filter it.
            if (!String.IsNullOrWhiteSpace(searchClientName)) // Part of the name was supplied
                clients = clients.Where(c => (c.Name.Contains(searchClientName)));

            return PartialView("_ClientsSearch", clients);
            //return PartialView("_Client", clients);
        }

The commented view is the partial view which has a flexigrid and it's not working. The _ClientsSearch view is the "normal" index view created by using the template and this works.

Do you see what exactly I am missing? The flexigrid method is simply not firing at all when I attempt to use it as a partial view from that main view.

War es hilfreich?

Lösung

I haven't figured out the more complex scenario I had originally in mind, but I was able to make it work using the regular view. The helpful idea first came from this FAQ: http://code.google.com/p/flexigrid/wiki/FAQ and also looking a bit closer to that sample I used.

So, now my Client view is this:

    @model CardNumbers.Objects.Client

@{
    ViewBag.Title = "Client";
}

 <form id="frmClientsSearch">

        <label for="clientNo">Client No: </label>
        <input type="number" name="searchClientNo" class="numericOnly" /><br />
        <label for="clientName">Client Name: </label>
        <input type =  "text" size =25 value ="Please enter the search value"
            name ="searchClientName" />

       <input type="button" id="btnClientsSearch" value ="Find / Refresh" />      
</form>
<div style="padding-left: 150px; padding-top: 50px; padding-bottom: 50px;" id="ClientsResults">
    <table id="flexClients" style="display: none">
    </table>
</div>
<div style="display: none">
   <form id="sform">
        <input type="hidden" id="fntype" name="fntype">
        <input type="hidden" id="Id" name="Id">
        <label for="Number">Client No: </label>
        <input type="number" id="Number" name="Number" class="numericOnly" />
        <label for="Name">Client Name: </label>
        <input type="text" size="25" id="Name" name="Name" /><br />
        <label for="Contact11">Contact 1: </label>
        <input type="text" size="25" id="Contact1" name="Contact1" /><br />
        <div class="float-right">
            <button type="Submit" id="btnSave">Submit</button>
            <button type=reset id="btnCancel">Cancel</button>
        </div>
    </form>
</div>

And the main work is done in the .js file (note the AddFormData method):

   /// <reference path = "jquery-1.5.1-vsdoc.js"/>
/// <reference path = "jquery-ui-1.8.11.js"/>

$(document).ready(function() {
    $(":input[data-autocomplete]").each(function() {
        $(this).autocomplete({ source: $(this).attr("data-autocomplete") });
    });
});

$(function () {
    $('input[name="delete"]').click(function () {
        return confirm('Are you sure?');
    });
});

$(".numericOnly").keypress(function (e) {
    if (String.fromCharCode(e.keyCode).match(/[^0-9]/g)) return false;
});

    $("#flexClients").flexigrid({
        url: '/Client/Client/',
        dataType: 'json',
        colModel: [
        { display: 'Client Id', name: 'Id', width: 100, sortable: true, align: 'center', hide: true},
        { display: 'Client #', name: 'Number', width: 100, sortable: true, align: 'center' },
        { display: 'Name', name: 'Name', width: 350, sortable: true, align: 'center' },
        { display: 'Contact 1', name: 'Contact1', width: 350, sortable: true, align: 'center' },
        ],
        buttons: [
        { name: 'Add', bclass: 'add', onpress: test },
        { name: 'Edit', bclass: 'edit', onpress: test },
        { name: 'Delete', bclass: 'delete', onpress: test },
        { separator: true }
        ],
        searchitems: [
        { display: 'Client Name', name: 'Name' }
        ],
        sortname: "Name",
        sortorder: "asc",
        usepager: true,
        title: 'Clients',
        useRp: true,
        rp: 15,
        showTableToggleBtn: true,
        width: 1000,
        onSubmit: addFormData,
        height: 300
    });

//This function adds parameters to the post of flexigrid. You can add a verification as well by return to false if you don't want flexigrid to submit           
function addFormData() {

    //passing a form object to serializeArray will get the valid data from all the objects, but, if the you pass a non-form object, you have to specify the input elements that the data will come from
    var dt = $('#sform').serializeArray();
    dt = dt.concat($('#frmClientsSearch').serializeArray());

    $("#flexClients").flexOptions({ params: dt });

    return true;
}

$('#sform').submit(function () {

    $('#flexClients').flexOptions({ newp: 1 }).flexReload();
    alert("Hello World");
    return false;
});

function test(com, grid) {
    if (com === 'Delete') {
        var clientName = $('.trSelected td:eq(2)').text();
        if (clientName) //Variable is defined and not empty
        {
            if (confirm("Are you sure you want to delete " + $.trim(clientName) + "?"))
                return false;

            $('#fntype').val('Delete');
            $('#Id').val($('.trSelected td:eq(0)').text());
            $('#Number').val('');
            $('#Name').val('');
            $('#Contact1').val('');

            $('.trSelected', grid).each(function () {
                var id = $(this).attr('id');
                id = id.substring(id.lastIndexOf('row') + 3);

                addFormData(); $('#flexClients').flexOptions({ url: '/Client/Client/' }).flexReload();
            });

            clearForm();
        }
    } else if (com === 'Add') {

        $("#sform").dialog({
            autoOpen: false,
            show: "blind",
            width: 1000,
            height: 500
        });
        $("#sform").dialog("open");

        $('#fntype').val('Add');
        $('#Number').val('');
        $('#Name').val('');
        $('#Contact1').val('');

    } else if (com === 'Edit') {

        $('.trSelected', grid).each(function () {

            $("#sform").dialog({
                autoOpen: false,
                show: "blind",
                width: 1000,
                height: 500
            });
            $("#sform").dialog("open");

            $('#fntype').val('Edit');
            $('#Id').val($('.trSelected td:eq(0)').text());
            $('#Number').val($('.trSelected td:eq(1)').text());
            $('#Name').val($('.trSelected td:eq(2)').text());
            $('#Contact1').val($('.trSelected td:eq(3)').text());

        });

    }
}

function clearForm() {    

        $("#sform input").val("");    

};

$(function () {
    $('#btnSave').click(function () {
        addFormData();
        $('#flexClients').flexOptions({ url: '/Client/Client/' }).flexReload();
        clearForm();
        $('#sform').dialog('close');
        return false;
    });
});

$(function () {
    $('#btnCancel').click(function () {      

      //  clearForm();
        $('#sform').dialog('close');
        return false;
    });
});


$(function () {
    $('#btnClientsSearch').click(function () {
        addFormData();
        $('#flexClients').flexOptions({ url: '/Client/Client/' }).flexReload();
        //$.ajax({
        //    url: $(this).data('url'),
        //    type: 'GET',
        //    cache: false,
        //    success: function (result) {
        //        $('#ClientsResults').html(result);
        //    }
        //});
        return;//false;
    });
});

And my Client method in the controller is the same as it used to be with minor change.


Now, my next challenge is to generalize the above and also somehow instead of calling the form sForm I showed use a more complex form with validations as I if it is from the Create/Edit view.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top