Wordpress Settings API: Dynamic Array Value - javascript

I'm building my first Wordpress plugin and i'm having a little bit of trouble achieving the functionality I would like.
Essentially what I'm trying to do is save a dynamic array to options.php
I'll try and explain the functionality in a bit more depth. Basically, the user will select a post_type from a dropdown of all the available post_types including custom post types. Using jQuery, I'm detecting state changes on that dropdown to then post to a function in the plugin which will output all the available field_types associated with the selected post_type as labels and checkboxes.
https://www.dropbox.com/s/zacpvq85c5u9lrq/Screen%20Shot%202015-12-21%20at%2012.01.12.png?dl=0
https://www.dropbox.com/s/txyigfe81k0wd1i/Screen%20Shot%202015-12-21%20at%2012.01.23.png?dl=0
I can determine which checkboxes have been checked and create a javascript array of them, how do I then get this array, to wordpress and then have it saved as a preconfigured setting_field?
What I've got so far.
I output all the current post_types as part of a select input.
<select name="comparison_pt" id="comparison_pt" value="<?php echo get_option('comparison_pt'); ?>" value="<?php echo get_option('comparison_pt'); ?>">
<?php
$types = get_post_types(array());
$fields = get_fields();
foreach($types as $type) { ?>
<option value='<?php echo $type; ?>'><?php echo $type; ?></option>
<?php } ?>
</select>
Based on the selected option from the above dropdown
$('#settings_post_type').change(function() {
var selected_post_type = $('#settings_post_type option:selected').text();
$.ajax({
url: plugin_object.admin_url,
type: 'POST',
data: {
action: 'get_settings_field_values',
type: selected_post_type
},
success: function(response) {
console.log('AJAX POST => SUCCESS');
$('#settings_field_types').text('');
$('#settings_field_types').append(response);
},
error: function(response) {
console.log('AJAX POST => ERROR');
console.log(response);
}
});
});
I use the selected value as a WP_Query post_type parameter, returning only 1 post and using that to determine the available field_types for that post.
This outputs a number of labels and checkboxes as can be seen in the images provided, when they're clicked I have a function to detect which checkboxes are checked and then pushes them into an array e.g. var selected = ['population', 'growth_pa'];
I want to save this array in wordpress as an settings_field which is already predefined.
add_settings_field("comparison_ft", "Comparison Field Types", "display_fields_form_element", "plugin-options", "options_section");

Related

jQuery star rating plugin doesnt return correctly amount of stars

I'm making a rating system to rate a post using 5 stars. I use the jQuery bar plugin for this (jQuery bar plugin).
Users can vote posts from 1 to 5. The data is stored in the database. After someone votes the stars will be disabled and show the amount of stars the user rated.
Rating is correctly stored in database and after user rate e.g. 3 stars It display 3 stars and console.log currentRating show correctly 3 stars, but when user go other page and go back to the post that rated it won't return the right amount and it will just show 1 star. When someone other user go that post that someone else rated it displays 1 star always.
So what I've done wrong or is barrating lib supposed work that way?
How I can always display right amount stars as active and when user come back or ctrl+f5 right amount stars displayed?
Code:
$rating_res = "SELECT * FROM post_rating
WHERE post_id = " . $id . " AND userid = " . $userid;
$rating_arr = sql_query($rating_res);
$getRating = mysql_fetch_array($rating_arr);
$rating = $getRating['rating'];
$avg_res = "SELECT ROUND(AVG(rating), 1) as numRating
FROM post_rating WHERE post_id=".$id;
$avgresult = sql_query($avg_res);
$fetchAverage = mysql_fetch_array($avgresult);
$numRating = $fetchAverage['numRating'];
if ($numRating <= 0) {
$numRating = "N/A";
}
<select id='rating_<?php echo $id; ?>' name="star_rating_option"
class="rating" data-id='rating_<?php echo $id; ?>'>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
Rating: <span id='numeric_rating_<?php echo $id; ?>'><?php echo $numRating; ?></span>
And here is jquery barrating part:
$(document).ready(function() {
currentRating = $(".rating").val();
console.log(currentRating);
$('#rating_<?php echo $id; ?>').barrating('set',<?php echo $rating; ?>);
});
$(function () {
$('.rating').barrating({
theme: 'fontawesome-stars',
initialRating: $(this).data('current-rating'),
//initialRating: currentRating,
onSelect: function (value, text, event) {
var el = this;
var el_id = el.$elem.data('id');
if (typeof (event) !== 'undefined') {
var split_id = el_id.split("_");
var post_id = split_id[1];
$.ajax({
url: './rate.php',
type: 'post',
data: {
post_id: post_id,
rating: value
},
dataType: 'json',
success: function (data) {
var average = data['numRating'];
$('#numeric_rating_' + post_id).text(average);
}
});
}
}
});
});
Few notes, $(document).ready(function() {}); and $(function () {}); are equivalents, so the order is wrong, you should first initialize the barrating and then doing barrating('set', ...).
$(".rating").val() since you dont have any option as selected the value will be allways the same, could change if you correct the document.ready ordering, either way you cannot use it as per commented line initialRating: currentRating because that information doenst exist yet, its the barrating initialization which set it. Purpouse of initialRating is different then setting the current value btw.
initialRating: $(this).data('current-rating'), there is no attribute data-current-rating at the initialization, so this one is wrong too, imo you are missing that attribute.
id and data-id contains the same value its kinda nonsence, you could simply just put the id into data-id attribute and omit the string spliting part.
From your post its not clear how do you include the javascript part into your page, the initialization part should be in separate file to properly use caching and the setting part in php because you printing the current rating from php variable. Take a look at page source locate the line $('#rating_<?php echo $id; ?>').barrating('set',<?php echo $rating; ?>); and check if there is actually expected output, if there is then its just the ordering problem.

