aslagle / reactive-table

A reactive table designed for Meteor
https://atmospherejs.com/aslagle/reactive-table
Other
328 stars 138 forks source link

Reactjs compatibility #339

Open imranur8 opened 8 years ago

imranur8 commented 8 years ago

Is there any plan to make another reactjs version ?

aslagle commented 8 years ago

I haven't gotten around to trying react with meteor yet, but it seems like there must already be good table components for react, and maybe they wouldn't be as hard to integrate with meteor as it was with blaze. I'm curious what you think if you've been trying any.

csillag commented 8 years ago

@aslagle, here is how I used it with meteor + React.js:

Preparation:

/*
  The react components are configured by HTML attributes, which must be strings.
  We are passing on this attributes when initializing the blaze templates.

  However, sometimes we need in other data types. (Numbers, booleans, arrays, or other JSON data.)
  Therefore, before passing on the data to the blaze templates, we need to convert them to the
  correct data types. This files defines functions to do that.
 */

let _parseBlazeArg = function (value) {
    try {
        /*
          Here, we try to interpret the string as JSON.
          (Besides actual JSON data, this also works for array, booleans and numbers.)

          Before the attempt to interpret the string as JSON, as preparation, we:
           - Replace single quotes with double qoutes.
           - Try to quote unquoted JSON. (ie. key: "value" ==> "key": "value"
         */
        return JSON.parse(value.replace(/'/g, "\"").replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2": '));
    } catch (err) {
        return value;
    }
};

_parseBlazeArgs = function (args) {
    var result = {}
    for (let key of Object.keys(args)) {
        result[key] = _parseBlazeArg(args[key]);
    }
    return result;
};

ReactiveTable = React.createClass({
    componentDidMount() {
        let data = _parseBlazeArgs(this.props);
        data.collection = window[this.props.collection];
        if (data.fields) {
            for (let key of Object.keys(data.fields)) {
                if (data.fields[key].tmpl) {
                    data.fields[key].tmpl = Template[data.fields[key].tmpl];
                }
            }
        }
        this.view = Blaze.renderWithData(Template.reactiveTable, data,
            ReactDOM.findDOMNode(this.refs.container));
    },
    componentWillUnmount() {
        Blaze.remove(this.view);
    },
    render() {
        return <span ref="container"/>;
    }
});

Data mode (not related to React.js or reactive table):

Users = new Mongo.Collection("users");

And finally:

<ReactiveTable
    collection="Users"
    fields="[
      { key: 'firstName', label: 'First name' },
      { key: 'lastName', label: 'Last name' },
      { key: 'email', label: 'E-Mail' }
    ]"
/>

With this, the table works OK. React the data changes, and everything.

I can use custom cells when specifying the fields this:

 { key: '_id', label: 'Actions', tmpl: 'userActionsCell' }

and the template for it is:

<template name="userActionsCell">
    <button type="button" class="btn btn-xs delete btn-danger fa-remove"></button>
</template>
if (Meteor.isClient) {
    Template.userActionsCell.events({
        'click .delete': function () {
            if (window.confirm("Should we really delete this user?")) {
                Users.remove(this._id);
            }
        }
    });
};
aslagle commented 8 years ago

Thanks @csillag !