Do not load div until after full page load - javascript

I have a smart tag inside a hidden field in my WP Forms (written with php - see below) that collects user data, however this significantly slows down the webpage. The div ID is: wpforms-10395-field_107. The url is: https://ellasbubbles.com/contact-us/
My question is, how can I prevent this div from loading until after the page has fully loaded. This way it can load in the background while the user is populating their contact form details
Note: A better solution might be to keep this div empty, and simply populate it with the shortcode on page load?
PHP (currently in functions.php) - Grabs users location details and stores them in a smart tag:
add_shortcode('geo', 'shortcode');
function wpf_dev_register_smarttag( $tags ) {
// Key is the tag, item is the tag name.
$tags['geo'] = 'geo';
return $tags;
}
add_filter( 'wpforms_smart_tags', 'wpf_dev_register_smarttag' );
function wpf_dev_process_smarttag( $content, $tag ) {
$city = do_shortcode('[userip_location type=city]');
$country = do_shortcode('[userip_location type=country]');
$region = do_shortcode('[userip_location type=region]');
$flow = do_shortcode('[track-user-flow]');
// Only run if it is our desired tag.
if ( 'geo' === $tag ) {
$userinfo = '<b>City:</b> ' . $city . "\n" . '<b>Region:</b> ' . $region . "\n" . '<b>Country:</b> ' . $country . "\n" . "\n" . '<b>User Flow:</b> ' . $flow;
// Replace the tag with our link.
$content = str_replace( '{geo}', $userinfo, $content );
}
return $content;
}
add_filter( 'wpforms_smart_tag_process', 'wpf_dev_process_smarttag', 10, 2 );
It looks like I can use:
$(window).load(function(){
$.get("<path to php file>", function(data){
Replace Placeholder code here? (maybe)
});
})

Related

Wordpress search issue

Hi i have a website on which i have a search bar on home page when i search something on it, it will show a number result Chapter/Post related to that keyword but when i open any Chapter/Post there are number of "drop-downs" in the Chapter page & i can't see the word highlighted for which i have searched for. Can anybody help with that to highlight text or it's background
For Example i'm searching for word "Morning" on this page https://policies.americanprep.org/
I will make the background or word color "red" on this page https://policies.americanprep.org/chapter-f-classroom-organization/?highlight=Morning?s=Morning
You need to change default wp_content/wp_excerpt in result page with something like this:
if (isset($_GET['highlight'])){
$content = get_the_content();
$keys = implode('|', explode(' ', $_GET['highlight']));
$content = preg_replace('/(' . $keys .')/iu', '<strong class="search-highlight">\0</strong>', $content);
echo '<p>' . $content . '</p>';
} else {
echo '<p>' . get_the_content() . '</p>';
}
Also you need to add css code for span.search-highlight
$_GET parameter 's' would be better to remove from url.

How to dynamically pass an array of values to a <select> field in Contact Form 7?

