admin管理员组文章数量:1321253
I have a custom plugin that uses shortcodes to generate tables which are meant to be manipulated by the user. As they change the number of servings in A2, it will divide the values in B2-E2 by the value in A2.
The shortcode and table functions correctly the first time it appears on the page. If I try to use the shortcode again, it will generate the table but nothing happens when the value in cell A2 is changed, it doesn't divide the values like it's supposed to.
Any ideas?
Here is my .js code:
'use strict';
var updateNutritionValues = function updateNutritionValues(multipler, macros) {
var carbs = document.querySelector('.nutrition-table__content--carbs');
var protein = document.querySelector('.nutrition-table__content--protein');
var fat = document.querySelector('.nutrition-table__content--fat');
var calories = document.querySelector('.nutrition-table__content--calories');
carbs.textContent = (macros.carbs / parseInt(multipler)).toFixed(1) + 'g';
protein.textContent = (macros.protein / parseInt(multipler)).toFixed(1) + 'g';
fat.textContent = (macros.fat / parseInt(multipler)).toFixed(1) + 'g';
calories.textContent = (macros.calories / parseInt(multipler)).toFixed(0) + ' cals';
console.log('carbs => ', (macros.carbs / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.protein / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.fat / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.calories / parseInt(multipler)) + ' cals');
};
var nutritionTable = function nutritionTable() {
var number = document.querySelector('.nutrition-table__number');
var originalValues = {
carbs: parseInt(document.querySelector('.nutrition-table__content--carbs').textContent),
protein: parseInt(document.querySelector('.nutrition-table__content--protein').textContent),
fat: parseInt(document.querySelector('.nutrition-table__content--fat').textContent),
calories: parseInt(document.querySelector('.nutrition-table__content--calories').textContent)
};
number.addEventListener('change', function (e) {
updateNutritionValues(parseInt(e.target.value), originalValues);
});
};
document.addEventListener('DOMContentLoaded', function () {
return nutritionTable();
});
Here is my .php code
function ls_nutritional_table_resources() {
global $post;
if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'nutrition_table') ) {
wp_register_style( 'ls-nutritional-table-css', plugin_dir_url( __FILE__ ) . 'nutritional-table.css' );
wp_enqueue_style( 'ls-nutritional-table-css' );
wp_enqueue_script('ls-nutritional-table-js', plugin_dir_url( __FILE__ ) . 'nutritional-table.js' );
}
}
add_action( 'wp_enqueue_scripts', 'ls_nutritional_table_resources');
add_shortcode('nutrition_table', 'ls_nutritional_table');
function ls_shortcodes() {
function ls_nutritional_table($atts) {
$attributes = shortcode_atts(array(
'servings' => '1',
'carbs' => '100',
'protein' => '400',
'fats' => '90',
'calories'=> '2810'
), $atts);
$output = '<div class="nutrition-table">
<div class="nutrition-table__column">
<div class="nutrition-table__head">Servings</div>
<div class="nutrition-table__content">
<input type="number" value="' . esc_attr($attributes['servings']) . '" min="1" autocomplete="off" class="nutrition-table__number">
</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Carbs</div>
<div class="nutrition-table__content nutrition-table__content--carbs">' . esc_attr($attributes['carbs']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Protein</div>
<div class="nutrition-table__content nutrition-table__content--protein">' . esc_attr($attributes['protein']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Fat</div>
<div class="nutrition-table__content nutrition-table__content--fat">' . esc_attr($attributes['fats']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Calories</div>
<div class="nutrition-table__content nutrition-table__content--calories">' . esc_attr($attributes['calories']) . ' cals</div>
</div>
</div>';
return $output;
}
}
add_action('init', 'ls_shortcodes');
/** Always end your PHP files with this closing tag */
?>
I have a custom plugin that uses shortcodes to generate tables which are meant to be manipulated by the user. As they change the number of servings in A2, it will divide the values in B2-E2 by the value in A2.
The shortcode and table functions correctly the first time it appears on the page. If I try to use the shortcode again, it will generate the table but nothing happens when the value in cell A2 is changed, it doesn't divide the values like it's supposed to.
Any ideas?
Here is my .js code:
'use strict';
var updateNutritionValues = function updateNutritionValues(multipler, macros) {
var carbs = document.querySelector('.nutrition-table__content--carbs');
var protein = document.querySelector('.nutrition-table__content--protein');
var fat = document.querySelector('.nutrition-table__content--fat');
var calories = document.querySelector('.nutrition-table__content--calories');
carbs.textContent = (macros.carbs / parseInt(multipler)).toFixed(1) + 'g';
protein.textContent = (macros.protein / parseInt(multipler)).toFixed(1) + 'g';
fat.textContent = (macros.fat / parseInt(multipler)).toFixed(1) + 'g';
calories.textContent = (macros.calories / parseInt(multipler)).toFixed(0) + ' cals';
console.log('carbs => ', (macros.carbs / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.protein / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.fat / parseInt(multipler)).toFixed(1) + 'g');
console.log('carbs => ', (macros.calories / parseInt(multipler)) + ' cals');
};
var nutritionTable = function nutritionTable() {
var number = document.querySelector('.nutrition-table__number');
var originalValues = {
carbs: parseInt(document.querySelector('.nutrition-table__content--carbs').textContent),
protein: parseInt(document.querySelector('.nutrition-table__content--protein').textContent),
fat: parseInt(document.querySelector('.nutrition-table__content--fat').textContent),
calories: parseInt(document.querySelector('.nutrition-table__content--calories').textContent)
};
number.addEventListener('change', function (e) {
updateNutritionValues(parseInt(e.target.value), originalValues);
});
};
document.addEventListener('DOMContentLoaded', function () {
return nutritionTable();
});
Here is my .php code
function ls_nutritional_table_resources() {
global $post;
if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'nutrition_table') ) {
wp_register_style( 'ls-nutritional-table-css', plugin_dir_url( __FILE__ ) . 'nutritional-table.css' );
wp_enqueue_style( 'ls-nutritional-table-css' );
wp_enqueue_script('ls-nutritional-table-js', plugin_dir_url( __FILE__ ) . 'nutritional-table.js' );
}
}
add_action( 'wp_enqueue_scripts', 'ls_nutritional_table_resources');
add_shortcode('nutrition_table', 'ls_nutritional_table');
function ls_shortcodes() {
function ls_nutritional_table($atts) {
$attributes = shortcode_atts(array(
'servings' => '1',
'carbs' => '100',
'protein' => '400',
'fats' => '90',
'calories'=> '2810'
), $atts);
$output = '<div class="nutrition-table">
<div class="nutrition-table__column">
<div class="nutrition-table__head">Servings</div>
<div class="nutrition-table__content">
<input type="number" value="' . esc_attr($attributes['servings']) . '" min="1" autocomplete="off" class="nutrition-table__number">
</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Carbs</div>
<div class="nutrition-table__content nutrition-table__content--carbs">' . esc_attr($attributes['carbs']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Protein</div>
<div class="nutrition-table__content nutrition-table__content--protein">' . esc_attr($attributes['protein']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Fat</div>
<div class="nutrition-table__content nutrition-table__content--fat">' . esc_attr($attributes['fats']) . 'g</div>
</div>
<div class="nutrition-table__column">
<div class="nutrition-table__head">Calories</div>
<div class="nutrition-table__content nutrition-table__content--calories">' . esc_attr($attributes['calories']) . ' cals</div>
</div>
</div>';
return $output;
}
}
add_action('init', 'ls_shortcodes');
/** Always end your PHP files with this closing tag */
?>
Share
Improve this question
asked Sep 28, 2020 at 6:27
jmc1885jmc1885
31 bronze badge
1 Answer
Reset to default 0The reason your code only applies to the first table, is because you are only selecting the first input with var number = document.querySelector('.nutrition-table__number');
You need to loop over all your tables, and add an event listener to each.
Here is an example of how this could work. The plugin pattern is from https://vanillajstoolkit/boilerplates/revealing-module-pattern/
/*!
* Revealing Constructor Pattern Boilerplate
* (c) 2019 Chris Ferdinandi, MIT License, https://gomakethings
*/
var NutritionTablesPlugin = (function () {
'use strict';
/**
* Create the Constructor object
*/
var Constructor = function (selector) {
//
// Variables
//
var publicAPIs = {};
var nodes = document.querySelectorAll(selector);
//
// Methods
//
var allNodes = function (callback) {
for (var i = 0; i < nodes.length; i++) {
callback(nodes[i], i);
}
};
/**
* A private method
*/
var updateNutritionValues = function (table, multipler, macros) {
var carbs = table.querySelector( '.nutrition-table__content--carbs');
var protein = table.querySelector('.nutrition-table__content--protein');
var fat = table.querySelector('.nutrition-table__content--fat');
var calories = table.querySelector('.nutrition-table__content--calories');
carbs.textContent = (macros.carbs / parseInt(multipler)).toFixed(1) + 'g';
protein.textContent = (macros.protein / parseInt(multipler)).toFixed(1) + 'g';
fat.textContent = (macros.fat / parseInt(multipler)).toFixed(1) + 'g';
calories.textContent = (macros.calories / parseInt(multipler)).toFixed(0) + ' cals';
};
/**
* Another public method
*/
publicAPIs.init = function (options) {
allNodes( function(node){
var originalValues = {
carbs: parseInt(node.querySelector('.nutrition-table__content--carbs').textContent),
protein: parseInt(node.querySelector('.nutrition-table__content--protein').textContent),
fat: parseInt(node.querySelector('.nutrition-table__content--fat').textContent),
calories: parseInt(node.querySelector( '.nutrition-table__content--calories').textContent)
};
node.addEventListener('change', function (e) {
updateNutritionValues(node, parseInt(e.target.value), originalValues);
});
});
};
//
// Return the Public APIs
//
return publicAPIs;
};
//
// Return the Constructor
//
return Constructor;
})();
document.addEventListener("DOMContentLoaded", function(event) {
var nutrition = new NutritionTablesPlugin('.nutrition-table');
nutrition.init();
});
And in your PHP code, you'll want to use esc_html
for the carbs/fat/protein/calories attributes output. https://developer.wordpress/reference/functions/esc_html/
本文标签: phpWhy does my custom plugin only function correctly once per page
版权声明:本文标题:php - Why does my custom plugin only function correctly once per page? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742096720a2420596.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论