Skip to content

Making Gearz components #1

@masbicudo

Description

@masbicudo

I have created a working sample of how Gearz components could be made, so that they are generic enough to make everyone happy: good for gearz and for everyone else using reactjs out there.

gearz.mixin.js

This is the mixin that defines all reusable pieces of the Gearz components.
Comments in the code explain what these methods do.

var gearz = {
        getInitialState: function() {
            return {};
        },

        // 'get' is used to get properties that may be stored in 'state' or in 'props'
        // this happens when a value is defined throw a 'setter'

        get: function(propName) {
            return this.state.hasOwnProperty(propName)
                ? this.state[propName]
                : this.props[propName];
        },

        // 'setter' is used to create a function that changes the value of an
        // attribute used by this component, raising events to notify parent
        // components (if any), and with a default behaviour of storing changes
        // in the component internal 'state'

        setter: function(propName, newValue) {
            return function(e) {
                var prevDef = false;
                var e1 = {
                    preventDefault: function() {
                        prevDef = true;
                    },
                    key: propName,
                    value: newValue,
                    previous: this.props[propName],
                    setValue: function(v){newValue=v;},
                    domEvent: e
                };
                Object.freeze(e1);

                var fn0 = this.props.onAnyChange;
                fn0 && fn0(e1);
                if (prevDef)
                    return;

                var name = propName == "value"
                    ? ""
                    : propName[0].toUpperCase()+propName.substr(1);
                var fn1 = this.props["on"+name+"Change"];
                fn1 && fn1(e1);
                if (prevDef)
                    return;

                this.state[propName] = newValue;
                this.props.render();
            }.bind(this);
        },
    };

pager.jsx

This is the pager component. It is self-sufficient, but allows the developer to everride it's default behaviour as defined in the mixin: using setter and get methods.

var Pager = React.createClass({
        mixins: [gearz],
        render: function() {
                var page = this.get("page");
                var pageCount = this.props.count / this.props.pageSize,
                    children = [];

                for (var it = 0; it < pageCount; it++) {
                    var setter = this.setter("page", it+1);
                    children.push(
                        <div
                            className={[page-1==it?"current":"", "item"].join(' ')}
                            onMouseDown={setter}
                            key={"pg-"+it+1}>{it}</div>);
                }

                return (
                    <div className="pager">{children}</div>
                    );
            }
    });

pager.html

Test page, to test the pager component, and the ways of using it.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Pager Component Experiment</title>
    <link href="pager.css" type="text/css" rel="stylesheet" />
    <!-- React.js -->
    <script src="../packages/react-0.12.1/build/react.js"></script>
    <script src="../packages/react-0.12.1/build/JSXTransformer.js"></script>
    <script src="gearz.mixin.js"></script>
    <script src="pager.jsx" type="text/jsx"></script>
    <style>
        .pager {
            display: inline-block;
        }

        .pager > .current.item {
            color: blue;
            font-weight: bold;
        }

        .pager > .item {
            display: inline-block;
            padding: 8px;
            color: black;
            cursor: pointer;
        }

        .pager > .item:hover {
            background-color: #fdb;
        }
    </style>
</head>
<body>
    <h1>pager.jsx</h1>
    <h3>using external props (generic event)</h3>
    <div id="output1"></div>
    <h3>using external props (specific event)</h3>
    <div id="output2"></div>
    <h3>using internal state (no events at all)</h3>
    <div id="output3"></div>
    <script type="text/jsx">
        var glb = {
            pager1: {
                page: 1,
                pageSize: 10,
                count: 45
            },
            pager2: {
                page: 1,
                pageSize: 10,
                count: 88
            }
        };
        function onPagerChange(data, render) {
            return function(e) {
                e.preventDefault();
                data[e.key] = e.value;
                render();
            }.bind(this);
        }
        function render1() {
            React.render(
                <Pager
                    page={glb.pager1.page}
                    count={glb.pager1.count}
                    pageSize={glb.pager1.pageSize}
                    onAnyChange={onPagerChange(glb.pager1, render1)} />,
                document.getElementById("output1")
            );
        }
        function render2() {
            React.render(
                <Pager
                    page={glb.pager2.page}
                    count={glb.pager2.count}
                    pageSize={glb.pager2.pageSize}
                    onPageChange={onPagerChange(glb.pager2, render2)} />,
                document.getElementById("output2")
            );
        }
        function render3() {
            React.render(
                <Pager
                    page={1}
                    count={101}
                    pageSize={10}
                    render={render3} />,
                document.getElementById("output3")
            );
        }
        render1();
        render2();
        render3();
    </script>
</body>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions