Change PHP variable using javascript or AJAX on the same page - javascript

I know this question has been asked alot of times, but I think in my case, I'm dealing with something different, or better saying, I need something different.
I'm using an open source that works as appointments booking but unfortunately, the client can choose the service and not the duration of it. I can recreate the same service by manually adding it more times with different minutes length but that way, in the dropdown menu, would be present alot of options and that's not what I'm looking for as a workaround.
So, what I thought of, was using a dropdown to select the time, and based on that selection, on the services dropdown menu, would show the ONLY the corresponding ones based on time.
THe site looks like this:
site
What I'm looking for, is that whenever I select the nr of hours... I ONLY GET the services that are part of that hour and not all of them.
I'm ok with using a button that refreshes the page as far as that works, but I can't create another file that then redirects here.
This is the part of the code interested in that:
<select id="select-service" class="col-xs-12 col-sm-4 form-control">
<?php
// Group services by category, only if there is at least one service with a parent category.
$has_category = FALSE;
foreach($available_services as $service) {
if ($service['category_id'] != NULL) {
$has_category = TRUE;
break;
}
}
if ($has_category) {
$grouped_services = array();
foreach($available_services as $service) {
if ($service['category_name'] == '2 HOURS' || $service['category_name'] == '1 HOUR' || $service['category_name'] == '3 HOURS') {
if (!isset($grouped_services[$service['category_name']])) {
$grouped_services[$service['category_name']] = array();
}
$grouped_services[$service['category_name']][] = $service;
}
}
// We need the uncategorized services at the end of the list so
// we will use another iteration only for the uncategorized services.
$grouped_services['uncategorized'] = array();
foreach($available_services as $service) {
if ($service['category_id'] == NULL) {
$grouped_services['uncategorized'][] = $service;
}
}
foreach($grouped_services as $key => $group) {
$group_label = ($key != 'uncategorized')
? $group[0]['category_name'] : 'Uncategorized';
if (count($group) > 0) {
echo '<optgroup label="' . $group_label . '">';
foreach($group as $service) {
echo '<option value="' . $service['id'] . '">'
. $service['name'] . '</option>';
}
echo '</optgroup>';
}
}
} else {
foreach($available_services as $service) {
echo '<option value="' . $service['id'] . '">' . $service['name'] . '</option>';
}
}
?>
</select>

I only use a single AJAX function for my platform. Below is a minimal example:
function ajax(method,url,param_id_container_pos,id_container)
{
var xhr = new XMLHttpRequest();
xhr.open(method,url,true);
xhr.onreadystatechange = function()
{
if (xhr.readyState=='4')
{
var type = xhr.getResponseHeader('content-type').split('/')[1];
if (method=='post')
{
if (type=='json')
{
var j = JSON.parse(xhr.responseText);
console.log(j);//Check your browser's developer network panel.
eval(j.javascript);//eval is frowned upon though just use to call a sequel JS function.
}
}
}
}
}
//Example uses:
ajax('get','admin/?ajax=account','inside','id_target');
var fd = new FormData();
fd.append('ajax','admin_post_account_approval');
fd.append('parameter1',object1);
fd.append('parameter2',object2);
ajax('post',path+'admin/',fd);
Your goal is to make your code minimal and highly reusable when possible.
In regards to the server and PHP you need to remember: never trust the user. That means you need to verify everything:
<?php
if (isset($_POST['ajax']) && $_POST['ajax']=='admin_post_account_approval')
{
if (!isset($_POST['parameter1'])) {/*error_handling*/}
else if (!isset($_POST['parameter1'])) {/*error_handling*/}
else if (![condition not met]) {}
else
{
if ([all conditions met])
{
header('Content-Type: application/json');
$array = array('javascript'=>'alert(\'Just a JavaScript alert triggered by PHP.\');');
die(json_encode($array));
}
}
}
?>
Server side code, PHP should be thought of like real life: always fail first and test the conditions for length, proper characters or improper characters in form parameters, etc.
Additionally I highly recommend having the server respond with JSON as I generally illustrated in the code above. Because I only write my own code and don't work with other people's code this is more of a generic response than attempting to target whatever software you're working with. Regardless if you enable error reporting and pay attention to your developer tools in whichever browser you're using you'll get there. Good luck.

Related

Disabling HTML button on condition with PHP (WordPress Plugin)