how to get each selected checkbox value from foreach loop using jquery

I have received the value from the array then made a foreach to achieve each value from it.
after adding each value to checkbox then made a onclick function to pass value to jquery function.
i have receiving each value just one by one I need to collect all those value who has been selected from user by clicking on checkbox.
Here is my code
$val = array();
$val = array("Peter"=>35, "Ben"=>37, "Joe"=>43);
foreach ($val as $value){
<input type="checkbox" id="vehicle1" name="vehicle1" value="<?php print_r($value['id']); ?>"
onclick="assignId(<?php echo (isset($value['id'])?$value['id']:'0') ?>)">
}
Here is my jquery function where I need to collect all checkbox selected record and pass to controller
function assignId(val) {
alert(val);
$.ajax({
url: '/path/to/file',
type: 'POST',
dataType: 'json',
data: {param1: 'value1'},
success : function(response){
alert(response);
}
});
}
As you can see, I just need to get all the selected value of the checkbox which is here under foreach and pass it to controller.
The array that you are looping over is an associative array, which means it has key-value pairs. When you loop over such an array you can destructure the keys and values in the foreach statement. This way you can dynamically set the id, name and value of each checkbox.
Making your ids and names unique is actually quite important. Takes makes it possible to distinguish elements from one another and it makes it possible to pair each input with a value. Names can be the same though, but for now make them unique.
Wrap your <input> elements in a <form> tag. This form tag will make it easier for you to use jQuery and get all the values from each input whenever you need them. Also add a <button> to submit the form.
<?php
$data = array(
"Peter" => 35,
"Ben" => 37,
"Joe" => 43
);
?>
<form id="vehicleForm">
<?php foreach ($data as $key => $value) { ?>
<input type="checkbox" name="vehicle-<?php echo $key); ?>" value="<?php echo $value); ?>"/>
<?php } ?>
<button type="submit">Submit</button>
</form>
Modify your assignId function to accept a single string which can be used for the data property on your AJAX call. This string will be generated by the jQuery after this example.
function assignIds(data) {
$.ajax({
url: '/path/to/file',
type: 'POST',
dataType: 'json',
data: data,
success: function(response){
alert(response);
}
});
}
Listen to the submit event on the form. This event will be triggered every time you click on the submit button. Forms have a default behavior. You'll want to prevent this default behavior so you can create your own.
With the .serialize() method you extract the values from the form. The result of this method is a query string ready to send to the server. Pass that to the assignIds function and your data is sent.
$('#vehicleForm').on('submit', function(event) {
event.preventDefault();
var $this = $(this);
var data = $this.serialize();
assignIds(data)
});
What bad thing comes up to your code is that every time you click the checkbox it will send a request to your server. So I've made you a simple solution for your problem.
in your PHP Code write this:
<form id="myForm">
<?php
$value = array("Peter"=>35, "Ben"=>37, "Joe"=>43);
var_dump($value);
foreach ($value as $val => $data){
echo '<input type="checkbox" id="vehicle1" name="vehicle1" value="'.$data.'" /><label>'.$val.'</label>';
}
?>
<input type="submit" name="" value="submit">
</form>
Then for your Script:
$('form').on('submit', function( event ) {
console.log($(this).serialize());
event.preventDefault();
$.ajax({
url: '/path/to/file',
type: 'POST',
dataType: 'json',
data: {param1: $(this).serialize()},
success : function(response){
alert(response);
}
});
});
I hope this will help you. Happy Coding!!!
All main problems of your code has been already well explained and fixed by #Emiel but always there is different approach to solve every problem. The following are steps i followed and i have decided to use only one function. In addition there might be something useful for future readers. That's why i'm writing this answer.
I created a button to submit the form because you cannot use onclick() function on each checkbox that will be triggered every time someone clicks on it. So create a button with onclick=assignID().
I fixed the approach you have used is not correct which have already been mentioned in first answer by #Emiel so better not repeat it.
I kept the name of checkboxes the same so that i can access them in general later using getElementsByName(vehicle1) function.
in assignID() I created an array to hold the value of checked boxes
then used JSON.stringify() to format the array as JSON data.
<?php
$val =array("Peter"=>35, "Ben"=>37, "Joe"=>43);
foreach ($val as $key=>$value){//assouciative array have key and value relation
?>
<input type="checkbox" id="vehicle1" name="vehicle1" value="<?php echo $value; ?>"><!--//you don't have to put onclick functio in here-->
<?php
}
?>
<button onclick="assignId()">Button</button><!--Its necassary to have a button to submit value-->
<script type="text/javascript">
function assignId() {
var datas = [];//crating array
var checkboxes=document.getElementsByName("vehicle1");//getting all checkboxes by name
for(var i=0, n=checkboxes.length;i<n;i++) {//looping through each checkboxes to see if they are checked
if(checkboxes[i].checked==true){//check if checkbox is checked
datas.push(checkboxes[i].value);//push the value of the checked checkbox into datas array
}
}
$.ajax({
url: 'path/to/php/file',
type: 'POST',
datatype:"json",
data: {
param1: JSON.stringify(datas)//send the array in JSON data form
},
success : function(response){
alert(response);
}
});
}
</script>

