reactive-table icon indicating copy to clipboard operation
reactive-table copied to clipboard

Reactjs compatibility

Open imranur8 opened this issue 9 years ago • 3 comments

Is there any plan to make another reactjs version ?

imranur8 avatar Jan 16 '16 08:01 imranur8

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.

aslagle avatar Jan 17 '16 16:01 aslagle

@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);
            }
        }
    });
};

csillag avatar Feb 22 '16 11:02 csillag

Thanks @csillag !

aslagle avatar Feb 22 '16 13:02 aslagle