I'm making a custom plugin for a WordPress powered page to disable a certain button on condition.
Context: To disable place order button if the user breached a certain credit limit.
I'm expecting that upon entering checkout page, the plugin will fire and check if the user exceeded the credit limit. If yes, it will then alert the user and disable the place order button.(OR create an overlay OR any other methods)
For now I have this:
function credit_limit_check()
{
/** page 13 is the check out page ID*/
if (is_page(13)) {
if (is_user_logged_in()) {
/* For reference purpose*/
/* get_user_meta( int $user_id, string $key = '', bool $single = false ) */
$ID = get_current_user_id();
$credit_val = get_user_meta($ID, 'credit_limit', true);
$outstanding_val = get_user_meta($ID, 'outstanding_credit', true);
$credit_breach = $credit_val - $outstanding_val;
if ($credit_breach <= 0) {
/*disable checkout button if not enough credit limit*/
echo '<button type="submit" class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="Place order" data-value="Place order" disabled>Place order</button>';
echo '<script>alert("You have exceeded your credit limit, please make sure you have no outstanding bill")</script>';
} else {
print_r("Huzzah! Good news! You have enough credit to proceed!");
}
} else {
print_r("Please login with your account before proceeding.");
}
}
}
The only problem is that the functions actually creates an extra button on top of the page instead of disabling the original button. So I am wondering if this is actually doable, or do I have to modify the html files directly to achieve what is intended.(Preferably not)
Now, I do see some similar questions, but all of them require directly applying php in the html tags. It is not applicable for my situation as I am creating a wordpress custom plugin. (Which is an individual php file).
Well I would solve this in two parts.
Step 1 . Adding proper notices.
function add_notices_for_checkout_credit()
{
if(is_checkout()) {
if (is_user_logged_in()) {
$ID = get_current_user_id();
$credit_breach = getUserCredit($ID);
if ($credit_breach <= 0) {
wc_add_notice( 'You have exceeded your credit limit, please make sure you have no outstanding bill', 'error' );
} else {
wc_add_notice( 'Huzzah! Good news! You have enough credit to proceed!', 'success' );
}
}
}
}
add_action( 'wp', 'add_notices_for_checkout_credit');
function getUserCredit($ID) {
$credit_val = get_user_meta($ID, 'credit_limit', true);
$outstanding_val = get_user_meta($ID, 'outstanding_credit', true);
$credit_breach = $credit_val - $outstanding_val;
return $credit_breach;
}
With less credit it shows.
When sufficient credit it shows.
Step 2 . Restricting button
function change_button($order_button)
{
if (is_user_logged_in()) {
$ID = get_current_user_id();
$credit_breach = getUserCredit($ID);
if ($credit_breach <= 0) {
$order_button_text = __( "No Credit", "woocommerce" );
$style = ' style="color:#fff;cursor:not-allowed;background-color:#999;text-align:center"';
return '<a class="button alt"'.$style.' name="woocommerce_checkout_place_order" id="place_order" >' . esc_html( $order_button_text ) . '</a>';
}
}
return $order_button;
}
add_filter( 'woocommerce_order_button_html', 'change_button');
This will disable the button, and you should be good to go.
Don't check for guest in your code, change it from your woocommerce setting. In Account setting mark it compuslory to login when checking out.
PS : For extra security use woocommerce_checkout_update_order_review to check if its a valid request because someone can create a submit button using developer tool.

JQuery and the editableSelect package is not allowing me to Filter a select menu with a RegExp. JavaScript and jQuery nub or novice

