Opened 13 years ago

Closed 13 years ago

Last modified 12 years ago

#803 closed defect (fixed)

sortable table - <tr selected="true"> b0rken

Reported by: mark@… Owned by: Tom Trenka
Priority: high Milestone:
Component: General Version: 0.2
Keywords: Cc:
Blocked By: Blocking:

Description

Adding the selected="true" attribute into the <tr> tag does not (at the moment) actually pre-select the row.

The function

reset:function(){

summary

completely resets the internal representations.

this.columns=[];

this.data=[];

Commented out to allow <tr selected="true"> facility

this.resetSelections(this.domNode.getElementsByTagName("tbody")[0]);

},

in SortableTable?.js needs the end line commented out (*cough* removed) like above to allow the functionality required.

Basically PostCreate?() calls parseColumns() which calls reset(), PostCreate?() then calls parseDataFromtable() which tests the <tr>s for the attribute 'selected' - which has just been removed by resetSelections().

Everything else works fine with the suggested amend in place, though you may like to test that yourself.

BTW - keep up the good work :o)

Change History (10)

comment:1 Changed 13 years ago by as above

Addendum:

Using a named valueField (and dynamic XML creation process) in place of Id seems to snag the quick fix above when using meta [ctrl] to deselect a pre-selected row - in that compare uses o1Id? within the isSelected calls of onUISelect.

A dirty fix is adding

if (!o1Id?) o1Id? = o1[this.valueField]; if (!o2Id?) o2Id? = o2[this.valueField];

at the start of the compare() function

Hopefully you can find a better fix ;o)

comment:2 Changed 13 years ago by Tom Trenka

Owner: changed from anonymous to Tom Trenka

Can you post examples as opposed to fixes? If I see the examples under which it's failing I can make better fixes than the hacks above :)

comment:3 Changed 13 years ago by alex

Tom: why the abuse for folks submitting patches?

comment:4 Changed 13 years ago by alex

Milestone: 0.4

comment:5 Changed 13 years ago by mark@…

Apologies for the delay replying - system snags at home so email erratic.

To get the selected rows working, the initial fix is needed (or some workaround anyway). The valueField snag might just be due to the way I am generating the tables (as detailed below...)

Rather than using the second pass parser (the one that instantiates the dojo objects from XML) I wrote a workaround script that just interprets a html table within an XML node...

function receiveAjaxXML(type, xmlObject, evt) {
    switch(type) {
        case 'load':
            // get the SortableTable content
            sort = xmlObject.getElementsByTagName('sortableTable');
            if ( sort.length == 1 ) {
                setTableContent( sort[0] );
            }
    }
}

function setTableContent(sortroot) {
    // first clear the old table if any
    tblContainer = sortroot.getElementsByTagName('container')[0];
    if ( tblContainer ) {
        tblContainerNode = document.getElementById( tblContainer.getAttribute('id') );
        removeChildrenFromNode( tblContainerNode );
    }
    // build the table
    tblXML = sortroot.getElementsByTagName('table')[0];
    tbl = document.createElement('TABLE');
    tbl.setAttribute("dojoType", "SortableTable");
    attrs = tblXML.attributes;
    for (i=0, il=attrs.length; i<il; i++) {
        attr = attrs[i];
        tbl.setAttribute(attr.nodeName, attr.nodeValue);
        // alert('adding attr '+attr.nodeName+' : '+attr.nodeValue);
    }
    // add the header
    thead = document.createElement('THEAD');
    tbl.appendChild( thead );
    thead_tr = document.createElement('TR');
    thead.appendChild( thead_tr );
    theadXML = tblXML.getElementsByTagName('thead')[0];
    thead_rows = theadXML.getElementsByTagName('tr')[0].getElementsByTagName('th');
    for (i=0, il=thead_rows.length; i<il; i++) {
        thead_row = thead_rows[i];
        th = document.createElement('TH');
        thead_row_attrs = thead_row.attributes;
        for (j=0, jl=thead_row_attrs.length; j<jl; j++) {
            thead_row_attr = thead_row_attrs[j];
            th.setAttribute(thead_row_attr.nodeName, thead_row_attr.nodeValue);
            // alert('adding attr '+thead_row_attr.nodeName+' : '+thead_row_attr.nodeValue);
        }
        th.innerHTML = thead_row.firstChild.nodeValue;
        thead_tr.appendChild( th );
    }
    tbody = document.createElement('TBODY');
    tbl.appendChild( tbody );
    tbodyXML = tblXML.getElementsByTagName('tbody')[0];
    tbody_rows = tbodyXML.getElementsByTagName('tr');
    for (i=0, il=tbody_rows.length; i<il; i++) {
        tbody_row = tbody_rows[i];
        tbody_tr = document.createElement('TR');
        tbody_row_attrs = tbody_row.attributes;
        for (j=0, jl=tbody_row_attrs.length; j<jl; j++) {
            tbody_row_attr = tbody_row_attrs[j];
            tbody_tr.setAttribute(tbody_row_attr.nodeName, tbody_row_attr.nodeValue);
            // alert('adding attr '+tbody_row_attr.nodeName+' : '+tbody_row_attr.nodeValue);
        }
        tbody.appendChild( tbody_tr );
        row_cells = tbody_rows[i].getElementsByTagName('td');
        for (j=0, jl=row_cells.length; j<jl; j++) {
            td = document.createElement('TD');
            td.innerHTML = row_cells[j].firstChild.nodeValue;
            tbody_tr.appendChild( td );
        }
        tbody.appendChild( tbody_tr );
    }
    tblWidget = dojo.widget.fromScript("SortableTable", {}, tbl);
    // manually set the attributes from <table ... to the widget
    for (i=0, il=attrs.length; i<il; i++) {
        if (attrs[i].nodeValue == "true" || attrs[i].nodeValue == "false" || (parseInt(attrs[i].nodeValue) == attrs[i].nodeValue)) {
            eval("tblWidget." + attrs[i].nodeName + " = " + attrs[i].nodeValue + ";");
        } else {
            eval("tblWidget." + attrs[i].nodeName + " = '" + attrs[i].nodeValue + "';");
        }
    }
    tblContainerNode.appendChild( tblWidget.domNode );
}