PHP and AJAX Loading Data

Good Day. I'm trying to develop a plugin for WordPress that manually sends an e-mail (containg the WooCommerce Order details) to a desired supplier's e-mail. I'm having a hard time figuring out on how to load a data when a user select from a drop down list. I would like to load the data using AJAX on multiple fields without leaving the page. Here's some part of the code:
<select id = "dropdown_orders" class = "dropdown_orders" name="dropdown_orders" onchange="myFunction(this.value)">
<option value=""><?php _e( 'Select an Order', 'woocommerce-manual-order-forwarding' ); ?></option>
<?php
foreach($order_details as $details => $value)
{
echo '<option value="' . $value['ID'] . '">' . "Order ID: " .$value['ID'] . '</option>';
}
?>
</select>
That is the code for the drop down list to show all the Orders with "Complete" Status. And here is the AJAX part.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"</script>
<script type="text/javascript">
function myFunction(value)
{
if(value!="")
{
$.ajax(
{
type: "GET",
url: '<?php echo $_SERVER['PHP_SELF']; ?>',
data: { experience: value},
success: function(data) {
alert("You have selected the Order ID of: " + value);
//I want to display a div element that contains all the data from the WordPress database.
}
});
}
else
{
alert("Please Select and Order ID first!");
}
}
</script>
What I want to achieve is that, when the user select from one of the options from the drop down list, the page will display a div element that displays all the details about the order. Is it possible to do that? Any help would be appreciated. I know that it's impossible to call a PHP function after the "success" part of AJAX.
EDIT HERE
On display-orders-admin.php
<div id="forward-field" class="wrap">
<h2><?php _e( 'WooCommerce Order Forwarding System', 'woocommerce-manual-order-forwarding' ); ?></h2>
<p><?php _e( '<strong>Note:</strong> This add-on gives you the capability to forward your WooCommerce orders individually on your desired supplier.', 'woocommerce-manual-order-forwarding');?></p>
</div>
<div class="container-box">
<h2><?php _e( 'Order Details', 'woocommerce-manual-order-forwarding' ); ?></h2>
<p><?php _e( '<strong>Note:</strong> Please select an order from the drop down list below to use the order e-mail forwarding feature.', 'woocommerce-manual-order-forwarding');?></p>
<select id = "dropdown_orders" class = "dropdown_orders" name="dropdown_orders">
<option value=""><?php _e( 'Select an Order', 'woocommerce-manual-order-forwarding' ); ?></option>
<?php
foreach($order_details as $details => $value)
{
echo '<option value="' . $value['ID'] . '">' . "Order ID: " .$value['ID'] . '</option>';
}
?>
</select>
<div class="custom-border"></div>
<!-- TRIGGER AN ACTION HERE WHEN THE USER SELECT FROM ONE OF THE ORDER IDS FROM DROPDOWN -->
<!-- EXECUTE A JQUERY | AJAX REQUEST TO PULL OUT ALL THE DETAILS OF THE ORDER WITH THE GIVEN ID -->
<!-- DISPLAY THE ORDER DETAILS USING DIV ELEMENTS ON THE SAME PAGE -->
</div>
How can I achieve those in comments?
First you are using jQuery, yet you are doing things old-school by using onchange. Let's not do that.
Remove onchange attribute and instead attach an onchange event listener to your dropdown using .change() method.
<select id="dropdown_orders" class="dropdown_orders" name="dropdown_orders">
<option value=""><?php _e( 'Select an Order', 'woocommerce-manual-order-forwarding' ); ?></option>
<?php foreach ($order_details as $details => $value) : ?>
<option value="<?php echo $value['ID'] ?>">Order ID: <?php echo $value['ID'] ?></option>
<?php endif ?>
</select>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"</script>
<script>
$(function () {
$('#dropdown_orders').change(function () {
if (this.value != "") {
// fyi: $.getJSON() method is a shorter syntax
$.ajax({
type: "GET",
url: '<?php echo $_SERVER['PHP_SELF'] ?>',
data: { experience: this.value },
dataType: "json",
success: function (res) {
// ...
}
});
} else {
alert("Please Select and Order ID first!");
}
});
});
</script>
Now, regarding your actual problem, make your PHP return back a JSON string using json_encode(). A starter example of how your PHP script would look like:
// first step: check the request parameter
if (isset($_GET['experience'])) {
// get the order detail e.g. $order based on the request parameter
// let's assume $order is an associative array e.g. $order = ['id' => 123, 'price' => 12.40]
// final step: send back a JSON-encoded response
header('Content-Type: application/json');
echo json_encode($order); // only this should be echo'd
}
Back to the HTML/JS code, all you have to do is process the response res once it is received in the success callback. First, it may be a good idea to create and re-use a hidden block element to store your order detail's information. This will be like a template. You will just need to show it once the order information is ready.
So, first add the following to your HTML:
<div id="order-detail" style="display: none;">
<div class="id"></div>
<div class="price"></div>
</div>
Next, change your JS.
$(function () {
$('#dropdown_orders').change(function () {
if (this.value != "") {
// fyi: $.getJSON() method is a shorter syntax
$.ajax({
type: "GET",
url: "<?php echo $_SERVER['PHP_SELF'] ?>",
data: { experience: this.value },
dataType: "json",
success: function (res) {
// load the information from your response into the DIV
var $div = $('#order-detail');
$div.find('.id').html(res.id);
$div.find('.price').html(res.price);
// show the DIV once everything is ready
$div.show();
}
});
} else {
alert("Please Select and Order ID first!");
}
});
});
Instead of having a template to store your order details, you can also build the DIV with the order information within your success callback; however, this may lead to messy code.

How can I have a PHP query select a certain table based on a drop down list selection?

I have a web program where the goal is plot data points for a certain Kiln that the user has selected. My problem is when a user wants to select a new Kiln, how can I update all the separate JSON pages to where the data is pulled from the new table they selected?
Here is my drop down list creater code.
<p class="navleft">
Kiln Number:<br>
<select name="kilns" id="kilns">
<?php
$sql = "SHOW TABLES FROM history";
$result = mysqli_query($con,$sql);
while($table = mysqli_fetch_array($result)) { // go through each row that was returned in $result
echo ("<option value='". $table[0] . "'>" . $table[0] . "</option>");
}
?>
</select>
</p>
And here is one of the php pages where I select all the data from a value in a table and turn it into a JSON file.
<?php
$con = mysqli_connect("localhost","KilnAdmin","KilnAdmin","history");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_select_db($con,"history") or die ("no database");
//Fetch Data
$query = "SELECT * FROM k1_history LIMIT 1000";
$result = mysqli_query($con,$query);
if ($result) {
$data = array();
while($row = mysqli_fetch_assoc($result)) {
//$data[] = $row;
$data[] = array(
"date" => $row[ 'Timestamp' ],
"value" => $row[ 'DryBulbFront' ]
);
}
echo json_encode($data);
}
else {
echo "Error";
}
?>
Where is says k1_history, how can I get that to be the selection from the user in the dropbox menu from the other page?
In this kind of scenario you have to strongly pay attention to avoid SQL injection. Use a whitelist approach as mentioned by Konstantinos Vytiniotis and check this out How can I prevent SQL injection in PHP?
If I understand correctly what you want, then what you need is Ajax.
You have to populate the select like you do and on each select, make an Ajax call to a .php where you will handle what the user has chosen. In your case this .php file is going to take the table name the user chose, run a query and return some results back to the html. For demonstration purposes, I'll explain with an example.
Let's say in your .html you have a select like this:
Select Value:
<select name="kilns" id="kilns">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
What defined in the value property of the option is what you are gonna pass to the .php file I mentioned. To do that, you use Ajax, so inside some script tags you have:
$('#kilns').on('change', function(e) {
var data = {'kilns': this.value};
$.ajax({
type: 'POST',
url: 'submit.php',
data: data,
dataType: 'json'
}).done(function(msg) {
alert(msg);
});
});
What this does is that every time a user selects something from the select, then this function is called, where the select's value (var data = {'kilns': this.value};) is being sent to a file named submit.php, via POST. The submit.php could look like this:
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
$kilns_error = 0;
if (isset($_POST['kilns']) && !empty($_POST['kilns'])) {
$kilns = $_POST['kilns'];
} else {
$kilns = null;
$kilns_error = 1;
}
if ($kilns_error != 1) {
echo json_encode($kilns);
}
}
What happens here is after we check we have indeed a POST REQUEST, we check whether the value is undefined or empty. After this simple check, we proceed to echo json_encode($kilns); where we return the value that we initially sent to the .php script, which in fact is the value the user selected.
In your case, what you have to do it to actually do some things in the .php script and not just return the value that you called it with. Also, make sure to pass the value you take through a whitelist to ensure that the user selects an actual table and is not trying to create problems for your database, cause it would be really easy to just change the value of what he is going to select before actually selecting it. Have a look at the prepared statements of the mysqli and PDO.