According to the official Contact Form 7 docs, it is possible to pass a a default value to CF7 from the shortcode, in this way:
// field in CF7 in Wordpress admin area
[email* destination-email default:shortcode_attr]
// shortcode in a Wordpress php template
[contact-form-7 id="123" title="Contact Form" destination-email="xxxxxx#example.com"]
// function in functions.php
add_filter( 'shortcode_atts_wpcf7', 'custom_shortcode_atts_wpcf7_filter', 10, 3 );
function custom_shortcode_atts_wpcf7_filter( $out, $pairs, $atts ) {
$my_attr = 'destination-email';
if ( isset( $atts[$my_attr] ) ) {
$out[$my_attr] = $atts[$my_attr];
}
return $out;
}
This works for a simple text field, but I need to pass an array of values to a <select> field and use them as <option>s inside it; I've tried to modify a bit this code, but apparently it isn't working, or at least I've not been able to.
Is it possible to use the shortcode to send dynamic data to CF7 even if not a single plain text like this?
If not, I'm open to every other kind of solution, even if it involves another method, or some additional plugin; is there some other way to dynamically send an array of values to <select> fields in Contact Form 7?
These values are data queried from the database (such as post names, custom fields, and so on), so they need to come from php first even if there is a solution that involves javascript.
Here's an example of a form tag I've used for getting US States. This is a <select> generated from an array. This is probably more along the lines of what you want to do.
You can see that I also use the usermeta billing_state to pre-select the choice.
With that said, you should also be able to use this same method to create a select tag that performs any WP_Query and puts the results into an option tag.
<?php
add_action('wpcf7_init', function (){
wpcf7_add_form_tag( array('dd_states', 'dd_states*'), 'cf7_state_dropdown' , true );
});
function cf7_state_dropdown($tag) {
$tag = new WPCF7_FormTag( $tag );
$atts = array();
$validation_error = wpcf7_get_validation_error( $tag->type );
$class = wpcf7_form_controls_class( $tag->type );
if ( $validation_error ) {
$class .= ' wpcf7-not-valid';
}
$atts['class'] = $tag->get_class_option( $class );
$atts['aria-required'] = 'true';
$atts['aria-invalid'] = $validation_error ? 'true' : 'false';
$atts = wpcf7_format_atts( $atts );
// Get User ID and Billing State from DB
$userid = get_current_user_id();
$user_state = get_user_meta($userid, 'billing_state', true);
$states = array ( 'FL'=>'Florida','AL'=>'Alabama','AK'=>'Alaska','AZ'=>'Arizona','AR'=>'Arkansas','CA'=>'California','CO'=>'Colorado','CT'=>'Connecticut','DE'=>'Delaware','DC'=>'District of Columbia','GA'=>'Georgia','HI'=>'Hawaii','ID'=>'Idaho','IL'=>'Illinois','IN'=>'Indiana','IA'=>'Iowa','KS'=>'Kansas','KY'=>'Kentucky','LA'=>'Louisiana','ME'=>'Maine','MD'=>'Maryland','MA'=>'Massachusetts','MI'=>'Michigan','MN'=>'Minnesota','MS'=>'Mississippi','MO'=>'Missouri','MT'=>'Montana','NE'=>'Nebraska','NV'=>'Nevada','NH'=>'New Hampshire','NJ'=>'New Jersey','NM'=>'New Mexico','NY'=>'New York','NC'=>'North Carolina','ND'=>'North Dakota','OH'=>'Ohio','OK'=>'Oklahoma','OR'=>'Oregon','PA'=>'Pennsylvania','RI'=>'Rhode Island','SC'=>'South Carolina','SD'=>'South Dakota','TN'=>'Tennessee','TX'=>'Texas','UT'=>'Utah','VT'=>'Vermont','VA'=>'Virginia','WA'=>'Washington','WV'=>'West Virginia','WI'=>'Wisconsin','WY'=>'Wyoming');
$output = '<span class="wpcf7-form-control-wrap '.sanitize_html_class( $tag->name ).'"><select name="state" id="state" '.$atts.'>';
$output .= "<option value=\"\"> - - Choose State - - </option>";
foreach ($states as $abbrev=>$state){
$selected = ($user_state == $abbrev) ? ' selected="selected"' : '';
$output .= '<option value="'.$abbrev.'"'. $selected .'>'.$state.'</option>';
}
$output .= "</select></span>";
$output .= $validation_error;
return $output;
}

Rendering a Wordpress shortcode with Javascript from a JSON object?

