Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any way to save element attributes that are assigned via element.someAttribute = "some value"? #95

Closed
dkwin opened this issue Feb 13, 2017 · 9 comments

Comments

@dkwin
Copy link

dkwin commented Feb 13, 2017

Hi

I'm currently evaluating the plugin for a fairly large table.

Currently, I'm initializing the table as such (via existing html):

window.clusterize = new Clusterize({
        scrollId: 'scrollDiv',
        contentElem: document.getElementById ("myTableTbody"),
        rows_in_block: VISIBLE_ROWS_IN_TABLE,
        blocks_in_cluster:BLOCKS_PER_CLUSTER
        }
)

My table is initialized by html and some initial JS as well (some of which I cannot change). The JS also sets some attributes which are used to render the table.

IE

document.getElementById ("someElement").someAttribute = "some important value needed to render";

I'm wondering how to best persist the JS attributes when the elements are destroyed.

thanks for any info

@Thrilleratplay
Copy link

@dkwin You mean like the data-* attribute?

@dkwin
Copy link
Author

dkwin commented Feb 14, 2017

@Thrilleratplay Thanks for the reply, I was wondering if clusterizejs would actually store the variables as opposed to me having to store it in data-attributes (I'd have to refactor a ton of existing JS). I'd like to avoid refactoring existing JS if possible but rather just make a wrapper to mimic dom elements.

@NeXTs
Copy link
Owner

NeXTs commented Feb 14, 2017

Hello @dkwin
I've re-read your question few times but I did not get idea what you need, could you please rephrase it somehow

@dkwin
Copy link
Author

dkwin commented Feb 14, 2017

Hi @NeXTs

The issue I'm having is that some of the attributes assigned to DOM elements in my table are lost. There is legacy JS code that initializes the HTML table via Javascript, which sets attributes of DOM elements using the "=" operator (ie, someElement.someAttribute = "some Value").

These attributes are used for some dynamic functionality like onClicks, onHovers, etc.

I want to avoid refactoring existing JS if possible so I'm wondering if there is a way for ClusterizeJS to preserve the attributes of the elements.

The table is loaded in the following manner (alot of legacy code):

var tableElement = document.getElementById ("myTableTbody");

//some JS functions go through the HTML and set attributes that are needed for certain dynamic widgets
 //Going through cells of the table

   var tableCells = document.querySelectorAll("#myTableTbody td");
    //going through each table cell and doing something special/unique from legacy JS code
   tableCells.forEach ( function (element) { 
                                              //assign special values and do business logic to element
                                              element.someAttr1 = getSpecialAttribute1 (element);
                                              element.someAttr2 = getSpecialAttribute2 (element);
                                             ....
   
                                       }
    );


window.clusterize = new Clusterize({
        scrollId: 'scrollDiv',
        contentElem:  tableElement,
       rows_in_block: VISIBLE_ROWS_IN_TABLE,
       blocks_in_cluster:BLOCKS_PER_CLUSTER
        }

 //In order to get widgets on the cell to work, I need to be able to get element.someAttr1, element.someAttr2
 //However, these attributes seem to be destroyed
tableCells = document.querySelectorAll("#myTableTbody td");
tableCells.forEach ( function (element) { 
                                //element.someAttr1 and element.someAttr2 are now empty
                                //despite assign attributes to them earlier
                                             ....
   
                                       }
    );

)

Sorry for the confusion and I greatly appreciate any help

@NeXTs
Copy link
Owner

NeXTs commented Feb 14, 2017

That happens because after applying clusterize most of your rows were removed from DOM, that's why you can not access them by querySelectorAll

since you did not provide "rows" parameter to new Clusterize({...}) that means you fetch existing markup. and that's the problem because it was not designed to work that way.
after fetching your rows, clusterize saves it to private variable called rows, and it was made private intentionally.
Markup (rows) generated on server considered to be static, rows generated on client are dynamic and that's why there are .update() method to work with.

To be able make changes to rows in your case you have to change clusterize sources a bit..
change this line from
var rows = isArray(data.rows)
to
this.rows = isArray(data.rows)

after that (in theory) you will have access to parsed rows by clusterize instance (hence they will be in string format) by doing

var clusterize = new Clusterize({...})
console.log(clusterize.rows);

iterate clusterize.rows, change necessary clusterize.rows items, whatever..
then do cluserize.update(clusterize.items) to apply your changes

I understand, it may be not convenient for you to work with strings, but that's the only way I can see in this case.

@dkwin
Copy link
Author

dkwin commented Feb 14, 2017

@NeXTs Thanks so much for your help.

@dkwin
Copy link
Author

dkwin commented Feb 14, 2017

@NeXTs

Is it possible to detach the rows from the tbody element and use that to pass in?

For example

    //tbody is the tbody element of the table
    var rows = tbody.children;
    rows = [].slice.call(rows);

   //detaching rows from the document
   if (rows && rows.length > 0){
      rows.forEach ( function (element) {
                        tbody.removeChild(element);
                     }
                   );
   }

     window.clusterize = new Clusterize({
    scrollId: 'scrollDiv',
    contentElem:  tbody,
    rows: rows,
   rows_in_block: VISIBLE_ROWS_IN_TABLE,
   blocks_in_cluster:BLOCKS_PER_CLUSTER
    }

I tried doing that but it seems that I can get an error when Clusterize is trying to get the tag name of the first child of contentElem.

Does the row data absolutely have to be an array of Strings?

@NeXTs
Copy link
Owner

NeXTs commented Feb 14, 2017

Yes it must be array of strings. You may be interested in this PR that allows to work with actual DON nodes instead of strings.

But you are almost done with code you provided. The only thing left - to map your rows of DOM nodes to strings. You can easily do it by yourself. Hint how to do that

@dkwin
Copy link
Author

dkwin commented Feb 14, 2017

@NeXTs

Thanks, I actually used outerHTML before but I was hoping to somehow keep the attributes without doing too much gerry rigging.

I think I'll go the route of the PR you just posted.

Thanks again!

@dkwin dkwin closed this as completed Feb 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants