What is the proper way to pass options to a jquery file? - php

On each page of my theme, a user has the option of adding a slider. When they do this, they can choose several settings for the slider. This includes things such as how long the slides will pause before changing, how long it takes for the slide to transition when it changes, and what type of transition it uses.
Now if I were to just hard code this and not let the user choose the options for the slider, the code would look like this:
<script>
jQuery(function(){
jQuery('#camera_wrap_3').camera({
height: '40%',
thumbnails: true,
time: 3500,
fx: 'scrollBottom',
transPeriod: 1200,
autoAdvance: true,
minHeight: '50px',
mobileNavHover: false,
});
});
</script>
What is the proper way to pass the variables that are created when the user chooses their settings to the code above?
Keep in mind that I want to be able to enqueue this file the proper way with wp_enqueue

I'm assuming this is related to your question about passing variables to wp_head - if you want to store parameters from a plugin, Wordpress provides two (three if you are using multisite) methods depending on the scope of your parameters.
If it is specific to a page/post, then you should store the parameters in the postmeta table with the Custom Fields API. You would use update_post_meta($post_id, $key, $data) and fetch it with get_post_meta($post_id, $key, $single) where $single is true/false depending on if you want an array of values or just a single value - if it is something like "width" you would probably set this to true. More info here - http://codex.wordpress.org/Custom_Fields.
If it is applicable to the entire site, then you would store it in the Options API in the options table using update_option($key, $data) and retrieve it with get_option($key, $default) where $default is returned if the $key can't be found, otherwise it will return false. The last option applicable only to multisite is also part of the Options API and uses update_site_option($key, $data) and get_site_option($key, $default). More info here - http://codex.wordpress.org/Options_API.
An excellent option for managing custom fields (and options through a premium feature) is Advanced Custom Fields.
Assuming this is per post/page, and you are setting the values with ACF, you can then write a hook to wp_head to pull these fields into your Javascript. You can either put this into the functions.php file in your theme, or if you want it to stick around if you change themes, you can use a Custom Functions Plugin.
// hooked to wp_head
function my_wp_head(){
// get the current $post
global $post;
// get value or key "camera_time"
$camera_time = get_post_meta($post->ID, "camera_time", true);
// write result to javascript
echo "<script>";
echo "var cameraTime = {$camera_time};";
// ... the rest of your javascript
echo "</script>";
}
if (is_single()) // only include on single pages
add_action( 'wp_head', 'my_wp_head' );

you can use extend method for that.
function foo (params) {
//default values
var settings = $.extend({
'someKey': { k1: 'v1' },
'otherKey': 'oTherValue'
}, params);
//use it
if (settings.someKey.k1 == 'v1') ...
var bar = settings.otherKey;
}
then just call it from your code
foo({someKey: {k1: 'v2'}, otherKey: 'bla' });
i created a simple jQuery plugin usnig this approach. check it out

Related

edit php code in WordPress

I am a beginner in wordpress then in my code below, I have an Array of video ids and I use integrated vimeo videos on a page.
The video starts playing as soon as the page is open and when the first video has finished, the second one starts.
Now, I want to add a text field in my wordpress to give permission to user to edit the ids if he want to change the videos.
Any ideas ?
<div id="headervideo" class="videoClass"></div>
<script src="https://player.vimeo.com/api/player.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var videos = [ '240466644', '146661000']; //Array videos ids
var options = {
id: videos[0],//first element
width: 700,
height: 500,
loop: false
};
player = new Vimeo.Player('headervideo', options);
player.play()
playMovie(videos, 0, true)
})
var playMovie = function(videos, currentVideoIdx, first) {
if (!first) {
player.loadVideo(videos[currentVideoIdx % videos.length]).then(function(id) {
player.play()
}).catch(function(error) {});
player.on('ended', function() {
playMovie(videos, ++currentVideoIdx, false)
});
}
</script>
Have you considered writing this functionality as a custom shortcode? Then, you can allow your administrative user to change the video ID's by modifying the shortcode attributes.
For example, let's say you put your functionality in a shortcode, and that shortcode was accessed with the value: two_videos
You could modify your functionality to allow for user input/modification of your shortcode, so your end shortcode would look like:
[two_videos video1='240466644' video2='146661000']
That way, your admin user could just change the values of parameters video1 and video2, and you can achieve your desired result.
You can't allow the user to edit ID and due to security reasons, in simple no one does it. But you can call a string function get user input and then push the string value to the function(i.e., the id array) by calling it. But, not sure until you give more details. What you are trying to achieve.

How to filter from external input and startswith?

I'm trying to filter a table content with tablesorter applying two filters at the same time, but the table is not being filtered with filter_startswith when the "filtertext" is being taken from an external input.
The startswith filter works fine when the "filtertext" is from columnFilters, but with the external input the filter works but ignores the startswith filter.
From the source example I added the external input to filter, the rest is almost the same.
Is this an expected behavior or can it be called a bug/error/problem with the widget?
How can I make what I want? (filter the table from an external input but with the startswith filter)
Source example: http://mottie.github.io/tablesorter/docs/example-widget-filter.html
I set up this example with the filter_startsWith option set to true and it appears to work when I try to filter the first name column for "a"; the only results I see are "Aaron" and "Alex", not "Philip Aaron" or "Martha".
$(function() {
$('table').tablesorter({
theme: 'blue',
widgets: ['filter'],
widgetOptions : {
filter_external : '.search',
filter_startsWith: true,
filter_reset: '.reset'
}
});
});
If this isn't working for you, then please modify the demo to show the problem so I can help troubleshoot it.

Display something on admin post page if specific category is selected

I'm trying to get Wordpress' Admin Post Page to display some form of output when a specific category (say, 'Featured') is selected.
Something like this (original page):
When I select the 'Featured' category (selected 'Featured' category), I want something to display, like this:
Meaning the page checks if the specific category is checked, and if it is, Wordpress generates an option menu for the user to fill in.
How do I go about doing this? I'm looking at the Wordpress Codex but so far, no dice.
You'll have to print some jQuery only in that screen, and then it's matter of listening for live changes and making the show/hide actions.
The following is from this WPSE Answer. You have to adjust the elements IDs. Also, jQuery's live method is deprecated, change that as well.
add_action('admin_head', 'wpse_53486_script_enqueuer');
function wpse_53486_script_enqueuer() {
global $current_screen;
if ( 'post' == $current_screen->id )
{
echo <<<HTML
<script type="text/javascript">
jQuery(document).ready( function($) {
if ( $('#in-category-6').is(':checked') ) {
$("form#adv-settings label[for='myplugin_sectionid-hide']").show();
$('#myplugin_sectionid').show();
} else {
$('#myplugin_sectionid').hide();
$("form#adv-settings label[for='myplugin_sectionid-hide']").hide();
}
$('#in-category-6').live('change', function(){
if ( $(this).is(':checked') ) {
$('#myplugin_sectionid').show();
$("form#adv-settings label[for='myplugin_sectionid-hide']").show();
} else {
$('#myplugin_sectionid').hide();
$("form#adv-settings label[for='myplugin_sectionid-hide']").hide();
}
});
});
</script>
HTML;
}
}
Another method to print scripts in targeted admin pages.
If you want that you feature will works after the post is saved (so that it already marked id DB to witch category this post belong to), you should use in_category() function to detect whether this post is in the category that you want, and if so - to show your extra box.
But, as I understand you want that it will work also before the post is saved, so you should use jQuery - detect whether the checkbox with value x (where x is your category id) is checked, and then display your extra box by changing css display property from none to block.
Check out Advanced Custom Fields.
It is a wordpress plugin that allows you to add additional fields to posts, and it can do this by category. I have used it before to set background images on posts for use in a slider.

Implementing money.js on multiple fields on same page

I'm struggling with conceptually how to implement this (what events to bind to etc).
I'm using CakePHP and have a view with the following:
An array of products to display and an associated price ($products['Product']['price'])
Each product has a base currency set ($product['Currency]['currency'])
I have money.js, accounting.js and another JS that sets JSON data for fx.rates and fx.base
I know the currency that the user wants to see and will likely differ from the product base currency (SessionComponent::read('User.Preferences.Currency')
A div to display the currency shortname (USD) and converted value, each div with unique id
My simple test works fine - using inline-php I've put a bit of JS on the page between two script tags.
<script>
var value = accounting.unformat(<? echo $product['Product']['price'] ?>); // clean up number (eg. user input)
var target = "<? echo SessionComponent::read('User.Preference.currency'); ?>"; // or some user input
var convertedValue = fx(value).from("<? echo $product['Currency']['currency'] >").to(target);
accounting.formatMoney(convertedValue, {
symbol: target,
format: "%v %s"
}); // eg. "53,180.08 GBP"
alert(convertedValue);
</script>
Fine. Works great. But what I can't work out is how to implement this on a page with N number of products.
I'm assuming I create a JS function, something like:
fx_convert(divid, price, fromcurrency, tocurrency)
And in my Cake view, I use inline php to echo the function parameters.
What is the clean way to use jQuery for this function, and have the price 'divs' call fx_convert and update their content with the converted value?
Or is my thinking totally backwards on this? All help is greatly appreciated.
After some decent sleep, figured it out. :)
Using inline PHP, I pass the to/from currencies via the div attributes and set a uniform class name. e.g.
<div class="fx" fx-from="<?php echo $product['Currency']['currency']; ?>" fx-to="<?php echo SessionComponent::read('User.Preference.currency') ?>" fx-value="<?php echo $product['Product']['price']; ?>"></div>
And then use the following jQuery snippet to loop over all elements of class "fx" and do the required calculation (using the excellent money.js and accounting.js)
$(document).ready(function() {
$(".fx").each( function( index, element ){
var value = accounting.unformat($(this).attr("fx-value")); // clean up number (eg. user input)
var target = $(this).attr("fx-to"); // or some user input
var convertedValue = fx(value).from($(this).attr("fx-from")).to(target);
$(this).html(accounting.formatMoney(convertedValue, {
symbol: target,
format: "%v %s"
}));
});
});
Still need to refactor and tidy up, but the solution is there.

How can I limit WordPress category selection to just one?

I have a custom post type and a custom taxonomy setup - pretty standard stuff.
However, I would like to know how I can restrict my client from selecting more than one taxonomy category per post?
I don't mind them being able to create and delete taxonomy types, but I don't want them selecting more than one. Because these are checkboxes, they CAN. Perhaps radio buttons might work?
I have seen solutions use jQuery to change these fields, but they seem a bit hacky. What's the best practice way to do this?
Attached, is a screenshot of my custom taxonomy box.
I realize this isn't a full blown answer but something as simple as listing the categories (or taxonomy terms) with a dropdown would do the trick. I don't know of one personally but there's got to be plugin that does this. No offense but this certainly strikes me as a problem that's been solved before.
As far as I know, we have to use jQuery. It's "hacky" but works easily and a pure PHP/WP solution is really complex if my memory serves me well.
This is the necessary code:
jQuery("#categorychecklist input").each(function(){
this.type = 'radio';
});
We have to run the code on the pages /wp-admin/post.php and /wp-admin/post-new.php. It should run on load and then run again if a new category is created. To solve the new category issue I used a MutationObserver:
foreach( array( 'post', 'post-new' ) as $hook )
add_action( "admin_footer-$hook.php", 'convert_cats_to_radio' );
function convert_cats_to_radio(){
global $post;
if( $post->post_type !== 'post') // select your desired Post Type
return;
?>
<script type="text/javascript">
function makeRadioButtons(){
jQuery("#categorychecklist input").each(function(){
this.type = 'radio';
});
}
function newCategoryObserver(){
// Example from developer.mozilla.org/en-US/docs/Web/API/MutationObserver
var targetNode = document.getElementById('categorychecklist');
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList) {
for(var mutation of mutationsList) {
if (mutation.type == 'childList') {
makeRadioButtons();
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
}
newCategoryObserver();
makeRadioButtons();
</script>
<?php
}
Relevant: this old plugin still works perfectly to solve the issue of sub-categories hierarchy. By default in WP, when one sub-category is selected it doesn't show under its parent category but on top of the list. It's also a jQuery solution and written by a lead WP core developer at the time.
Here is a solution in case you need the checkboxes to act like radio buttons, but still be able to uncheck them all:
(function() {
// Allow only one selection
const checkboxes = document.querySelectorAll('[name="tax_input[event-series][]"][type="checkbox"]');
checkboxes.forEach((item) => {
item.addEventListener('click', function() {
checkboxes.forEach((el) => {
if (item !== el) {
el.checked = false;
}
});
});
});
})();
It's looping through each checkbox and it's adding a click event listener. If you click on a checkbox, it's going to remove the check state on each of the elements, but itself.
However, it's still keeping the ability to uncheck an option if it's already selected.
I've added the scripts only in the administration. To do so, you can use the admin_enqueue_scripts.
Hope this one helps somebody! :)

Categories