Сохранять состояние CheckBox в Telerik MVC Grid во время подкачки в приложении ASP.NET MVC - PullRequest
4 голосов
/ 21 января 2011

Я использую Telerik MVC Grid, где один из столбцов - это флажки. Если я выберу флажки, а затем перейду на страницу 2, а затем вернусь на страницу 1, все флажки исчезнут. Конечно, так работает HTTP. Теперь я установил все выбранные флажки внутри скрытого поля, но поскольку сетка выполняет какую-то обратную передачу, мое скрытое поле очищается в следующий раз.

Ответы [ 3 ]

11 голосов
/ 21 февраля 2011

Если вы используете привязку данных на стороне клиента, вы можете использовать приведенный ниже javascript / jquery для поддержания состояния флажка.

Сохранить состояние флажка:

var selectedIds = [];

$(document).ready(function () {
    //wire up checkboxes.
    $('#YOUR_GRID_ID :checkbox').live('change', function (e) {
        var $check = $(this);
        console.log($check);
        if ($check.is(':checked')) {
            //add id to selectedIds.
            selectedIds.push($check.val());
        }
        else {
            //remove id from selectedIds.
            selectedIds = $.grep(selectedIds, function (item, index) {
                return item != $check.val();
            });
        }
    });
});

Восстановить состояние флажка после привязки данных:

function onDataBound(e) {
    //restore selected checkboxes.
    $('#YOUR_GRID_ID :checkbox').each(function () {
        //set checked based on if current checkbox's value is in selectedIds.
        $(this).attr('checked', jQuery.inArray($(this).val(), selectedIds) > -1);
    });
}

Более подробное объяснение доступно в моем блоге: http://blog.cdeutsch.com/2011/02/preserve-telerik-mvc-grid-checkboxes.html

0 голосов
/ 02 октября 2012

для сохранения состояния отмеченного / не отмеченного флажка с использованием клиентской таблицы Telerik Grid между обратными и асинхронными обратными передачами, а также при обновлении сетки и (авто) подкачки страниц, я попробовал решение, приведенное выше, безрезультатно, и поэтому нашел более сложное решение;поскольку я не мог сохранить состояние в БД, я использовал переменную сеанса и скрытое поле:во-первых, способ сделать обратную передачу ajax (см. функцию DoAjaxPostAndMore, любезно предоставлена ​​кем-то здесь), где в случае успеха мы заботимся о клиентских значениях выборок, добавляя и удаляя как проверенные / непроверенныеЯ также должен был вручную установить / снять флажки внутри поста ajax вручнуюво-вторых, скрытое поле (см. «hidSelectedRefs») для сохранения клиентов, так как используемая переменная Session не будет видна клиентской стороне при частичном рендеринге



    @model IEnumerable<yourInterfaceOrClass>

    @{
        ViewBag.Title = "Select Something via checkboxes";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }

    <h2>Select Something via checkboxes</h2>
    <!-- we need a form with an id, action must be there but can be an empty string -->
    <form id="frm" name ="frm"  action=""> 
    <p>
    <!--we need this as Session new values will not be takein in aajax requests clientisde, so it is easier to mange this field, which, in first and subsequent complete postbacks can have the value of the Session variable -->
        <input type="hidden" name="hidSelectedRefs" id="hidSelectedRefs" value= '@Session["SelectedReferencesToPrint"]' />  
    </p>

    <br />

    <script type="text/javascript">
       //ajax manual post to a custom action of controller, passing the id of record and the state of the checkbox
       //to adjust the Session value
       //data: $form.serialize() will have the single checbox value
       //but only if checked. To make my life eaasier, I added the value (is id ) and the checked/unchecked 
       //state of checkbox (is the $(chkClicked).attr('checked'))
        function DoAjaxPostAndMore(chkClicked) {
            var $form = $("#frm");
            $.ajax({
                type: "POST",
                url: 'SelectReferences',
                data: $form.serialize() + '&id=' + $(chkClicked).val() + '&checked=' + $(chkClicked).attr('checked'),
                error: function (xhr, status, error) {
                    //do something about the error
                    alert("Sorry, we were not able to get your selection...");
                },
                success: function (response) {
                    //I also needed to check / uncheck manually the checkboxes:

                    $(chkClicked).attr('checked', !$(chkClicked).attr('checked'));

                    //and now put correct values in hidSelectedRefs hidden field:

                    if ($(chkClicked).attr('checked')) {

                        $('input[name=hidSelectedRefs]').val($('input[name=hidSelectedRefs]').val() + '|' + $(chkClicked).val() + '|');
                    } else {
                        var tmp = $('input[name=hidSelectedRefs]').val();

                        $('input[name=hidSelectedRefs]').val(tmp.toString().replace('|' + $(chkClicked).val() + '|', ''));

                    }
                }
            });

            return false; // if it's a link to prevent post
        }

