MJoin with field type select not working

MJoin with field type select not working

rossbobrossbob Posts: 29Questions: 4Answers: 0

Link to test case: http://live.datatables.net/raserege/1/edit
Debugger code (debug.datatables.net):
Error messages shown:

<br />
<b>Warning</b>: count(): Parameter must be an array or an object that implements Countable in <b>/var/www/html/autoscales/public/vendor/datatables.net/editor-php/Editor/Join.php</b> on line <b>781</b><br />
<br />
<b>Warning</b>: count(): Parameter must be an array or an object that implements Countable in <b>/var/www/html/autoscales/public/vendor/datatables.net/editor-php/Editor/Join.php</b> on line <b>781</b><br />
{"fieldErrors":[{"name":"rack_details[].id","status":"This field is required."}],"data":[]}

Description of problem:

If I define rack_details[].id in my JS editor definition ie let editor = new $.fn.dataTable.Editor(..., as type select, I get the above PHP error message from Apache. If I change the type the checkbox, everything works.

When its set to select and I submit, the post data looks like this;

data[row_6][scale_prog_id]: 1004
data[row_6][scale_desc]: Scale 4
data[row_6][dbDateTime]: 2020-05-12 15:04:12
data[row_6][pad_count]: 6
data[row_6][rack_details]: 1
data[row_6][status]: Active
action: edit

When it's set to checkbox (which works), it looks like this;

data[row_6][scale_prog_id]: 1004
data[row_6][scale_desc]: Scale 4
data[row_6][dbDateTime]: 2020-05-12 15:04:12
data[row_6][pad_count]: 6
data[row_6][rack_details][0][id]: 1
data[row_6][rack_details-many-count]: 1
data[row_6][status]: Active
action: edit

Obviously the error I am getting is because the data being posted to the server is not correct, which I get, but I do not understand how to correctly format my select so that the client knows that it is an MJOIN. I didn't have to do anything fancy with checkbox, it just worked.

Any ideas?

Cheers,

Ross.

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406
    edited May 2020 Answer ✓

    One reason could be that you implemented the select field as a single select field and not as multi-select. Which means you are not passing an array which causes the error. Using select with an Mjoin requires the select field to be multi-select, if I recall it correctly. I found this rather complex transformation in my code to make selectize work with an mjoin and single select:

    I would recommend you change the field to be multi-select. If that works: great! If it should only be permitted to select just one value you'll need to find a way to implement it somehow ...

    editor = new $.fn.dataTable.Editor( {
       ajax: {
            url: 'actions.php?action=tblContractEntryGov',
            data: function ( d ) {
        //make selectize work with an mjoin and single select!
                if (d.action === 'create' || d.action === 'edit') {                
                    var keys = Object.keys(d.data); //array of object keys
                    var rowId = keys[0]; //row_xxx (edit) or 0 (create)
                    if ( typeof d.data[rowId].base !== 'undefined' ) {                    
                        var baseId = d.data[rowId].base;            
                        if ( typeof baseId === 'string' || baseId instanceof String) {
                            delete d.data[rowId].base;
                            if (baseId > '0') {
                                var base = []; var element = {};
                                element.id = baseId; //set property id of element object
                                base.push(element); //put element object into base array
                                d.data[rowId].base = base; //set new property of object and put the array into it
                                d.data[rowId]["base-many-count"] = 1; //set the many count as well                           
                            } else {                            
                                d.data[rowId]["base-many-count"] = 0; //set the many count as well            
                            }
                        }
                    }
                }
            }
        },
    table: "#table",
    fields: [ .... {
            label: lang === 'de' ? 
                    'Optional, Auswahl Basisgeschäft:' : 
                    'Optional, Selection of base contract:',
            name: "base[].id", //render gov_name, govdept_name
            type: "selectize", 
            opts: {
                create: false,
                maxItems: 1,
                openOnFocus: true,
                allowEmptyOption: true,
                placeholder: lang === 'de' ? 
                    'Bitte ein Basisgeschäft wählen (optional)' : 'Please select one base contract (optional)'
                }
        }, .....
    

    This field here works fine with the Mjoin without any transformation because it is a multi-select field in the same Editor instance. Same applies to using "select" or "select2".

    }, {
            label: lang === 'de' ? 
                    'Wählen Sie einen oder mehrere Verträge über Basisgeschäfte:' : 
                    'Select one or more underlying contracts:',
            name:  "underlying[].id", //render serial, instrument, type, number
            type: "selectize", 
            opts: {
                create: false,
                maxItems: null,
                openOnFocus: true,
                allowEmptyOption: true,
                placeholder: lang === 'de' ? 
                    'Bitte Grundgeschäft auswählen' : 'Please select underlying'
                }
        }, {
    
  • rossbobrossbob Posts: 29Questions: 4Answers: 0

    Ah ok, I get it now, MJOIN is the wrong use case for what I'm trying to do. Thanks for helping me understand that.

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    The problem really is that a single select sends a different data structure to the server than a multi select that only selects one item. Even though - in both cases - only one item is being sent to the server.

    But: if you need to use a link table you need the Mjoin which expects the data structure of a multi select. (In most cases of course you won't need an Mjoin when using a single select field: It is usually just an options instance for a foreign key in the parent table. But that changes if you have self-referencing relationships which mostly require the usage of a link table even though they do not resolve an N:M relationship.)

    There are 2 work arounds:
    1. Manipulate the data structure to make the single select send the same data to the server than a multi select with one or no option selected
    2. Use a multi select field client side; if the user selects more than one value: send an error message to the front end: "Please select only one value!"

    I decided for the first work around because I found the second one not user friendly enough even though it is much simpler to implement.

This discussion has been closed.