I'm currently working on a Wordpress site. I'm building a custom plugin that allows for lazy loading of custom post types.
Some of these post types contain shortcodes, that I need to display. I have a primary Javascript file that makes Ajax requests to my PHP code in my plugin, which returns a JSON object containing the shortcode like this:
Object {shortcode: "[embedyt]https://www.youtube.com/watch?&height=300[/embedyt]"}
I'm then trying to display this shortcode on the front-end, since I'm dynamically building HTML blocks based on the JSON response.
However, when I try to output the shortcode to the page via the Javascript, it just displays as text, like this:
Here's my PHP code and Javascript:
$packet = array();
$formatted_url = "[embedyt]" . $youtube_root . $video_id . "&height=300" . "[/embedyt]";
$packet["shortcode"] = do_shortcode($formatted_url);
echo json_encode($packet); // This sends a response back to the Ajax request
And:
$.ajax({
type: 'POST',
url: tlas_lazy_load.ajax_url,
data: {
action: 'tlas_lazy_load',
post_type: post_type,
posts_per_page: 6,
paged: page
},
success: function(packet) {
response = JSON.parse(packet);
for(var i = 0; i < response.length; i++) {
build_lazy_load("#lazy-load-row", packet[i], i);
}
}
});
function build_lazy_load(element, packet, index) {
var block = "";
block += "<div class=\"col-md-4\">";
block += " <div class=\"video-individual\">";
block += " <div class=\"panel panel-default\">";
block += " <div class=\"panel-body\" id=" + index + ">";
block += packet.shortcode;
block += " <\/div>";
block += " <\/div>";
block += " <\/div>";
block += "<\/div>";
$(element).append(block);
};
What gives me hope that this can be done is the answer to this question:
Wordpress: Outputting shortcode with Javascript?
And I'm following along with what that person suggested. However can this be done?
Update:
So I can display the shortcode if I do this in enqueue scripts method:
add_action( 'wp_enqueue_scripts', 'tlas_lazy_load_enqueue_scripts' );
function tlas_lazy_load_enqueue_scripts() {
wp_enqueue_script( 'tlas-lazy-load', plugins_url( 'js/tlas_lazy_load.js', __FILE__ ), array('jquery'), '1.0', true );
wp_localize_script( 'tlas-lazy-load', 'tlas_lazy_load', array(
'ajax_url' => admin_url( 'admin-ajax.php' )
// BELOW
'videos_shortcode' => do_shortcode("[embedyt]" . $youtube_root . $video_id . "&height=300" . "[/embedyt]")
));
}
By setting it as a localized variable which my Javascript can access. The problem is that I have to add the shortcode after this function has already been declared. I tried localizing it later within the file in my above function by doing:
...
$packet = array();
$formatted_url = "[embedyt]" . $youtube_root . $video_id . "&height=300" . "[/embedyt]";
wp_localize_script( 'tlas-lazy-load', 'tlas_lazy_load', array(
'videos_shortcode' => do_shortcode($formatted_url)
));
...
But this didn't work, it simply returned nothing. I'm on the right track (I think?) but I'm not sure how you can dynamically localize a script/Javascript variable.

Title Tag Nested inside itself with jQuery PHP Load

I have a dynamic site that loads only the body when a usr clicks a page. I am trying t change the title tag, but am getting no luck.
HTML:
<head>
// Title tag is contained in the php file
<?php include (BASEPATH . "includes/widgets/pageTitle.php"); ?>
</head>
JavaScript/jQuery:
$(document).on('click', 'a', function(e) {
// Page url of destination
var pageurl = $(this).attr('href');
var baseurl = "http://localhost/offstreams/";
// prevent page from loading
e.preventDefault();
// Empty info inside the body class and reload new info
// THIS WORKS PERFECTLY
$('.body').empty().load(pageurl + " > .body > *");
//!!!!!!!!!!!!!!!!!!!!!
// THIS IS THE PROBLEM
//!!!!!!!!!!!!!!!!!!!!!
$('title').empty().load(pageurl + "> title > *");
// Push the URL state
if(pageurl!=window.location){
window.history.pushState({path:pageurl},'',pageurl);
}
//stop refreshing to the page given in
return false;
}
});
A Snippet of PHP code:
//Band page title tag
if (isset($_GET['member']) && isset($_GET['edit']) && isset($_GET['band'])){
$band_id = $_GET['band'];
$sql = "SELECT `band_name` FROM `bands` WHERE `band_id` = '$band_id'";
$query = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($query)){
$band_name = $row['band_name'];
echo "<title>" . $band_name . " | " . "Offstreams</title>";
}
An example output on actual load would be Count to Four | Offstreams, which is what I want.
When I do the ajax load, the website works, but the title tag gives the default url like localhost/offstreams/etc... and the title tag turns into
<title>
<title>Count to Four | Offstreams</title>
</title>
Does anyone know why?
It looks like you're doubling up on title tags there, the $('title').empty() bit will be leaving the previous ones there.
Try putting the title tags in your initial html:
<head>
// Title tag is contained in the php file
<title><?php include (BASEPATH . "includes/widgets/pageTitle.php"); ?></title>
</head>
And removing them from your php:
echo $band_name . " | " . "Offstreams";
I don't understand the reason for outputting the title in a loop since there is only one per page, unless I am missing something in your code. Seems like it needs to be outside.
if (isset($_GET['member']) && isset($_GET['edit']) && isset($_GET['band'])){
$band_id = $_GET['band'];
$sql = "SELECT `band_name` FROM `bands` WHERE `band_id` = '$band_id'";
$query = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($query)){
$band_name = $row['band_name'];
}
echo "<title>" . $band_name . " | " . "Offstreams</title>";
}
In regards to your JQuery script, keep this in mind from the .load() documentation:
jQuery uses the browser's .innerHTML property to parse the retrieved
document and insert it into the current document. During this process,
browsers often filter elements from the document such as <html>,
<title>, or <head> elements. As a result, the elements retrieved by
.load() may not be exactly the same as if the document were retrieved
directly by the browser.
In other words, what you're doing may not work properly all the time with all browsers. With that in mind, give this a try.
$(document).on('click', 'a', function(e) {
// Page url of destination
var pageurl = $(this).attr('href');
// prevent page from loading
e.preventDefault();
// Empty info inside the body class and reload new info
// THIS WORKS PERFECTLY
$('.body').empty().load(pageurl + " > .body > *");
// Give this a try
$(pageurl).load(pageurl, function() {
$('title').load('title', function() {
document.title = $(this).text();
});
});
// Push the URL state
if(pageurl !== window.location){
window.history.pushState({path:pageurl},'',pageurl);
}
//stop refreshing to the page given in
return false;
});

