This is a migrated thread and some comments may be shown as answers.

parameterMap - No models sent to controller

4 Answers 1372 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 09 Apr 2014, 04:58 PM
Hi guys, I'm new to Kendo and am having problems getting the parameterMap to work. Please help me to understand why given the following datasource and grid configuration no model params are passed to the create controller action. I have read the documentation on parameterMap and still don't understand why my configuration is not working.

<div id="grid" style="margin-bottom: 20px"></div>
<!-- Data sources for supporter and supportee AutoComplete. -->
<script type="text/javascript">
  var supporterDataSource = new kendo.data.DataSource({
    transport: {
      read: {
        url: "<%= supporters_admin_customer_support_clients_url + '.json' %>",
        dataType: "json"
      },
      schema: {
        user_id: { type: 'number' },
        full_name: { type: 'string' }
      }
    }
  });
  var supporteeDataSource = new kendo.data.DataSource({
    transport: {
      read: {
        url: "<%= supportees_admin_customer_support_clients_url + '.json' %>",
        dataType: "json"
      },
      schema: {
        user_id: { type: 'number' },
        full_name: { type: 'string' }
      }
    }
  });
</script>
<!-- Popup editor template for customer support client grid -->
<script id="popup_editor" type="text/x-kendo-template">
  <div class="k-edit-label" style="padding-right: 10px">
    <label for="SupporterName">Customer Support Rep</label>
  </div>
  <input name="SupporterName"
     data-bind="value:supporter_name"
     data-value-field="user_id"
     data-text-field="full_name"
     data-source="supporterDataSource"
     data-role="autocomplete" />
  <div class="clear"></div>
  <div class="k-edit-label" style="padding-right: 10px">
    <label for="SupporteeName">Researcher</label>
  </div>
  <input name="SupporteeName"
     data-bind="value:supportee_name"
     data-value-field="user_id"
     data-text-field="full_name"
     data-source="supporteeDataSource"
     data-role="autocomplete" />
</script>
<!-- Customer support client grid -->
<% content_for :javascript do %>
  var crudServiceBaseUrl = "<%= admin_customer_support_clients_url %>",
    dataSource = new kendo.data.DataSource({
      transport: {
        read: {
          url: crudServiceBaseUrl + '.json',
          dataType: "json"
        },
        create: {
          url: crudServiceBaseUrl + '.json',
          type: "POST",
          dataType: "json"
        },
        update: {
          url: function (data) {
            return crudServiceBaseUrl + '/' + data.id + '.json';
          },
          type: "PUT",
          dataType: "json"
        },
        destroy: {
          url: function (data) {
            return crudServiceBaseUrl + '/' + data.id + '.json';
          },
          type: "DELETE",
          dataType: "json"
        },
        parameterMap: function(options, operation) {
          if (operation !== "read" && options.models) {
            return {models: kendo.stringify(options.models)};
          }
        }
      },
      pageSize: 20,
      serverPaging: false,
      serverFiltering: false,
      serverSorting: false,
      schema: {
        model: {
          id: "id",
          fields: {
            id: { editable: false, type: 'number' },
            supporter_id: { type: 'number' },
            supporter_name: { type: 'string' },
            supportee_id: { type: 'number' },
            supportee_name: { type: 'string' },
            created_at: { editable: false, type: 'date' },
            updated_at: { editable: false, type: 'date' }
          }
        }
      }
    });
 
  $("#grid").kendoGrid({
    dataSource: dataSource,
    editable: {
      mode: "popup",
      template: kendo.template($("#popup_editor").html())
    },
    edit: function(e) {
      $(e.container)
        .find("input[name='SupporterName']")
        .data("kendoAutoComplete")
        .bind("change", function(e) {});
      $(e.container)
        .find("input[name='SupporteeName']")
        .data("kendoAutoComplete")
        .bind("change", function(e) {});
    },
    toolbar: ["create"],
    height: 430,
    filterable: true,
    sortable: true,
    pageable: true,
    columns: [{
      field: "supporter_name",
      title: "Customer Support Rep",
      type: "string"
    }, {
      field: "supportee_name",
      title: "Researcher",
      type: "string"
    }, {
      field: "created_at",
      title: "Created At",
      type: "date",
      format: "{0:dd-MMM-yyyy hh:mm tt}",
      parseFormats: ["yyyy-MM-dd'T'HH:mm:ss.zz"]
    }, {
      field: "updated_at",
      title: "Updated At",
      type: "date",
      format: "{0:dd-MMM-yyyy hh:mm tt}",
      parseFormats: ["yyyy-MM-dd'T'HH:mm:ss.zz"]
    }, {
      command: ["edit", "destroy"],
      title: " ",
      width: "175px"
    }]
  });
