Two select boxes - can first select box control the ipOpts of the second?

Two select boxes - can first select box control the ipOpts of the second?

guntergunter Posts: 11Questions: 0Answers: 0
edited February 2013 in Editor
I am using two select boxes. Now I want that the ipOpts-Fields of my second select box change depending on selecting a value in the first select box.
The table is populated with an Ajax-Request on loading from TableLoadServlet. The first select-box is filled also on loading the table with the ipOptsArray. So far my program is working. Now my problem is how can I find out, which value is selected in the first select box and then how to load the ipOpts data to populate the second select box. What command should I use to send to the server?

Here is my code:

$(document).ready(function() {

var editor = new $.fn.dataTable.Editor( {
"ajaxUrl": "TableLoadServlet",
"domTable": "#timesheet",
"fields": [
{
"label": "FirstSelectBox",
"name": "project_number",
"type": "select",
"ipOpts": ipOptsArray
},
{
"label": "SecondSelectBox",
"name": "pos_name",
"type": "select",
"ipOpts": functionToLoadData(project_number.selected.value) // should be refreshed when selecting a value in the first select box
}
]
}

} );

Replies

  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Hi,

    The way to do this in Editor is two fold - firstly you need to listen for the `onInitCreate` and `onInitEdit` events so you can initialise the form when it is shown for an edit or delete. Then you also need to listen for a `change` event from the select box.

    This might be setup thus:

    [code]
    editor = new $.fn.dataTable.Editor( {
    "ajaxUrl": "TableLoadServlet",
    "domTable": "#timesheet",
    "fields": [ {
    "label": "FirstSelectBox",
    "name":"project_number",
    "type": "select",
    "ipOpts": ipOptsArray
    },
    {
    "label": "SecondSelectBox",
    "name":"pos_name",
    "type": "select"
    } ]
    } );

    // Initialise the form to the correct values on create / edit
    editor.on('onInitCreate onInitEdit', function () {
    editor.field('pos_name').update(
    functionToLoadData( editor.get('project_number') )
    );
    } );

    // Listen for change events from the 'project_number' select and update
    $('select', editor.node('project_number')).on('change', function () {
    editor.field('pos_name').update(
    functionToLoadData( editor.get('project_number') )
    );
    } );
    [/code]

    So the key things here are:

    1. The use of the `node` API method from Editor to get the container node for the 'project_number' field (and thus the 'select' so we assign a 'change' event to it).

    2. The `update` method for the field to update the data available - this is field specific the radio and select types have this method.

    3. The `get` method to get the current value from Editor.

    Regards,
    Allan
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    I should say that the Editor roadmap has field events scheduled for v1.4 (1.2 is the current release) - so you'd be able to listen for the `change` event a little easier. Rather than needing the two extra blocks above (init and update) you'd just need one.

    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    Hi Allen,

    thank you for your solution. It works so far. But how to get the data to populate the ipOpts for pos_name from the server?. Can you give me an example how the call to the server to get the JSON-data should look like, please?
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    So basically what the `functionToLoadData` function does? You've got two basic options that I can see:

    1. Make an Ajax call to the server with `$.ajax` to get the values you need - and then use the `update` field method in the `success` function for the Ajax call to update the field with the returned values.

    2. Do some kind of processing on the data you already have on the client-side to build the array needed, based upon the values you have and then return that array.

    Depending on the complexity of the data, you might choose one of these two methods.

    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    Hi Allen,

    thank you for the quick response. I am using your first suggestion using $.ajax. The code is;

    function functionToLoadData(id) {


    $.ajax({
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    url: 'TableLoadServlet?action=2&projid=' + id,
    async: false,
    dataType: 'json',
    success: function (json) {
    for(var i=0;i
  • guntergunter Posts: 11Questions: 0Answers: 0
    Hi Allen,

    I found an obvious error in the load method. But still the select box stays empty. Here is the code:

    var arrPosName = new Array();

    function functionToLoadData(id) {

    $.ajax({
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    url: 'TableLoadServlet?action=2&projid=' + id,
    async: false,
    dataType: 'json',
    success: function (json) {
    for(var i=0;i
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Okay, that looks like a good start! What I would suggest is trying this, just to sanity check that it will update as you expect without Ajax:

    [code]
    function functionToLoadData(id) {
    editor.field('pos_name').update( [
    { label:"Test 1", value: "Test 1" },
    { label:"Test 2", value: "Test 2" }
    ] );
    }
    [/code]

    Now assuming that works (it should, assuming `editor` is an available variable!), what looks to me to be the issue with your Ajax call is that you have:

    > json[i][0]

    But you say the JSON coming back from the server is in the format:

    > {"pos_name":"Position 1","posid":"10"}

    So don't you want something like:

    > obj = { "label" : json[i].pos_name, "value" : json[i].posid};

    Also, I don't think you want your array to be 'global' - it will just add data to it on every call, rather than clearing it out and replacing it with new data!

    I would suggest you try something like this:

    [code]
    success: function ( json ) {
    var a = [];
    for ( var i=0, ien=json.length ; i
  • guntergunter Posts: 11Questions: 0Answers: 0
    Hi Allen,

    I can see the alert with the id, but no data in the select box.

    {
    "label": "Angebotsposition",
    "name": "pos_name",
    "type": "select"
    },


    [code]
    function functionToLoadData(id) {
    alert(id);
    editor.field('pos_name').update( [
    { label:"Test 1", value: "Test 1" },
    { label:"Test 2", value: "Test 2" }
    ] );
    }
    [/code]

    How can I check if editor is available?

    Gunter
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Are you getting a Javascript error in your browser's console? That's the most common way.

    What you might consider doing is passing the `editor` variable into `functionToLoadData` :

    [code]
    functionToLoadData( editor, editor.get('project_number') )
    [/code]

    And change the function to be:

    [code]
    function functionToLoadData( editor, id) {
    console.log( 'going to update the pos name' );
    editor.field('pos_name').update( [
    { label:"Test 1", value: "Test 1" },
    { label:"Test 2", value: "Test 2" }
    ] );
    console.log( 'update done' );
    }
    [/code]

    I've added a couple of console debug lines just to see what is going on in your browser's console.

    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    There are no Javascript errors in the browser console. Here is the console log output:

    going to update the pos name table.timesheet.js:94
    update done table.timesheet.js:99


    Gunter
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Are you able to link me to the page you are working on? The looks like it should be updating the field to me.

    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    I appreciate your help very much. I am sorry but I am not able to link to the page as I don't have it installed on a web server yet. It's just a project in eclipse. I could send you the code or maybe we could do a remote session.
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Hi,

    Thanks for the link (removed from the public forum here).

    So the problem was that the `update` method on the field was being called twice - the first time with the correct data being set, but immediately after that with `undefined` data causing the list to look empty.

    This is how the event handler code for the change event was (the `init` events have the same problem and the fix is the same):

    [code]
    $('select', editor.node('project_number')).on('change', function () {
    editor.field('pos_name').update(
    functionToLoadData( editor, editor.get('project_number') )
    );
    } );
    [/code]

    So you can see here that `update` is being passed the return from your load data function. That's fine, if your function were to return a data array - it isn't! Instead, the function is itself calling the `update` . So what it should look like is:

    [code]
    $('select', editor.node('project_number')).on('change', function () {
    functionToLoadData( editor, editor.get('project_number') );
    } );
    [/code]

    Add in your Ajax call and it should be good to go!

    Regards,
    Allan
  • vinod_ccvvinod_ccv Posts: 75Questions: 0Answers: 0
    Hi allan,
    It works awesome for me. Only difference in approach that as you told, i used the second method instead of ajax call
    [quote]2. Do some kind of processing on the data you already have on the client-side to build the array needed, based upon the values you have and then return that array.[/quote]

    Let me share it , may be useful for some one.
    [code]
    /////STEP 1://///
    // Initialise the form to the correct values on create / edit
    editor.on('onInitCreate onInitEdit', function () {
    functionToLoadData( editor, editor.get('project_number') );
    } );

    // Listen for change events from the 'project_number' select and update
    $('select', editor.node('project_number')).on('change', function () {
    functionToLoadData( editor, editor.get('project_number') );
    } );
    /////STEP 2: making a variable global/////////////////////////////


    $(document).ready(function() {
    var jsonpos = null;
    ...............................
    ...............................

    //////STEP3: Getting json values. (positionList is my json object from server-side)////////
    "fnInitComplete": function ( settings, json ) {

    jsonpos=json.positionList;


    }
    ///////STEP 4: Selecting the applicable values and making array///////////////////////////////////
    function functionToLoadData(editor,id)
    {
    var a = [];
    for (var i = 0; i
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Thanks for posting your solution - I'm sure others will find it useful.

    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    Hi Allen,

    I have considered all your hints and it works great now. Thank you so much for your help.
    There is one issue left what I could make better. On clicking on edit, the editor always starts with the data of the first row of the data table. I think it should be better to use the data of the row that has been clicked on. Is that possible, and if, how?

    Gunter
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    > On clicking on edit, the editor always starts with the data of the first row of the data table. I think it should be better to use the data of the row that has been clicked on. Is that possible, and if, how?

    Never mind making it better, I would say that is critical!

    Looking at the page you sent me before, let's take the last row as an example - where "Projectnumber" is `111111` .

    In the Editor project select list you have the following options:

    [quote]
    Value: `1` - Display: `111111, divers`
    Value: `30` - Display: `3, Testdrei`
    [/quote]

    So when Editor display's the form, it is trying to set the value `111111` ( `project_number` in your JSON) but not finding it in the data available, thus all it can do is show the OS default selection, which is the first value.

    So there is a discrepancy between the data being shown in the select list, and the data that is being set as the value.

    Looking at your JSON data, I think you want to change:

    > "name": "project_number",

    in your table.timesheet.js to be:

    [code]
    "name": "projid",
    [/code]

    That will get the `projid` for the project and set that as the value, which matches what is in the `value` attribute for that project in the select!

    Regards,
    Allan
  • guntergunter Posts: 11Questions: 0Answers: 0
    You are right. That's it. I have changed the name to projid and the concerned references. Now it works like a charm. Thank you again for your help, Allen.

    Gunter
  • vinod_ccvvinod_ccv Posts: 75Questions: 0Answers: 0
    Hi Allan,
    Is it possible to push and update some 'default values' for fields using 'functionToLoadData' other than 'label' / 'value'.
    In my case, I have a check-box field and its options are loaded according to previous select field. I could display the options using the method above, but I need default tick marks on few options. Any solution in your magic box :)
  • allanallan Posts: 63,534Questions: 1Answers: 10,475 Site admin
    Call the `set` method with the values that you want to set for the field, after you've called `update` .

    Allan
This discussion has been closed.