简体   繁体   English

Gravity Forms&ReactJS - 将表格加载到模态并提交

[英]Gravity Forms & ReactJS - Loading Form into Modal and submitting

I am currently stuck on a problem with Gravity Forms and ReactJS. 我目前陷入Gravity Forms和ReactJS的问题。 I am trying to load a Gravity Form as a Modal in a ReactJS component for contact purposes. 我正在尝试在ReactJS组件中加载重力形式作为模态以用于联系目的。 Basically, how I am currently set up is by doing a GET from the WP-API for the page with the form loaded in, and then using dangerouslySetInnerHTML to build the page in the component. 基本上,我当前设置的方法是从WP-API为加载了表单的页面执行GET ,然后使用dangerouslySetInnerHTML在组件中构建页面。 The problem is though that when I try to submit the form, its giving me a problem with the POST . 问题是,当我尝试提交表单时,它给我一个POST问题。 Its trying to submit it to the URL from the GET . 它试图将其提交到GETURL I can use some serious help here on what would be the best approach. 我可以在这里使用一些认真的帮助来解决最好的方法。

import React, { PropTypes } from 'react';
import Modal from 'react-modal';
import $ from 'jquery';

class RequestContactModal extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      content: ''
    };
  }

  componentWillMount() {
    const wpApiUrl = '../wp-json/wp/v2/pages/61';

    $.ajax({
      url: wpApiUrl,
      type: 'GET'
    })
      .done((response) => {
        console.log(response);
        this.setState({
          content: response.content.rendered
        });
      })
      .fail((response) => {
        console.log('fail');
        console.log(response);
      });
  }

  handleSubmit = (ev) => {
    ev.preventDefault();
    this.props.closeModal();
  }

  handleCloseClick = (ev) => {
    ev.preventDefault();
    this.props.closeModal();
  }

  render() {
    const customStyles = {
      overlay: {
        backgroundColor: 'rgba(0, 0, 0, 0.65)'
      },
      content: {
        top: '50%',
        left: '50%',
        right: 'auto',
        bottom: 'auto',
        marginRight: '-50%',
        transform: 'translate(-50%, -50%)',
        background: '#fff'
      }
    };

    return (
      <Modal
        isOpen={this.props.isOpen}
        onRequestClose={this.props.closeModal}
        style={customStyles}
      >
        <div>
          <p>Gravity Forms</p>
          <div dangerouslySetInnerHTML={{__html: this.state.content}} />
        </div>
      </Modal>
    );
  }
}

RequestContactModal.propTypes = {
  closeModal: PropTypes.func.isRequired,
  isOpen: PropTypes.bool
};

RequestContactModal.defaultProps = {
  isOpen: false
};

export default RequestContactModal;

