Change in field doesn't activate save/cancel in custom component table.

So, I’m building my own Recycle Bin.

I’m using the “Custom” component to build a dynamic model and a table that adopts the rows of a bunch of other dynamic models. I’ll paste the code below. The table has a row action which updates the IsDeleted field to false (trying to ‘undelete’ the row). When that action runs, the field value is changed in the model from true to false, but nothing is added to the model’s ‘changes’ and hasChanged still equals false. What might be going wrong here?

var element = arguments[0], $ = skuid.$,
$xml = skuid.utils.makeXMLDoc;
var modelObjects = ['Patient__c', 'Patient_Case__c', 'Interaction__c', 'Abortion__c', 'Related_Person__c', 'STD_Test__c', 'Attachment', 'Reoccurance__c', 'Signature__c'];
    var modelsXML = $.map(modelObjects, function(name){
        return $xml('<model id="'+ name +'" limit="20" query="true" createrowifnonefound="false" adapter="" type="" sobject="'+ name +'" orderby="LastModifiedDate DESC" doclone="" queryallrows="true"/>').append(
            $xml('<fields/>').append(
                $xml('<field id="Name"/>'),
                $xml('<field id="Id"/>'),
                $xml('<field id="LastModifiedDate"/>'),
                $xml('<field id="LastModifiedById"/>'),
                $xml('<field id="LastModifiedBy.Name"/>'),
                $xml('<field id="IsDeleted"/>'),
                $xml('<field id="ObjectType" uionly="true" displaytype="FORMULA" label="Object Type" readonly="true" returntype="TEXT"/>').append(
                    $xml('<formula>{{$Model.'+ name +'.labelPlural}}</formula>')
                )
            ),
            $xml('<conditions/>').append(
                $xml('<condition type="fieldvalue" value="true" enclosevalueinquotes="false" field="IsDeleted"/>')
            ),
            $xml('<actions/>')
        );
    });
    
    var allModels = $.map(modelsXML, function(x){
        return new skuid.model.Model(x);
    });
$.each(allModels,function(){
    this.initialize().register();
});
$.when(skuid.model.load(allModels)).then(function(){
    var xmlDefinition = $xml('<skootable showconditions="true" showsavecancel="true" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="25" createrecords="false" model="RecycleBin" buttonposition="" mode="readonly" uniqueid="deletedItemsTable"/>')
        .append(
            $xml('<fields/>').append(
                $xml('<field id="Name" allowordering="true"/>'),
                $xml('<field id="ObjectType" allowordering="true"/>'),
                $xml('<field id="LastModifiedById" allowordering="true"/>'),
                $xml('<field id="LastModifiedDate" allowordering="true"/>')
            ),
            $xml('<rowactions/>').append(
                $xml('<action type="multi" label="Undelete" icon="sk-icon-add"/>').append(
                    $xml('<actions><action type="updateRow" fieldmodel="RecycleBin" field="IsDeleted" enclosevalueinquotes="false" value="false"/></actions>')
                )
            ),
            $xml('<massactions usefirstitemasdefault="true"/>'),
            $xml('<views><view type="standard"/></views>')
    );
    var rows = [];
    $.each(skuid.model.list(),function(i,m){
        if (m.getRows().length){
            $.each(m.getRows(), function(i,r){
                rows.push(r);
            });
        }
    });
    var model = new skuid.model.Model();
    model.objectName = 'Patient__c';
    model.id = 'RecycleBin';
    model.fields = [
        { id: 'Name' },
        { id: 'Id' },
        { id: 'LastModifiedById' },
        { id: 'LastModifiedBy.Name' },
        { id: 'LastModifiedDate' },
        { id: 'IsDeleted' },
        { 
            id: 'ObjectType',
            uionly: true,
            displaytype: 'TEXT',
            label: 'Object Type',
            readonly: true
        }
    ];
    model.conditions = [
        { 
            type: 'fieldvalue', 
            field: 'IsDeleted', 
            operator: '=', 
            value: true, 
            state: 'alwayson',
            encloseValueInQuotes: false
        }
    ];
            
    $.when(model.initialize().register().load()).then(function(){
        model.adoptRows(rows);
        element.empty();
        skuid.component.factory({
           element: element,
           xmlDefinition: xmlDefinition
        });    
    });
    
});
    

Do I have to do something to register the adopted rows with the model?

I’m pretty sure the IsDeleted field is a read-only field. Skuid is probably reading that metadata and throwing out the update. I may be wrong about this, but I think the only way to undelete a record in salesforce is with the DML Undelete command, which Skuid does not support. Feel free to prove me wrong though.

Hmm. Would that I knew this before I began!

I can run an apex action from skuid, though, right? Is there a good tutorial for that somewhere?

I think this is the definitive post on the subject.
https://community.skuidify.com/skuid/topics/calling_apex_function

Thanks, Ben. It looks like that post was written before Banzai. I believe y’all added an action called ‘Run Custom Apex Action.’ Does that change anything?