</code>


Then I handled the OnRowDataBound, to ensure the checboxes would be correctly checked on postbacks,
<code>

    function onRowDataBound(e) {
            var itemsChecked = $('input[name=hidSelectedRefs]').val();


            if (itemsChecked)
            {
                if (itemsChecked.indexOf('|' + $(e.row).find('input[name=checkedRecords]').val() + '|') >= 0)
                {
                    $(e.row).find('input[name=checkedRecords]').attr('checked', true);
                }
            }
     }
     </script>

    </code>

    The telerik mvc Grid is as follows:
    <br />(you can see I also handled OnDataBinding and OnDataBound, but thats's only to show a 
    "Loading" gif. The controller is named "Output" and the action that normally would be called "Index" here is callled "PrintReferences". The correspondenting Ajax action is called "_PrintReferences") 


    Of interest here is the ClientTemplate for checkbox (cortuesy of someone else herearound, where onclick
    we call our custom ajax action (named "SelectReferences") on our Output controller via a call to the
     DoAjaxPostAndMore() javascript/jquery function 

    <code>
    @(Html.Telerik().Grid<yourInterfaceOrClass>()
                    .Name("Grid")
                        .ClientEvents(e => e.OnDataBinding("showProgress").OnDataBound("hideProgress").OnRowDataBound("onRowDataBound"))
                         .DataBinding(dataBinding =>
                         {
                             dataBinding.Server().Select("PrintReferences", "Output", new { ajax = ViewData["ajax"]});
                             dataBinding.Ajax().Select("_PrintReferences", "Output").Enabled((bool)ViewData["ajax"]);
                         })  
                    .Columns( columns =>
                        {
                            columns.Bound(o => o.ID); 
                            columns.Bound(o => o.ID)
                            .ClientTemplate(
                               "<input type='checkbox' name='checkedRecords' value='<#= ID #>'  onclick='return DoAjaxPostAndMore(this)' />"
                               )
                            .Width(30)
                            .Title("")
                            .HtmlAttributes(new { style = "text-align:center; padding: 0px; margin: 0px;" });

                            columns.Bound(o => o.TITLE);
                            columns.Bound(o => o.JOBCODE); 
                            columns.Bound(o => o.ORDERCODE );
                            //columns.Bound(o => o.AUTHOR);
                            columns.Bound(o => o.STATE);

                            columns.Command(commands =>
                        commands
                           .Custom("Details")
                           .ButtonType(GridButtonType.Image)
                          .HtmlAttributes(new { @class = "t-icon-details" })                      
                           .DataRouteValues(route => route.Add(o => o.ID)
                              .RouteKey("ID"))
                           .Ajax(false)
                           .Action("Details", "Referenza")

                           );

                        })

                       .Pageable(paging => 
                      paging.PageSize(10)
                      .Style(GridPagerStyles.NextPreviousAndNumeric)
                      .Position(GridPagerPosition.Bottom))
                        .Sortable()
                        .Filterable()
                         .Resizable(resizing => resizing.Columns(true))
                         .Reorderable(reorder => reorder.Columns(true))
                        .NoRecordsTemplate("No Reference found. Please review your filters...")
                         .ColumnContextMenu()
                        )

    </form>

</code>


that's all for the View. Now, to the controller:
<code>

    //Get : this is the usally called "Index" action
    //here we can load data, but we also must ensure the Session variable is fine

      public ActionResult PrintReferences(bool? ajax, string msgInfo, string selectedRef)
      {
          if (Session["SelectedReferencesToPrint"] == null)
          {
              Session["SelectedReferencesToPrint"] = string.Empty;
          }
          if (string.IsNullOrEmpty(selectedRef))
          {
              selectedRef = "|0|";
          }


          string msgOut = string.Empty;

          //this is where I get data to show
          List<yourInterfaceOrClass> ret = LoadData(out msgOut);

          if (!string.IsNullOrEmpty(msgInfo) && !string.IsNullOrEmpty(msgInfo.Trim()))
          {
              msgOut = msgInfo + ' ' + msgOut;
          }
          ViewBag.msgOut = msgOut;

          ViewData["ajax"] = ajax ?? true;

          return View(ret);

      }

      //GridAction: here is telerik grid Ajax get request for your "_Index"
      [GridAction]
      public ActionResult _PrintReferences(string msgInfo)
      {
          //again, we must take care of Session variable
          if (Session["SelectedReferencesToPrint"] == null)
          {
              Session["SelectedReferencesToPrint"] = string.Empty;
          }
          string msgOut = string.Empty;

          List<yourInterfaceOrClass> ret = LoadData(out msgOut);
          return View(new GridModel(ret));
      }

      //Post: this is where our custom ajax post goes
      //we are here if a checkbox is cheched or unchecked
      //in the FormCollection parameter we get the checkbox value only if checked, and also 
      //(and always) the parms we passed (id of record and state of checkbox: we cannot simply add, 
      //we must also subtract unchecked) 
      [HttpPost]
      public ActionResult SelectReferences(FormCollection collection)
      {
          //we need a session variable
          if (Session["SelectedReferencesToPrint"] == null)
          {
              Session["SelectedReferencesToPrint"] = string.Empty;
          }
          //use a local variable for calculations
          string wholeSelectionToPrint = Session["SelectedReferencesToPrint"].ToString();

          //get value passed: id 
          string selectedRefId = collection["id"];
          if (!string.IsNullOrEmpty(selectedRefId))
          {
              selectedRefId = "|" + selectedRefId + "|";

          }
          bool cheked = (collection["checked"].ToString()=="checked");
          //get vcalue passed :checked or unchecked


          if (cheked)
          {
              //the element is to add
              wholeSelectionToPrint += selectedRefId;
          }
          else
          {
              //the element is to remove
             wholeSelectionToPrint = wholeSelectionToPrint.Replace(selectedRefId, "");
          }


          //set session variable final value
          Session["SelectedReferencesToPrint"] = wholeSelectionToPrint;

          return null;

      }

      //normal postback:
      //we will be here if we add a button type submit in our page,
      //here we can collect all data from session variable to do
      //something with selection
      [HttpPost]
      public ActionResult PrintReferences(FormCollection collection)
      {

          //get selected references  id 
          if (Session["SelectedReferencesToPrint"] == null)
          {
              Session["SelectedReferencesToPrint"] = string.Empty;
          }
          //use a local variable for calculations
          string wholeSelectionToPrint = Session["SelectedReferencesToPrint"].ToString();
          wholeSelectionToPrint = wholeSelectionToPrint.Replace("||", "|");
          string[] selectdIDs = wholeSelectionToPrint.Split(new char[] { '|' });
          foreach (string id in selectdIDs)
          { 
              if (!string.IsNullOrEmpty(id))
              {
                  //do something with single selected record ID
                  System.Diagnostics.Debug.WriteLine(id);    
              }
          }
          //omitted [....]

          ViewData["ajax"] = true;

          return View(ret);

      }


0 голосов
/ 21 января 2011

Вам необходимо сохранить состояние флажков в вашей базе данных, а затем снова извлечь их из базы данных при перезагрузке страницы.

Во время подкачки вам необходимо перезагрузить только те записи, которые относятся к определенной странице. Вы можете сделать это, используя методы Skip() и Take() из Linq.

...