Best method for firing and refiring AJAX via php

I'm trying to transcribe what my programmer told me. He and I may be doing this all wrong, so I need to make sure he and I am doing it in the right manner. Here is what we are trying to do:
I have a page on a website and within that page, I have a button. When you click on it, I want it to (via AJAX so the page doesn't refresh)
Send data (time capture) to the DB
See that the DB recorded the change and in turn return a different value back to the site
This would in turn change the button, noting that it is in a recording mode.
Think of it in this way, the button is a timer. On click, it records the time in the DB, and in the DB it also changes the state to recording. Since it is in the recording phase, somehow it gets sent back to the website page and changes the button showing that it is recording. Naturally clicking again would stop it and record the time in the DB.
Here is how the snippets are set up (not working I think) ATM:
*sidenote: This is in Joomla
Page:
<script src="js/ajax_link.js" type="text/javascript"></script>
<div id="ajaxlink" onclick="loadurl('php/ticket_timer.php',<?php echo $row->id?>)">Start Time</div>
ajax_link.js
function loadurl(dest,ticket_id) {
jQuery.ajax({
url: dest,
type: "POST",
data: "ticket_id="+ticket_id,
success: function(msg){
alert(msg);
jQuery('#ajaxlink').text("Timer Stop");
}
});
}
ticket_timer.php
<?php
define( '_JEXEC', 1 );
define( 'DS', DIRECTORY_SEPARATOR );
define( 'JPATH_BASE', $_SERVER[ 'DOCUMENT_ROOT' ] );
require_once( JPATH_BASE . DS . 'includes' . DS . 'defines.php' );
require_once( JPATH_BASE . DS . 'includes' . DS . 'framework.php' );
require_once( JPATH_BASE . DS . 'libraries' . DS . 'joomla' . DS . 'factory.php' );
$mainframe =& JFactory::getApplication('site');
$ticket_id = $_POST['ticket_id'];
$user =& JFactory::getUser();
$user_id=$user->get('id');
//DB Query
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('id', 'ticket_id', 'user_id', 'times','current_time')));
$query->from($db->quoteName('#__support_ticket_times'));
$query->where($db->quoteName('ticket_id') . ' LIKE '. $db->quote($ticket_id));
$query->where('ticket_id = '. $ticket_id, 'AND')
->where('user_id=' . $user_id );
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();
$current_time=$results[0]->current_time;
$times=$results[0]->times;
$id_results = $db->loadColumn();
$db->setQuery($idquery);
$timesString = $times . ',' . date('Y-m-d g:i');
echo($timesString);
if(empty($results[0])){
$values = array(max($id_results)+1, $ticket_id, $user_id, $db->quote(date('Y-m-d g:i')),$db->quote(date('Y-m-d g:i')));
//echo "YOU GET NOTHING, MAKING NEW ROW";
$columns = array('id', 'ticket_id', 'user_id', 'times','current_time');
// Prepare the insert query.
$insert_query = $db->getQuery(true);
$insert_query
->insert($db->quoteName('#__support_ticket_times'))
->columns($db->quoteName($columns))
->values(implode(',', $values));
// Set the query using our newly populated query object and execute it.
$db->setQuery($insert_query);
$db->query();
}else{
//echo("CURRENT TIME" . $current_time);
if($current_time=='0000-00-00 00:00:00'){
echo "NO TIME";
$fields = array(
$db->quoteName('current_time'). '=' . $db->quote(date('Y-m-d g:i'))
);
}
// . $db->quote(date('Y-m-d g:i'))
else{
echo "ADD TIME";
$fields = array($db->quoteName('times') . '=' . $db->quote($timesString) ,
$db->quoteName('current_time'). "='0000-00-00 00:00:00'"
);
}
$update_query = $db->getQuery(true);
$conditions = array(
$db->quoteName('user_id') . '=' . $db->quote($user_id),
$db->quoteName('ticket_id') . '=' . $db->quote($ticket_id)
);
$update_query->update($db->quoteName('#__support_ticket_times'))->set($fields)->where($conditions);
$db->setQuery($update_query);
$db->query();
//echo $update_query;
}
?>
Can anyone suggest how to get the timer to fire back that the timer has started? Are we butchering this and is there a better way to code this?
You need to exchange some data between the PHP and the HTML page. The HTML page can be modified with Javascript, of course. The notation typically used for this kind of an exchange is JSON. In this example, we're using JSON to:
Send a boolean timerRunning to the PHP,
change the value in PHP,
send a reply,
modify the HTML page, and
store the timerRunning value in the HTML element.
So, for starters, we pass some data from the HTML element to Javascript using the HTML5 data- attributes, like this:
<div id="ajaxlink" data-url="php/ticket_timer.php" data-ticketId="<?php echo $row->id; ?> " data-timerRunning="false">Start Time</div>
In your Javascript, we access the parameters set above and send them to your PHP script via AJAX:
jQuery(document).ready(function($){
// Add an 'onClick' handler to the element
jQuery('#ajaxlink').on('click', function(event) {
// Get the url and ticket_id from the element's 'data-' attributes
var url = jQuery(this).data( 'url' );
var data = {
'ticketId' : jQuery(this).data( 'ticketId' ),
'timerRunning' : jQuery(this).data( 'timerRunning' )
}
// Send an AJAX request
jQuery.ajax({
type: 'POST',
url: url,
data: data
}).done( function(response) {
// This runs when the AJAX request succeeds
if ( 'undefined' == typeof( response.timerRunning ) ) {
alert( 'The server didn\'t tell the timer state' );
return;
}
// Store the value in the element
jQuery('#ajaxlink').data( 'timerRunning', response.timerRunning );
// Change the element HTML
if ( response.timerRunning )
jQuery('#ajaxlink').html( 'Stop Timer' );
else
jQuery('#ajaxlink').html( 'Start Timer' );
}).fail( function(jqXHR, textStatus, errorThrown ) {
// This runs when the AJAX request fails
alert( 'The AJAX request failed with the error ' + errorThrown );
});
});
});
In your PHP script, check the timerRunning value and react accordingly:
if ( isset( $_POST['timerRunning'] ) ) { // Check that we got some value for 'timerRunning'
if ( $_POST['timerRunning'] ) {
// The 'timerRunning' value is TRUE, the timer is running, now stop it
your_code_here_to_stop_the_timer();
$reply = array( 'timerRunning' => false );
} else {
// The 'timerRunning' value is FALSE, the timer isn't running, now start it
your_code_here_to_start_the_timer_and_whatever();
$reply = array( 'timerRunning' => true );
}
// Send the correct header for a JSON response
header('Content-type: application/json');
// Send the $reply array encoded as JSON
echo json_encode( $reply );
}

Categories