The sortroot that is passed in is basically just an XML Object that has passed through the first pass parser, something like the <sortableTable> node listed below. This was to make the server coding easier (only difference between html and xml being the <![cdata[ enclosers.

<?xml version...>
  <sortableTable>
    <table maximumNumberOfSelections="0" rowAlternateClass="alternateRow" tbodyC
lass="scrollContent" rowClass="" rowSelectedClass="selected" columnSelected="sor
ted-column" sortDirection="0" border="0" headerClass="" sortIndex="0" widgetId="
testTable" minRows="0" enableMultipleSelect="false" headClass="fixedHeader" width="100%" defaultDateFormat="%D" cellspacing="0" dojoType="SortableTable" headerSortUpClass="selected" enableAlternateRows="true" headerSortDownClass="selected" valueField="mpnt_idx" cellpadding="0">
        <thead>
            <tr><th dataType="string" field="mpnt_idx">Meter Point Id</th><th da
taType="string" field="mpnt_last_changed">Last Changed</th><th dataType="string"
 field="mpnt_owner">Owner</th><th dataType="string" field="mpnt_contact_name" so
rt="asc">Contact Name</th><th dataType="string" field="mpnt_contact_phone">Conta
ct Phone</th><th dataType="string" field="mpnt_contact_email">Contact Email</th>

            </tr>
        </thead>
        <tbody>
            <tr value="990000009">
                <td><![CDATA[990000009]]></td>
                <td><![CDATA[2006-05-30 11:43:59.85]]></td>
                <td><![CDATA[2]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
            </tr>
            <tr value="990000011">
                <td><![CDATA[990000011]]></td>
                <td><![CDATA[2006-05-30 11:44:05.90]]></td>
                <td><![CDATA[3]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
            </tr>
            <tr value="990000012">
                <td><![CDATA[990000012]]></td>
                <td><![CDATA[2006-05-30 13:50:15.05]]></td>
                <td><![CDATA[3]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
                <td><![CDATA[None]]></td>
            </tr>
        </tbody>
    </table>
  </sortableTable>

I did find that the attributes within the <table tag were not properly processed in the

tblWidget = dojo.widget.fromScript("SortableTable?", {}, tbl);

call, so had to add the *nasty* eval statements. Maybe it is that that jinxes the valueField process.

As I'm sure you can see, I am using 'mpnt_idx' as the valueField and not 'Id' which is the default. When the rows are tested, one still retains rowId? while the other doesn't - hence the workaround fix.

Hopefully that gives you enough indication of where the snags were lying in my approach. If you need any more explanations, just ask.

subnote: I didn't take the request for examples as abuse ;o)

comment:6 Changed 13 years ago by Tom Trenka

I think I see...one thing I haven't done is test that the sortable table instantiates correctly when using widget.fromScript, so that might be a big part of it...

What you're doing is an interesting approach. I'll need to play with some things a bit but I have a sneaking suspicion that if I can solve the fromScript issue first (if it is an issue), the other bugs you're seeing will probably go away. I think I'll also need to double check that the code is grabbing the values of the value attribute of the row correctly.

Thanks for the examples, that helps a lot :)

comment:7 Changed 13 years ago by anonymous

I think you may be on the right track with the fromScript concept.

I have been playing with extending the sortable table object with a couple of functions, of the order:

dojo.widget.html.SortableTable?.prototype.selectAll = function( evt ) {

some functionality using the *this* object pointer etc this.setSelectionByRow( rows[i] );

I tried the usual

dojo.event.connect(btn1, "onclick", tblWidget, selectAll);

which then told me selectAll is not defined. I then just tried

dojo.event.connect(btn1, "onclick", tblWidget.selectAll); note the . dot

Which calls the function, though requires this.tblWidget.setSelectionByRow( ... to reference another internal function

It does therefore seem quite possible that the object instantiation from widget.fromScript may not be properly building the entire object and referencing it to the variable name given.

Hope that makes sense ;o)

comment:8 Changed 13 years ago by Tom Trenka

Actually, I think in your case you should have just done:

dojo.event.connect(btn1, "onclick", tblWidget, "selectAll");

comment:9 Changed 13 years ago by Tom Trenka

Resolution: fixed
Status: newclosed

Mark,

I don't know if you've been paying attention or not but I've created a bigger, beefier version of this widget called FilteringTable? which *should* allow creation via script. Preselecting rows using selected=true definitely works (except for Opera 9 due to an interesting bug), so I'm going to close this bug.

If you find that you're still running into edge-case scenarios, please file another bug report (with an example I can use to reproduce :) and assign it to me.

comment:10 Changed 12 years ago by (none)

Milestone: 0.4

Milestone 0.4 deleted

Note: See TracTickets for help on using tickets.