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

datasource: transport: update: not firing

8 Answers 40 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Michael
Top achievements
Rank 1
Michael asked on 10 Feb 2021, 08:05 AM

Hi

I don't really know Kendo UI very well but I'm modifying an existing application that was written almost entirely in Kendo UI. Normally, making small changes by studying and re-purposing existing bits of code works fine for me. However, I have found an issue that I can't get past and I need help with.

I have a screen that lists a bunch of people in a kendo.grid. There is an edit button for each row that launches a popup in which there are a bunch of checkboxes that can be checked. Then on update I will send that data to the server for processing.

However, in the popup, when I press update, the datasource: transport: update: clause isn't firing. (For info, the datasource: transport: read: clause fires perfectly).

So, here is the code. Can anybody see where I have made any mistakes?

(For info, I have pasted below just the grid code, but I have also put in attachment the entire JS page, in case it's helpful).

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

  function setGrid() {
  var command = {};
  dataSource = new kendo.data.DataSource({
  serverFiltering: false,
  serverSorting: false,
      serverPaging: false,
      sort: {
        field: 'per_name',
        dir: 'asc'
      },
      transport: {
      read: {
      url: 'action.cfm?action=filehandler.list',
      dataType: 'json',
      cache: false
      },
      update: {
      url: 'action.cfm?action=filehandler.save',
      dataType: 'json',
      cache: false
      }, // THIS NEVER FIRES
       parameterMap: function (options, operation) {
      console.log(operation);
      console.log(options);
      if (operation !== 'read') {
      return options;
      }
      }
      },
      pageSize: 20,
      schema: {
      model: {
      id: 'login',
      fields: {
      login: {
      editable: false
      },
      per_name: {
      editable: false
      },
      org_name: {
      editable: false
      },
      //lst_user_sec_ids: {
    //  editable: true
      //},
      lst_user_sec_labels: {
      editable: false
      }
      }
      }
      },
      change: function (e) {
      if (e.action === 'sync') {
      lists.loadFilehandlers();
      this.read();
      }
      },
      error: function (e) {
      app.printMessage({
      restError: e.xhr
      });
      }
      
  });

  $screen.find('#filehandler-grid').kendoGrid({
  dataSource: dataSource,
  sortable: true,
  cache: false,
  noRecords: true,
  pageable: {
  pageSize: 20,
  pageSizes: [20, 50, 100],
  refresh: true,
  info: true
  },
  filterable: {
  extra: false,
  mode: 'row',
  operators: {
  string: {
  contains: 'Contains'
  },
  number: {
  eq: 'Equals'
  }
  }
  },
  editable: {
  mode: 'popup',
  template: kendo.template($("#sectors-editor").html())
  },
  edit: function (e) {
  $(e.container).parent().css({
  top: '50px',
  left: '150px',
  width: '850px',
  height: '600px',
  overflow: 'scroll'
  });
  }, 
  
  resizable: true,
  selectable: 'cell',

  columns: [
  {
    field: 'login',
    title: 'ECAS ID',
    hidden: true,
    type: 'string',
    filterable: {
    cell: {
    showOperators: false
    }
    },
    width: '150px'
  },
  {
    field: 'per_name',
    title: 'Name',
    hidden: false,
    filterable: {
    cell: {
    showOperators: false
    }
    }
  },
  {
        field: 'org_name',
        title: 'Unit',
        hidden: false,
        type: 'string',
        filterable: {
        cell: {
        showOperators: false
        }
        }
  },
  {
        field: 'lst_user_sec_labels',
        title: 'Has access to sectors',
        hidden: false,
        type: 'string',
        filterable: {
        cell: {
        showOperators: false
        }
        }
  },
  {
        field: 'lst_user_sec_ids',
        title: 'hide this later',
        hidden: false,
        type: 'string',
        filterable: {
        cell: {
        showOperators: false
        }
        }
  },
  {
    command: [
    {
    name: 'edit',
    text: {
    edit: 'Edit',
    cancel: 'Cancel'
    },
    click: function(e) {
            // prevent page scroll position change
                e.preventDefault();
                // e.target is the DOM element representing the button
                var tr = $(e.target).closest("tr"); // get the current table row (tr)
                // get the data bound to the current table row
                var data = this.dataItem(tr);
                // Get the data for the list of sectors and write it into the popup window
                setSectorsList(data.login, data.lst_user_sec_ids);
    }
    }
    ],
    title: 'Actions',
    width: '225px',
    filterable: false
  }
  ]
  });

  }


 

8 Answers, 1 is accepted

Sort by
0
Michael
Top achievements
Rank 1
answered on 10 Feb 2021, 09:07 AM
I re-formatted the code for easier reading:
 
function setGrid() {
    var command = {};
    dataSource = new kendo.data.DataSource({
        serverFiltering: false,
        serverSorting: false,
        serverPaging: false,
        sort: {
          field: 'per_name',
          dir: 'asc'
        },
        transport: {
            read: {
                url: 'action.cfm?action=filehandler.list',
                dataType: 'json',
                cache: false
            },
            update: {
                url: 'action.cfm?action=filehandler.save',
                dataType: 'json',
                cache: false
            }, // THIS NEVER FIRES
            parameterMap: function (options, operation) {
                console.log(operation);
                console.log(options);
                if (operation !== 'read') {
                    return options;
                }
            }
        },
        pageSize: 20,
        schema: {
            model: {
                id: 'login',
                fields: {
                    login: {
                        editable: false
                    },
                    per_name: {
                        editable: false
                    },
                    org_name: {
                        editable: false
                    },
                    //lst_user_sec_ids: {
                      //  editable: true
                    //},
                    lst_user_sec_labels: {
                        editable: false
                    }
                }
            }
        },
        change: function (e) {
            if (e.action === 'sync') {
                lists.loadFilehandlers();
                this.read();
            }
        },
        error: function (e) {
            app.printMessage({
                restError: e.xhr
            });
        }
     
    });
 
    $screen.find('#filehandler-grid').kendoGrid({
        dataSource: dataSource,
        sortable: true,
        cache: false,
        noRecords: true,
        pageable: {
            pageSize: 20,
            pageSizes: [20, 50, 100],
            refresh: true,
            info: true
        },
        filterable: {
            extra: false,
            mode: 'row',
            operators: {
                string: {
                    contains: 'Contains'
                },
                number: {
                    eq: 'Equals'
                }
            }
        },
        editable: {
            mode: 'popup',
            template: kendo.template($("#sectors-editor").html())
        },
        edit: function (e) {
            $(e.container).parent().css({
                top: '50px',
                left: '150px',
                width: '850px',
                height: '600px',
                overflow: 'scroll'
            });
        },
         
        resizable: true,
        selectable: 'cell',
 
        columns: [
            {
              field: 'login',
              title: 'ECAS ID',
              hidden: true,
              type: 'string',
              filterable: {
                  cell: {
                      showOperators: false
                  }
              },
              width: '150px'
            },
            {
              field: 'per_name',
              title: 'Name',
              hidden: false,
              filterable: {
                  cell: {
                      showOperators: false
                  }
              }
            },
            {
              field: 'org_name',
              title: 'Unit',
              hidden: false,
              type: 'string',
              filterable: {
                  cell: {
                      showOperators: false
                  }
              }
            },
            {
              field: 'lst_user_sec_labels',
              title: 'Has access to sectors',
              hidden: false,
              type: 'string',
              filterable: {
                  cell: {
                      showOperators: false
                  }
              }
            },
            {
              field: 'lst_user_sec_ids',
              title: 'hide this later',
              hidden: false,
              type: 'string',
              filterable: {
                  cell: {
                      showOperators: false
                  }
              }
            },
            {
              command: [
                  {
                      name: 'edit',
                      text: {
                          edit: 'Edit',
                          cancel: 'Cancel'
                      },
                      click: function(e) {
                          // prevent page scroll position change
                          e.preventDefault();
                          // e.target is the DOM element representing the button
                          var tr = $(e.target).closest("tr"); // get the current table row (tr)
                          // get the data bound to the current table row
                          var data = this.dataItem(tr);
                          // Get the data for the list of sectors and write it into the popup window
                          setSectorsList(data.login, data.lst_user_sec_ids);
                      }
                  }
              ],
              title: 'Actions',
              width: '225px',
              filterable: false
            }
        ]
    });
 
}
0
Michael
Top achievements
Rank 1
answered on 10 Feb 2021, 09:21 AM

UPDATE

If I alter editable: mode: 'popup' to editable: mode: 'inline' the update method fires. So is there some sort of config issue with my popup template?

0
Michael
Top achievements
Rank 1
answered on 10 Feb 2021, 10:14 AM

UPDATE

And if I leave it as editable: mode: 'popup' but remove my custom template so that it uses the default popup template, again the update method fires.

So, I guess the question is now re-defined as: "Why does my custom popup template not fire the update method?" 

Here is the template code, which resides in my html template:

<script id="sectors-editor" type="text/x-kendo-template">
  <h5 class="sectorH5">Set the sectors that this File Handler can edit cases for</h5>
  <div id="sectors-list"><!-- This content is generated by admin-filehandler.js --></div>
</script>

 

0
Michael
Top achievements
Rank 1
answered on 10 Feb 2021, 03:32 PM

UPDATE 3

Here is my (revised) kendo template:

<script id="sectors-editor" type="text/x-kendo-template">
  <h5 class="sectorH5">Set the sectors that this File Handler can edit cases for</h5>
  <div id="sectors-list"><!-- This content is generated by admin-filehandler.js --></div>
  <ul>
      <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids_1073" id="sector_id_1073" value="1073" />seventy-three</label></li>
      <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids_1074" id="sector_id_1074" value="1074" />seventy-four</label></li>
      <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids_1075" id="sector_id_1075" value="1075" />seventy-five</label></li>
  </ul>
</script>

 

 

 

The <div id="sectors-list"> contains a whole load of checkboxes that I generate dynamically. I have a JS function that grabs them from the database, pre-checks some of them as appropriate and then pushes them into that div.

Below it, you can see I have hand-written in three more checkboxes.

If I check or un-check any of the hand-written checkboxes, the update method fires! However, if I check or un-check any of javascript-generated checkboxes, it doesn't.

If I inspect the two types of checkbox in the browser console, they are identical(!)

javascript-generated
<input data-bind="checked:lst_user_sec_ids_98" type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_98" value="98">

hand-written
<input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids_1073" id="sector_id_1073" value="1073" data-bind="checked:lst_user_sec_ids_1073">

So, why don't the javascript-generated checkboxes trigger the Update method?

0
Aleksandar
Telerik team
answered on 12 Feb 2021, 07:41 AM

Hi Michael,

Indeed the issue seems to be related to the custom template used for editing. Comparing the javascript-generated and hand-written checkboxes I see a difference in the name attribute - the hand-written has the value at the end while the javascript-generated doesn't:

javascript-generated
<input data-bind="checked:lst_user_sec_ids_98" type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_98" value="98">

hand-written
<input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids_1073" id="sector_id_1073" value="1073" data-bind="checked:lst_user_sec_ids_1073">

Can you try updating the javascript-generated name attributes in the above manner and check if the issue gets resolved?

Regards,
Aleksandar
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

0
Michael
Top achievements
Rank 1
answered on 12 Feb 2021, 07:49 AM

Hi Aleksandar

Yes, that was one version of the script. I have tried many others but with the same "nothing happening" result.

At present, I have things precisely as you mentioned. The javascript-generated code looks like this:

<ul class="sectorL1">
    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1073" value="1073" /> one seventy-three</label></li>
    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1074" value="1074" /> one seventy-four</label></li>
    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1075" value="1075" /> one seventy-five</label>
        <ul class="sectorL2">
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2073" value="2073" /> two seventy-three</label></li>
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2074" value="2074" /> two seventy-four</label></li>
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2075" value="2075" /> two seventy-five</label></li>
        </ul>
    </li>
    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1076" value="1076" /> one seventy-six</label>
        <ul class="sectorL2">
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2076" value="2076" /> two seventy-six</label></li>
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2077" value="2077" /> two seventy-seven</label>
                <ul class="sectorL3">
                    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_3073" value="3073" /> three seventy-three</label></li>
                    <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_3074" value="3074" /> three seventy-four</label></li>
                </ul>
            </li>
            <li><label><input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_2078" value="2078" /> two seventy-eight</label></li>
        </ul>
    </li>
</ul>

 

My hand-written code looks like this:

<input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1073" value="1073" /> 

And here is what I get in the browser console:

javascript-generated
<input data-bind="checked:lst_user_sec_ids_98" type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_98" value="98">

hand-written
<input type="checkbox" class="checkbox-inline k-valid" name="lst_user_sec_ids" id="sector_id_1073" value="1073" data-bind="checked:lst_user_sec_ids">

I note that kendo does something different when it appends the data-bind attribute. Maybe that's something worth looking at?

All help/advice would be much appreciated.
Thanks,

0
Michael
Top achievements
Rank 1
answered on 12 Feb 2021, 11:44 AM

Hi Aleksandar

 

So, here's a question. Forget about the hand-written checkboxes for now, let's just focus on the real ones.

I inject a checkbox into the template that looks like this:
<input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1074" value="1074" />

But when I view it in the browser console I see this:
<input type="checkbox" class="checkbox-inline" name="lst_user_sec_ids" id="sector_id_1074" value="1074" data-bind="checked:lst_user_sec_ids_1074" />

So we know that Kendo has seen the checkbox because it has appended the data-bind attribute. But the value of that attribute has the sec_id tagged onto the end. What we therefore end up with is a checkbox whose name attribute matches the datasource ("lst_user_sec_ids") but a data-bind attribute that doesn't ("checked:lst_user_sec_ids_1074").

Why does Kendo do that, is it important, and is it this action that is causing the problem?

0
Viktor Tachev
Telerik team
answered on 16 Feb 2021, 07:55 AM

Hi Michael,

 

I will paste my reply from the support ticket here for clarity as it can help someone with similar scenario.

 

The checkbox widgets are  usually intended to be bound to boolean fields. However, in this scenario it seems like there are multiple checkboxes that should be bound to a numeric field. 

In order for the binding of the values and the editing to work as expected I would suggest using a dropdown to present multiple options for selection to the users. You can use MVVM to set what values would be available in the dropdown. The approach is illustrated in the example below:

https://dojo.telerik.com/EgEgiXUs/3


In case you would like to have multiple options selected and the lst_user_sec_ids field represents an array you can use a MultiSelect as editor. Check out the example below that shows how that behavior can be implemented:

https://dojo.telerik.com/AyexEnuG

 

Regards,
Viktor Tachev
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Data Source
Asked by
Michael
Top achievements
Rank 1
Answers by
Michael
Top achievements
Rank 1
Aleksandar
Telerik team
Viktor Tachev
Telerik team
Share this question
or