Dropdown based on previous selection is not populating at all

I am trying to fill in a dropdown list from a mysql table based on the selection on a previous dropdown.
I have looked at many questions asking how to do this and came up wit the follwing, however nothing is happening to my second dropdown when I select something from the first.
I have newStock.php with the following script in the head.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
<script type="text/javascript">
$(function(){
$('#field').change(function(){ //on change event
var fieldVal = $('#field').val(); //<----- get the value from the parent select
$.ajax({
url : 'process.php', //the url you are sending datas to which will again send the result
type : 'GET', //type of request, GET or POST
data : { fieldValue: fieldVal}, //Data you are sending
success : function(data){$('#field2').html(data)}, // On success, it will populate the 2nd select
error : function(){alert('an error has occured')} //error message
})
})
})
</script>
With the two drop downs created in the body:
<?php
connect('final');//connect to DB
$sql = mysql_query("SELECT * FROM stockcata");
while ($row = mysql_fetch_array($sql)){
echo '<option value='.$row['id'].'>' .$row['Catagory']. '</option>';
}
?>
</Select> </label>
<input type="text" name="addCatagory" />
<label><span>Section</span>
<Select name="field2" id="field2">
</Select> </label>
And the following process.php used to query my database and provide the options to fill in the second drop down
<?php
require("header.php");
connect('final');
$temp = $_GET['fieldValue'];
$result = mysql_query("SELECT * FROM stocksection WHERE cataID = '$temp'");
while ($row = mysql_fetch_array($result)){
echo '<option value='.$row['id'].'>' .$row['section']. '</option>';
}
?>
Nothing happens in the second dropdown, I have no idea why.
Edit.........
I tried to debug it further. My database is set up with 2 tables;
Section: ID, title, Catagory_ID
and Catagory: ID, Title
When it queries the section table it is only returning data with a Catagory_ID of 0, no matter what option I chose from the drop down
The data in the success of your ajax call is not the string you think it is. You probably want something like this:
success : function(data){$('#field2').html(data.d)}, // On success,
Try a console.log(data.d); if that doesn't work to see what you are returning.

Categories

Resources