Here is a select list built using PHP, MariaDB, and HTML:
echo "<select name='companylist' id='companylist' size='86' value='' tabindex='1' >";
echo "<option value=''></option>";
echo "<option value='0-Create a New Company'>0-Create a New Company</option>";
foreach ($companyResult as $company) {
echo "<option id='".$company['Company_Key']."'
value='".$company['Company_Key']."'>".$company['Company_Names']."</option>";
}
echo "</select>";
It builds a dropdown list that is appropriate for my application.
Next, I built this testing script to find out if I was on the right track in the use of RegExp to filter the dropdown select list dynamically, and it works well, for its purpose. I only built it because the list following it is giving me fits.
echo "<script>";
echo "$('#companylist option').each(function() {
var Val = this.text;
var Filter='W';
var CompRegex = new RegExp('^'+Filter);
if(CompRegex.test(Val)){
console.log('RegExp with Filter has found the following Val starting with this
Filter: '+Filter);
console.log('Val = ' + Val);
}
})";
echo "</script>";
This above gives me the following console output:
RegExp with Filter has found the following Val starting with this Filter: W
Val = Welch Tile
RegExp with Filter has found the following Val starting with this Filter: W
Val = West Michigan Molding
RegExp with Filter has found the following Val starting with this Filter: W
Val = WL Molding of MI
This is a good start.
echo "<script>";
echo " $('#companylist')";
echo " .editableSelect()";
echo " .on('select.editable-select', function (e, li) {
console.log('value = ' + document.getElementById('companylist').value);
console.log('li.val() = '+li.val());
getCustomer_Names(li.val());
getTool_Numbers(li.val());
getPart_Name(li.val());
newCompany_Name();
})";
echo "</script>";
This above script loads other menus, as expected, once the user selects an item.
The next script here simply will not let me get the option text that the user sees in the list. I have 5 days into this, because I am new to JQuery and not a master of Javascript either, but I do read all kinds of sites for help, including reference guides, and the support boards (thank you for this one!), but I would like a happy ending soon. Any help, as stated, would be very appreciated.
echo "<script>";
echo " $('#companylist')";
echo " .editableSelect()";
echo " .on('input.editable-select', function () {
$(this).each(function() {
var Val = this.text;
var Filter = this.value;
var CompRegExp = new RegExp('^'+Filter);
console.log('Val = '+Val);
console.log('Filter = '+Filter);
console.log('CompRegExp = '+CompRegExp);
if(CompRegExp.test(Val)){
console.log('RegExp with Filter has found the following Val starting with this
Filter: '+Filter);
console.log('Val = ' + Val);
}
else {
// remove from select list
}
});
});";
echo "</script>";
This above script gives me
Val = undefined
Filter = a
CompRegExp = /^a/
It is the "Val = undefined" that is my undoing.
I also took a long-view of this problem and wrote a jQuery/JavaScript program that clears the dropdown list and then recreates the options by having a PHP program re-query the database to get the values that match a SQL LIKE 'Input%' which I will include to show you the depth of effort here. The problem here is that I could not get the dropdown menu to stay open even though I issued .editableSelect('show'); as instructed in the editableSelect git website to open the dropdown menu and show the modified list, although, if I clicked in the field and moved the cursor around, it would pop the menu open with the values that matched the return from MariaDB. It follows:
echo "<script>
function getCompany_Names(comp_val)
{
if(document.getElementById('companylist').value.substring(0,8) != '0-Create'){
$('#companylist').editableSelect('clear');
var xhttp;
if (comp_val === null || comp_val === '' ) {
$('#companylist').editableSelect('add', '<option value=></option>');
$('#companylist').editableSelect('add', '<option value=0-Create a New Company>0-Create a
New Company</option>');
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var select = $('#companylist');
var c_text = this.responseText;
console.log('comp_ctext = ' + c_text);
c_text = JSON.parse(c_text);
$.each($(c_text),function(key,value){
if (value.compname == 'One or more Company Names are Probably Not Entered.')
{
$('#companylist').editableSelect('add','<option value=' + 'One or more Company
Names are Probably Not Entered.' + '>One or more Company Names are Probably Not
Entered.</option>');
}
else
{
console.log('<option id=\'' + value.compkey + '\' value=\'' + value.compkey + '\'>'
+ value.compname + '</option>');
$('#companylist').editableSelect('add','<option id=\'' + value.compkey + '\'
value=\'' + value.compkey + '\'>' + value.compname + '</option>');
}
}); // end .editableSelect('add',...)
}
};
xhttp.open('GET', 'getCompany_Names.php?q='+comp_val, true);
xhttp.send();
}
}
</script>";
This is all because my patron does not like the default filter behavior of the editableSelect package where it matches what is typed to any values anywhere in the dropdown and wants some dropdowns to come up matching the input to the results from first character onward with something like (exactly like) a regex of /^input_variable/.
Thank you for your time.
R
its not a solution, just easier to ask something..i'll delete more later
i dont understand this syntax: no selector before .on??
.on('input.editable-select', function () {
$(this).each(function() {
i see $(this) that means you have more input?
the problem with these lines:
var Val = this.text;
var Filter = this.value;
what is Val? because this.text is not functional for input? (its the reason Val => undefined)
this.value gives what you type in input
This is WAY more complicated than my core problem actually is. I have posted another question that is just my actual failure. It is at: [https://stackoverflow.com/questions/66801231/the-use-of-https-github-com-indrimuska-jquery-editable-select-for-editable-sel]
I think I have an example of an example page the creator put together and it has a function their I am only just starting to understand, but it is all about adding values to the list. I will study it and post my results on the core issue page. Thank you to all who tried to help. Here's one for brevity.

Check if an external url is working PHP or JS

I have a php numeric array that includes 1000+ external links. Can you please help me figure out a PHP or JS function that will loop through every link and check if it's working or not? To create an array and include links that are no longer working.
For now I'm using this code:
$links = array(
'http://google.com',
'http://example.com',
'http://awkrlalrno1in01n2rn12r12r.com',
'http://112om1om1om.ru'
);
foreach($links as $link) {
if($file_headers = #get_headers($link)) {
if(strpos($file_headers[0],'404') !== false) {
$toDeleteLinks[] = $link;
}
}elseif($handle = curl_init($link)) {
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
//Get the HTML or whatever is linked in $url.
$response = curl_exec($handle);
//Check for 404 (file not found).
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode == 0) {
$toDeleteLinks[] = $link;
}
curl_close($handle);
}
}
if(isset($toDeleteLinks)) {
echo '<pre>';
print_r($toDeleteLinks);
echo '</pre>';
}
but it gives a 500 Internal Server Error.. seems like server is unable to handle so much requests, since I've tried to create an array with 4 links, 2 - correct links, 2 incorrect ones and the function works as a charm.
I'm about to pull my hears out of my head, so please help :D Thanks in advance!

PHP validation to check if record exists

I'm trying to create a validation for a form. When a user fills out the form, it is supposed to run a set of queries. The first is to check if a records already exists in the table. If it does exist, then it doesn't need to run the the next 2 queries, which are to INSERT and UPDATE.
I'm not sure what I am doing wrong, but the table already has an existing record. After checking the table, it still runs the INSERT and UPDATE queries. They should not fire. It should not do anything.
Here is my code: * I'm starting my code from the for loop, which is just taking an array of BOL numbers and CONTAINER numbers that the user manually selected. I exploded the array, but I will not show that code as I do not think it is necessary to show in this case *
<?php
for($i = 0; $i < $count; $i++)
{
$bolService = $bolArray[$i];
$conService = $conArray[$i];
$checkService = "SELECT * FROM import_service WHERE bol = '" . $bolService . "' AND container = '" . $conService . "'";
$checkSerRes = mysql_query($checkService);
$checkSerNum = mysql_num_rows($checkSerRes);
if($checkSerNum > 0)
{
$successService = false;
}
elseif($checkSerNum = 0)
{
$sql_query_string = mysql_query
("INSERT INTO import_service (bol, container) VALUES ('$bolService','$conService')");
$updateService = mysql_query ("UPDATE import_dispatch_details SET SERVICE = 'Y'
WHERE BOL_NUMBER = '$bolService' AND CONTAINER = '$conService')");
$successService = true;
}
}
// javascript fires an ALERT message in this next set of code
if($successService = true)
{
echo ("<script language='javascript'>
window.alert('Record has been saved')
window.location.href=''
</script>");
}
// if checkSerNum > 0, then it should skip the INSERT and UPDATE and fire the code below
elseif($successService = false)
{
echo ("<script language='javascript'>
window.alert('There was an error saving the record')
window.location.href=''
</script>");
}
?>
I'm not sure why this is not working correctly. I need this validation to work. I'm sure there is an alternative method, but this is what I got.
Please help me make this work.
Thank you in advance.
This elseif($checkSerNum = 0) needs to be elseif($checkSerNum == 0)
You're presently doing an assignment instead of a comparison.
Including if($successService = true) and elseif($successService = false) so add another = sign.
Add error reporting to the top of your file(s) which will help during production testing.
error_reporting(E_ALL);
ini_set('display_errors', 1);
http://www.php.net/manual/en/function.mysql-error.php
Footnotes:
mysql_* functions deprecation notice:
http://www.php.net/manual/en/intro.mysql.php
This extension is deprecated as of PHP 5.5.0, and is not recommended for writing new code as it will be removed in the future. Instead, either the mysqli or PDO_MySQL extension should be used. See also the MySQL API Overview for further help while choosing a MySQL API.
These functions allow you to access MySQL database servers. More information about MySQL can be found at » http://www.mysql.com/.
Documentation for MySQL can be found at » http://dev.mysql.com/doc/.
This isn't quite efficient (you are selecting * from your table, which you aren't using - waste of memory?). Why don't you do something like this:
for ($i = 0; $i < $count; $i++)
{
$bolService = $bolArray[$i];
$conService = $conArray[$i];
$recordExists = false;
$result = mysql_query("SELECT COUNT(*) AS recordCount FROM import_service WHERE bol = '" . $bolService . "' AND container = '" . $conService . "'");
if ($result) {
$row = mysql_fetch_assoc($result);
$recordExists = ($row['recordCount'] >= 1);
}
if ($recordExists)
{
$successService = false;
}
else
{
$sql_query_string = mysql_query
("INSERT INTO import_service (bol, container) VALUES ('$bolService','$conService')");
$updateService = mysql_query
("UPDATE import_dispatch_details SET SERVICE = 'Y'
WHERE BOL_NUMBER = '$bolService' AND CONTAINER = '$conService')");
$successService = true;
}
}
P.S. mysql_* is officially deprecated. Please use PDO or MySQLi. Also, your code is potentially open to SQL Injection.

Display final results on the same page from a dynamic drop down menu

I have a multiple drop down that goes from Country/State/city/destination.
What I want this plugin to do next, is once the destination menu is selected, the page will automatically display some general information about that destination on the same page without reloading.
The general info is in the same table as my destination drop down menu is, but under different columns.
So how can I get this information to display its self possibly in a text box or something similar only when the final distention menu is selected.
Here are some parts of my code thus far, I don't believe posting everything is necessary and might be a little confusing. PS-I am a beginner.
This is an example of my javascript which calls from my ajax.php file for the array to populate the drop down menu...
jQuery(".wrap").on('change', '#city', function() {
var querystr2 = 'cityid=' +jQuery('#city :selected').val();
jQuery.post("<?php echo plugins_url(); ?>/Destination_Drop_Down_Menu/ajax.php", querystr2, function(data) {
if(data.errorcode ==0){
jQuery('#descbo').html(data.chtml)
}else{
jQuery('#descbo').html(data.chtml)
}
}, "json");
});
This is part of my ajax.php file that previous example of jQuery is pulling information from.
$city_id = isset($_POST['cityid']) ? $_POST['cityid'] : 0;
if ($city_id <> 0) {
$errorcodeD = 0;
$strmsg = "";
$sqlD="SELECT * from destination WHERE IDCity = ". $city_id . " ORDER BY name;";
$resultD=mysql_query($sqlD);
$contD=mysql_num_rows($resultD);
if(mysql_num_rows($resultD)){
$chtmlD = '<select name="destination" id="destination"><option value="0">--Select Destination--</option>';
while($row = mysql_fetch_array($resultD)){
$chtmlD .= '<option value="'.$row['IDDestination'].'">'.$row['name'].'</option>';
}
$chtmlD .= '</select>';
echo json_encode(array("errorcode"=>$errorcodeD,"chtml"=>$chtmlD));
}else{
$errorcodeD = 1;
$strmsg = '<font style="color:#F00;">No Destination available</font>';
echo json_encode(array("errorcode"=>$errorcodeD,"chtml"=>$strmsg));
}
And MY html section that would display everything.
<h2>Destination</h2>
<div class="wrap" id="descbo">
</div>
So basically what ever destination the user chooses, the specific information for that destination will render its self on the screen in separate boxes or text areas.
Thank you!
So, if I understand correctly, you want your php script to return data from your destination table when a particular destination is selected. You said you don't want the page to reload, but I'll assume you're OK with issuing another AJAX request to the server. If that's the case, you can simply create another delegated jQuery handler for the destination <select>:
jQuery(".wrap").on('change', '#destination', function() {
var data = {destinationid: this.value};
jQuery.post("url/to/script.php", data)
.done(function(response) {
jQuery('#descbo').html(response.html);
});
Then, in your PHP, you could have something like this:
$destination_id = isset($_POST['destinationid']) ? $_POST['destinationid'] : 0;
...
$sqlD="SELECT * from destination WHERE ID = ". $destination_id . " ORDER BY name;";
$resultD=mysql_query($sqlD);
if(mysql_num_rows($resultD)){
$chtmlD = '<div class="destination">';
while($row = mysql_fetch_array($resultD)){
$chtmlD .= '<p>' . $row['whatever'] . '</p>';
}
$chtmlD .= '</div>';
echo json_encode(array("errorcode"=>$errorcodeD,"chtml"=>$chtmlD));
} else {
...
}
That will replace your original destination <select> with a div containing the destination description (or whatever the content is). If you don't want to replace the select, you could simply have the JS update a different element on the page, e.g.
jQuery('#some_other_element').html(response.html);

Categories