This question may be old, but building React applications on WordPress "facelessly" using the WP REST API is gaining momentum in a huge way (it's even the future for WordPress core), so this is bound to come up more and more. 这个问题可能已经过时了,但是使用WP REST API“无声地”在WordPress上构建React应用程序正在以巨大的方式获得动力(甚至是WordPress核心的未来),所以这必然会越来越多。

So what is happening is that Gravity Forms sets it's form action by via $action = remove_query_arg( 'gf_token' ); 所以发生的事情是Gravity Forms通过$action = remove_query_arg( 'gf_token' );设置它的表单动作$action = remove_query_arg( 'gf_token' ); which in turn calls add_query_arg() which then calls $uri = $_SERVER['REQUEST_URI']; 然后调用add_query_arg()然后调用$uri = $_SERVER['REQUEST_URI']; - this means that when you use React to display WordPress content containing a Gravity Form, the form's action is set to the REST endpoint called, not the content's permalink. - 这意味着当您使用React显示包含Gravity Form的WordPress内容时,表单的操作将设置为调用的REST端点,而不是内容的永久链接。 Whoops! 哎呦!

Although Gravity Forms has a bona-fide WP REST API add-on in works, there are two solid options I've been able to suss out so far: 虽然Gravity Forms在作品中有一个真正的WP REST API附加组件,但到目前为止我有两个可靠的选项:

Option 1 - Fully Headless 选项1 - 完全无头

Ensure you have a REST route that accepts POST (I suggest just reusing a GET route) and add do_action('wp'); 确保你有一个接受POST的REST路由(我建议只重用一个GET路由)并添加do_action('wp'); to your route callback. 到您的路线回调。 You could add it earlier if you like, like the rest_api_init hook. 如果你愿意,可以先添加它,比如rest_api_init钩子。 This will ensure that Gravity Forms gets triggered when REST requests are sent to it. 这将确保在向其发送REST请求时触发重力表单。

Alternatively, you can call GFForms::maybe_process_form() from your route callback or use it as a callback in the rest_api_init hook. 或者,您可以从路由回调中调用GFForms::maybe_process_form() ,或将其用作rest_api_init挂钩中的回调。 The trick is to ensure that the method gets called when the API receives the request. 诀窍是确保在API收到请求时调用该方法。

Next, have React handle your form submission (you don't want the browser actually posting it directly and showing your visitors JSON). 接下来,让React处理您的表单提交(您不希望浏览器实际直接发布它并显示您的访问者JSON)。 The REST API will automagically return a response with a properly handled Gravity Form markup... validation/error messages, confirmations, etc. Note that Gravity Forms needs to be ajax=false for this approach. REST API将自动返回具有正确处理的重力形式标记的响应...验证/错误消息,确认等。请注意,此方法的重力形式需要为ajax = false。

Option 2 - Faceless (Semi-Headless) 选项2 - 无面(半无头)

Assuming you want to preserve WordPress's permalinks, you will likely have your REST API endpoints configured to match the WordPress permalink URIs; 假设您想要保留WordPress的永久链接,您可能会将REST API端点配置为与WordPress永久链接URI匹配; So, for instance /wp-json/your-post-name-here/ is equivalent to /your-post-name-here/ . 所以,例如/wp-json/your-post-name-here/相当于/your-post-name-here/ If not, you can always ensure you are sending the URI along with your requests. 如果没有,您始终可以确保将URI与请求一起发送。 If this is how you are handling it, you can add something the following to the rest_api_init hook: 如果您正在处理它,可以在rest_api_init钩子中添加以下内容:

function tweak_request_uri() {
    $prefix = '/' . rest_get_url_prefix();
    $_SERVER['REQUEST_URI'] = str_replace( $prefix, '', $_SERVER['REQUEST_URI'] );
}

This ensures that the REQUEST_URI matches the current page, so that the Gravity Form is able to successfully post it's data to WordPress. 这可确保REQUEST_URI与当前页面匹配,以便Gravity Form能够将其数据成功发布到WordPress。 However, while this allows Gravity Forms postbacks to actual reach the server, you aren't going to get anything meaningful back if you are using only the REST API... because the response is tied to the request to the server, but React is making a new, separate request to the API for content. 但是,虽然这允许Gravity Forms回发实际到达服务器,但如果使用REST API,则不会得到任何有意义的内容...因为响应与对服务器的请求相关联,但React是为API提供新的单独的内容请求。 Ergo, you get a fresh form. 你会得到一个新的形式。 Not good UX, that. 那不好用户体验。

To fix this, you need to take whatever function, class, object, etc that you use to package your data prior to rest_ensure_response( $data ) and call it from within a wp_head() hook. 要解决这个问题,你需要在rest_ensure_response($ data)之前使用你用来打包数据的任何函数,类,对象等,并在wp_head()钩子中调用它。 You want to json_encode() the data and output it within a script tag as a Javascript variable. 您想要json_encode()数据并将其作为Javascript变量输出到脚本标记中。 For instance, something like this: 例如,像这样:

var $react_first_load_data = json_encode( [ 'id' => get_the_id(), 'title' => get_the_title(), 'content' => get_the_content() ] );
printf('<script type="text/javascript">window.reactFirstLoadData=%s</script>', $react_first_load_data);

Then, in your React app, you check for the presence of this variable first, and use the data if present. 然后,在您的React应用程序中,首先检查是否存在此变量,并使用数据(如果存在)。 If not, fall back to making the REST request as usual. 如果没有,请回到正常情况下发出REST请求。

I know this answer has been very architectural, but there's a lot of ways to tackle this and it depends heavily on how you've already structured your React implementation with WordPress. 我知道这个答案非常具有架构性,但是有很多方法可以解决这个问题,这在很大程度上取决于你如何用WordPress构建你的React实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM