Using Bootstrap table with Aurelia


#1

I am struggling with using bootstrap table with aurelia i think which is due to some context problems or timing issues i am not shure tbh.

I have classes that is injected with the correct api endpoints and informations etc, also trying to inject api directly into a class called tableformatter. bootstrap table want to call function that is uses to format data, or show details etc etc.

the constructor in the class is run correctly and saves this.api with an object of the api.

the problem is when bootstraptable calls the transactionsDetailFormatter function inside the tabelformatter class. this functions need to call the api to get the details, but now the class variable api is undefined.

so i am guessing this have to do somewhat with that bootstraptable dosnt live in the context of aurelia ?

but i am confused on how to fix this. is there a better way to use bootstrap table with aurelia.

i mport { inject } from ‘aurelia-framework’;
import { Config } from “aurelia-api”;
import Moment from “moment”;

@inject(Config)
export class TableFormatter {

constructor(config) {
console.log(“InitTableFormatter”);
this.api = config.getEndpoint(‘api’);

}


#2

I am looking at anoter solution i have with older js and jquery the bootstrap table is given the string to where the method is. where in aurelia i didnt manage to do that so it seems it as reference direclty to the function it self ore i gues a copy of it. is there a way to access aurelia code directly from console without being in debug


#3

You might want to add a link to whatever library you are using to your post.
It is hard to grasp what you are trying to do.
And not everybody has time too google…

My guess is that as bootstrap itself… it relies on jQuery global…
so importing it in the module would do no good for you.

Have to see the specifics.


#4

to ask another way is there a way to bind a method that lives inside my aureliamodule to the bootstraptable component on the html side. when i do it with just passing in the name of the function. and debugging into the bootstrap table i get the following:

old working plain js solution:“namespace.classname.functionname” as a string exactly likei gave it, and bootstrap table know to call this method and it is still in the context of the solution. it seems to me like it still is holding just the name of wherever the function is in your solution.

while in my aurelia project it seems to hold a copy of the source code of the method only so instead of seeing the string of where the method is i can see the source code like function(){… in the field.

the method is given to bootstraptable like this in html in the old solution this way didnt work at all in aurelia i tried with this.functioname not the old namespace etc.
data-detail-formatter=“namespace.Public.Table.transactionsDetailFormatter”>

and the table is initiated from js like this in the old solution
$(’#tblTransactions’).bootstrapTable({-------------------------

i can post more details later if this is not enough. but is there something i am missing aurelia wise to try to give a random component a way to call an aurelia method from html. or is it just not possible since this is loaded into the application with jquery.


#5

Sorry… still hard to decipher this.
can you start from the basic example that works for you without aurela and how you try to do that same o ne with aurelia?


#6

i am using a bootstrap extension called bootstrap-table. and the js code is though i am stripping away some of the functions as i am giving it data directly insteaf of using its built in ajax functionalities. but the issue is example like this data-detail-formatter=“iDrift.Public.Table.transactionsDetailFormatter”

 function initTable() {         $('#tblTransactions').bootstrapTable({
             url: '',
             method: 'post',
             pageSize: 20,
             pageList: [10, 20, 50, 100, 500],
             pagination: true,
             exportDataType: 'all',
             sidePagination: 'server',
             idField: 'Id',
             showLoading: true,
             cookie: true,
             cookieExpire: '7d',
             cookieIdTable: 'tblTransactions',
             onClickRow: function (row, $element) {
 
             },
             onColumnSwitch: function (field, checked) {
                 iDrift.Public.toggleTableFilterOnEvent('tblTransactions', bootstrapTableLocalStorageFilterKey);
             },
             onToggle: function (cardView) {
                 if (!cardView) {
                     iDrift.Public.toggleTableFilterOnEvent('tblTransactions', bootstrapTableLocalStorageFilterKey);
                 }
             },
             queryParams: function (params) {
                 var newParams = iDrift.Public.Table.search(params);
                 return newParams;
             },
             ajaxOptions: {
                 beforeSend: function (jqXHR) {
                     jqXHR.setRequestHeader("Authorization", iDrift.API.tokenData());
                     return jqXHR;
                 },
                 success: function (jqXHR) {
                 },
                 complete: function (jqXHR) {
                 }
             }
         })
     }

html is


 <table id="tblTransactions" class="table table-hover table-striped table-condensed table-responsive" cellpadding="0" cellspacing="0" border="0"
           data-toolbar="#SActivityLogToolbar"
           data-search="false"
           data-show-toggle="true"
           data-sortable="true"
           data-filter-control="true"
           data-show-columns="true"
           data-show-export="true"
           data-filter-show-clear="true"
           data-export-types="['excel','csv', 'txt','xml', 'pdf']"
           data-detail-view="true"
           data-detail-formatter="iDrift.Public.Table.transactionsDetailFormatter">
        <thead>
            <tr>
                <th id="thTransactionId"
                    data-field="Id"
                    data-sortable="true"
                    data-visible="false">ID</th>
                <th id="thTransactionExternalId"
                    data-field="ExternalId"
                    data-sortable="true"
                    data-filter-control="input"
                    data-visible="true">POGO Id</th>
                <th id="thTransactionDescription"
                    data-field="Description"
                    data-sortable="true"
                    data-filter-control="input"
                    data-visible="true">Description</th>
                <th id="thTransactionCreated"
                    data-sortable="true"
                    data-visible="true"
                    data-filter-control="datepicker"
                    data-filter-datepicker-options='{"autoclose":true, "clearBtn": true, "todayHighlight": true}'
                    data-field="FromDate"
                    data-formatter="iDrift.Public.Table.dateFormatter">From Date</th>
                <th id="thTransactionAmount"
                    data-field="Amount"
                    data-sortable="true"
                    data-filter-control="input"
                    data-visible="true"
                    data-align="right"
                    data-formatter="iDrift.Public.Table.moneyFormatter">Amount</th>
                <th id="thTransactionTransfered"
                    data-sortable="true"
                    data-visible="true"
                    data-filter-control="datepicker"
                    data-filter-datepicker-options='{"autoclose":true, "clearBtn": true, "todayHighlight": true}'
                    data-field="PostedPOGO"
                    data-formatter="iDrift.Public.Table.dateFormatter">Transfered to POGO</th>
                <th id="thTransactionUser"
                    data-sortable="true"
                    data-visible="true"
                    data-filter-control="input"
                    data-field="CreatedBy">By user</th>
                <th id="thTransactionTickerName"
                    data-field="TickerName"
                    data-sortable="true"
                    data-filter-control="input"
                    data-visible="true">TickerName</th>
            </tr>
        </thead>
    </table>

and tableclass is just a class in the namespace that have different methods for returning a formatted response do data. example dateformatter is called for each row in the corrospinding column.
and some more advanced to get details like s subrow etc

function classTable() {
    this.clearFilter = function(tableName, apiURL) {
        //Remove all cookies, except columns
        $.each($.cookie(), function (name, value) {
            if (name.startsWith(tableName)) {
                if (!name.endsWith('columns'))
                    $.removeCookie(name);
            }
        });

        //Remove all localStorage (egne søkefelt, ikke kolonne søk)
        var arr = []; // Array to hold the keys
        // Iterate over localStorage and insert the keys that meet the condition into arr
        for (var i = 0; i < localStorage.length; i++) {
            if (localStorage.key(i).substring(0, tableName.length) == tableName) {
                arr.push(localStorage.key(i));
            }
        }
        // Iterate over arr and remove the items by key
        for (var i = 0; i < arr.length; i++) {
            localStorage.removeItem(arr[i]);
        }

        //Destroy, init and refresh table
        $('#' + tableName).bootstrapTable('destroy');
        initTable();
        $('#' + tableName).bootstrapTable('getOptions').url = apiURL;
        refresh();
    }

    this.search = function(params, tableName) {
        //Convert to json
        if (typeof (params.filter) != "undefined")
            params.filter = JSON.parse(params.filter);

        if (iDrift.User.accessLevel.administrator == false)
            params.CompanyID = iDrift.User.companyID;

        //Check if we can hide data-filter (iterate params.filter)
        if (!iDrift.Public.searchParamsExists(params.filter) && localStorage != null && (localStorage[bootstrapTableLocalStorageFilterKey] == "false" || localStorage[bootstrapTableLocalStorageFilterKey] == undefined)) {
            iDrift.Public.showBootstrapTableFilter(false, undefined, undefined, tableName);
        }

        return params;
    }

    this.boolFormatter = function boolFormatter(value, row) {
        if (value == true)
            return '<i class="fa fa-check"></i>';
        else
            return '<i class="fa fa-times"></i>';
    }

    this.dateFormatter = function dateFormatter(value, row) {
        try {
            if (value != null) {
                return moment(value).format('YYYY-MM-DD');
            }
            else {
                return "-";
            }
        }
        catch (ex) {
        }

        return value;
    }

 this.transactionsDetailFormatter = function (value, row) {
        var html = "";
        //Check that we have a id
        if (row.Id !== null && row.Id > 0) {
            //Add wait symbol
            html = '<div id="waitingForDetails' + row.Id + '" class="waiting waiting32"></div>';
            //Load details
            iDrift.API.getTransactionDetails(row.Id, function (details) {
                //Success
                if (typeof details.rows !== 'undefined' && details.rows.length > 0) {
                    //Details is available. replace wait symbol
                    var result = iDrift.Public.Table.convertTransactionResultToTable(details);
                    $('#waitingForDetails' + row.Id).parent().html(result);
                }
                else {
                    $('#waitingForDetails' + row.Id).parent().html(iDrift.Language[iDrift.User.language].transactions.NoDetails);
                }
            },
            function (errorMessage) {
                //Failure
                $('#waitingForDetails' + row.Id).parent().html(iDrift.Language[iDrift.User.language].errorMessages.loadDeatailsError);
            });
        }
        else {
            html = '<p id="loadedDetails">' + iDrift.Language[iDrift.User.language].errorMessages.loadDeatailsError + '</p>';
        }
        return html;
    }

obiously the methods need to be written to use new api classes. but thats the problem i cant get bootstrap table to call the functions in the correct way. the way i manage to get it called. it was completly out of aurelias context didnt have any of the injected content or any variables that is set in the constructor. when i try with .bind on the html property. the table writes out the function code instead of calling it.


#7

Hei there, thank you for your patience. i just edited the post a littlebit i saw the quoting was a bit off. I am not necesarly just after a solution. More like can it be done, is there something realy simple noobish stuff i am missing. ore is it just the component that dosnt know how to handle function binding(if thats a real thing).

also looking into ag-grid that supports aurelia. looking at the example https://www.ag-grid.com/best-aurelia-data-grid/. they are setting the data variable from html not from the js side.

please correct me if i am wrong. but is the reason for it that when running the constructor html isnt yet alive. but when running attached you no longer have your state anymore ?