While developing a plugin, I've tried setting up a locally scoped state within my class so that I can call an observer method to call an enqueue_script function from within my shortcode. I'd like to be able to do this because I'm loading in Vue, and I don't want it to conflict with other areas of my site. After playing around for a while and reading docs online -- I can't find out where I'm going wrong.
My set_user_form function is currently loading in the framework, but I'd like to call $this->observer() from get_user_form. However, it's not loading the script from within the shortcode function.
Any idea where I can refactor this code to get the script to load properly?
<?php
namespace Usergen;
class UserInput {
public $_state = array (
'load_vue' => false
);
public function __construct()
{
/**
* Dependencies to sideload images into media gallery
*/
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
// front end javascript dependency registered as callable script
add_action( 'init', function() {
wp_register_script( 'vue-js', 'https://cdn.jsdelivr.net/npm/vue', array(), CRV_USER_GEN_VERSION, false );
});
// register user form as shortcode
add_action( 'init', array( $this, 'set_user_form' ) );
// register thank you page shortcode
add_action( 'init', array( $this, 'set_user_submission' ) );
}
public function observer()
{
if ( $this->_state['load_vue'] ) {
wp_enqueue_script( 'vue-js' );
}
}
public function set_user_form()
{
// load front end dependencies
if ( !function_exists( 'user_generated_content' ) ) {
add_shortcode( 'user_generated_content', array( $this, 'get_user_form' ) );
$this->_state['load_vue'] = true;
$this->observer();
}
}
public function get_user_form()
{
?><div id="usergen" class="form">
<div v-if="submitted">
<p>Your submission was successful!</p>
</div>
<form v-else @submit="checkForm" action="" method="POST" enctype="multipart/form-data">
<div v-if="errors.length">
<strong>Please fix the following errors</strong>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
<input v-model="name" id="first_name" type="text" name="crv_name" value="" placeholder="your name here" />
<input v-model="email" id="email" type="email" name="crv_email" value="" placeholder="your email" />
<label for="crv_story">Please include your social media account name so we can follow and tag you!</label>
<textarea id="crv_story" name="crv_story" rows="2" placeholder="your story here"></textarea>
<input id="files" type="file" accept="image/png, image/jpeg" name="crv_featured_media[]" multiple="mulitple" />
<br />
<input id="instagram" type="checkbox" name="crv_social_media_allowed_1" value="instagram" />
<label for="instagram">Instagram</label>
<input id="facebook" type="checkbox" name="crv_social_media_allowed_2" value="facebook" />
<label for="facebook">Facebook</label>
<input id="twitter" type="checkbox" name="crv_social_media_allowed_3" value="twitter" />
<label for="twitter">Twitter</label>
<input id="consent" type="checkbox" name="crv_social_media_allowed_3" value="consent" />
<label for="consent">I give consent to use these photos on their social media accounts.</label>
<input type="hidden" name="action" value="crv_user_generated" />
<?php wp_nonce_field( 'crv_user_generated' ) ?>
<input type="submit" value="submit" />
</form>
</div>
<script>
var usergen = new Vue({
el: "#usergen",
data: {
errors: [],
name: null,
email: null,
submitted: false
},
methods: {
checkForm: function(e) {
if(this.name && this.email) {
this.submitted = true;
return true
};
this.errors = [];
if(!this.name) this.errors.push("Name required");
if(!this.email) this.errors.push("Email required");
e.preventDefault();
}
}
})
</script>
<?php
}
}