zoid icon indicating copy to clipboard operation
zoid copied to clipboard

How to pass props to remote pop up?

Open NFhbar opened this issue 5 years ago • 3 comments

I have the following situation:

  1. I want to provide a zoid component that renders a simple button
  2. on click, this button should render another zoid component (react) that performs some complex functionality
  3. props should pass from the site that hosts the button component through to the final zoid component (react)

Much like this example: https://github.com/krakenjs/zoid/tree/master/demo/advanced/remote-popup

So, the user would use the component like this:

index.htm


<head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-design/4.0.2/bootstrap-material-design.css" />
    <link rel="stylesheet" href="./index.css" />

    <script src="../../dist/component.frame.js"></script>
</head>

<body>

    <h3>Checkout Demo</h3>

    <!-- Container for our zoid component to render into -->

    <div id="container"></div>

    <!-- Container to display the result of the login call -->

    <div id="loginContainer"></div>

    <script>

        // Render the component and pass down props to the iframe

        component.button({

            env: 'demo',

            prefilledEmail: '[email protected]',

            loginContainer: '#loginContainer',

            // When the iframe window calls `window.xprops.onLogin(email)` this callback will be called

            onLogin: function(email) {

                // Display the email address that was used to log in

                console.log('LOGIN')
            }

        }).render('#container');

    </script>

</body>

component.js

/* @flow */
/** @jsx node */

import { create } from 'zoid/src';
import * as zoid from "zoid/dist/zoid.frameworks.js";

import { node, dom } from 'jsx-pragmatic/src';

export let login = create({
    tag: "chargecheckout",
    url: "http://localhost:3000",
    defaultContext: 'popup',
    props: {
        prefilledEmail: {
            type: 'string'
        }
    },
  });

export let button = zoid.create({

    tag: 'login-component',

    dimensions: {
        width:  '300px',
        height: '150px'
    },

    url: ({ props }) => {
        return {
            demo: "./login.htm",
            production: 'https://my-site.com/login',
            test:       'mock://www.my-site.com/base/test/windows/login/index.htm',
        }[props.env];
    },

    props: {
        env: {
            type:    'string',
            default: () => 'production'
        },

        prefilledEmail: {
            type: 'string'
        },

        onLogin: {
            type: 'function'
        }
    },

    defaultContext: __DEFAULT_CONTEXT__,

login.htm


<head>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-material-design/4.0.2/bootstrap-material-design.css" />
    <link rel="stylesheet" href="./login.css" />

    <!-- Pull in zoid and the login component we defined -->

    <script src="../../dist/component.frame.js"></script>
</head>

<body>

    <!-- Set up a login form -->
    <button id="openLoginButton" id="btn" type="button" class="btn btn-outline-primary btn-lg">Checkout</button>
    <div id="result"></div>

    <script>
        document.querySelector('#openLoginButton').addEventListener('click', function() {
            document.querySelector('#openLoaginButton').style.display = 'none';
            component.button({
                prefilledEmail: window.xprops.prefilledEmail, // <--- Not sure about this
            }).renderTo(window.parent, window.xprops.loginContainer, 'popup');
            
        });
    </script>

</body>

And the login component is a simple create-react-app

import React from "react";
import ReactDOM from "react-dom";
import logo from "./logo.svg";

import "./App.css";

class App extends React.Component {
  render() {
    console.log("props", window.xprops); // <--- This is undefined
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>I am the Demo Component</p>
        </header>
      </div>
    );
  }
}
export default App;

I can get the react app to render properly in the popup windown on button click, but the prop prefilledEmail is undefined when I try to get it in the final zoid component.

Any ideas?

NFhbar avatar Dec 06 '19 23:12 NFhbar

I found a solution, you need to include the component in your react app. So the login component includes the script in the public folder index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="theme-color" content="#000000" />
        <meta
            name="description"
            content="Web site created using create-react-app"
        />
        <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
        <title>React App</title>
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
        <script src="%PUBLIC_URL%/js/component.frame.js"></script> //<--HERE
    </body>
</html>

Then the props propagate correctly from user to final zoid component.

However, when I tried to include the component via npm install and:

import React from "react";
import ReactDOM from "react-dom";
import logo from "./logo.svg";

//  I publish the component to a local npm registry so I can do this
import component from "component"; // <--- HERE,

import "./App.css";

class App extends React.Component {
  render() {
    console.log("props", window.xprops); 
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>I am the Demo Component</p>
        </header>
      </div>
    );
  }
}
export default App;

I get the following error:

Screen Shot 2019-12-07 at 2 53 50 PM

Not sure about this one.

NFhbar avatar Dec 07 '19 22:12 NFhbar

Fighting with this issue as well.

coderguy avatar Dec 11 '19 02:12 coderguy

Any news about this issue? I'm fighting against this problem as well

jbpadilha avatar Aug 09 '21 23:08 jbpadilha