<% end %>

4 Answers, 1 is accepted

Sort by
0
David
Top achievements
Rank 1
answered on 09 Apr 2014, 07:51 PM
Batch = true has to be defined on the datasource in order for parameterMap to work.

var crudServiceBaseUrl = "<%= admin_customer_support_clients_url %>",
    dataSource = new kendo.data.DataSource({
      transport: {
        read: {
          url: crudServiceBaseUrl + '.json',
          dataType: "json"
        },
        create: {
          url: crudServiceBaseUrl + '.json',
          type: "POST",
          dataType: "json"
        },
        update: {
          url: function (data) {
            return crudServiceBaseUrl + '/' + data.id + '.json';
          },
          type: "PUT",
          dataType: "json"
        },
        destroy: {
          url: function (data) {
            return crudServiceBaseUrl + '/' + data.id + '.json';
          },
          type: "DELETE",
          dataType: "json"
        },
        parameterMap: function(options, operation) {
          if (operation !== "read" && options.models) {
            return {models: kendo.stringify(options.models)};
          }
        }
      },
      pageSize: 20,
      serverPaging: false,
      serverFiltering: false,
      serverSorting: false,
      batch: true,
      schema: {
        model: {
          id: "id",
          fields: {
            id: { editable: false, type: 'number' },
            supporter_id: { type: 'number' },
            supporter_name: { type: 'string' },
            supportee_id: { type: 'number' },
            supportee_name: { type: 'string' },
            created_at: { editable: false, type: 'date' },
            updated_at: { editable: false, type: 'date' }
          }
        }
      }
    });
0
Daniel
Telerik team
answered on 11 Apr 2014, 01:49 PM
Hello David,

It is not necessary to use batch updates in order for the parameterMap function to work but as noted in the parameterMap documentation, the models parameters will be available only when the batch option is enabled. If you do not wish to use batch updates then you should serialize the options(which will include the fields from the changed item):
parameterMap: function(options, operation) {
  if (operation !== "read") {
    return kendo.stringify(options);
  }
}
and expect a single item on the server.


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
David
Top achievements
Rank 1
answered on 11 Apr 2014, 06:07 PM
Thanks for your reply Daniel. Yes you're right I don't need batch updates. The real issue is that "the parameterMap function will not be called when using custom functions for the read, update, create and destroy operations". This doesn't play nicely with Rails routes which includes the resource ID in the URL. The way to include the ID in the URL is to use a custom function in the transport params to add the relevant  ID but this doesn't work with parameterMap. To solve it at the moment I define custom routes in Rails that don't require a resource ID which allows me to drop the custom functions from the transport params but this is kind of hacky since I am actually just performing CRUD actions on a single resource and should be able to use the default Rails routes for a resource. If you have solved this problem before I'd be interested in seeing the solution as I haven't found any examples online that tackle the Rails default routes with parameterMap problem. Thanks for your help!
0
Accepted
Daniel
Telerik team
answered on 15 Apr 2014, 11:42 AM
Hello again David,

The parameterMap will not be called only when custom functions are used for the operations:
transport: {
    read: function(options) {
        ...
    }
since the request is handled entirely with custom code in this case. It will still be called when using a function for the request data or URL like in your scenario.


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Data Source
Asked by
David
Top achievements
Rank 1
Answers by
David
Top achievements
Rank 1
Daniel
Telerik team
Share this question
or