I am quite a newbie in Joomla and Javascript and JQuery.
I am writing a Joomla 3.x component and trying to use an Ajax call in a backend form.
I have written an Ajax call to update some fields on the fly in my edit.php (see the code below). I have attached a big part of the code as I am wondering if I am messing up with the javascript, Jquery and the Joomla stuff ...
And I get the following error at runtime on chrome : Uncaught SyntaxError: Unexpected identifier at the line method: "POST", of my Ajax call.
Any help would be highly appreciated.
Thank you very much for the time you spend on my question.
Best regards
Eric
<?php
/**
* #package Joomla.Administrator
* #subpackage com_emc
*
* #copyright Copyright (C) 2015 Eric LLANO. All rights reserved.
* #license GNU General Public License version 2 or later; see LICENSE.txt
*/
// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('jquery.framework');
JHtml::_('behavior.formvalidation');
JHtml::_('formbehavior.chosen', 'select');
JHTML::_('behavior.modal');
?>
<script type="text/javascript">
jQuery.noConflict();
function checkAmount() {
//billable_items_table = document.getElementById("#jform_billable_items_table_table");
console.log( "Table modified" );
//alert(billable_items_table.value);
}
function calculateAmount() {
billable_items_table = document.getElementById("jform_billable_items_table_table");
//
console.log( "Table saved" );
alert(billable_items_table.value);
}
function calculateVAT() {
console.log( "VAT modified" );
calculateVATAjax();
}
jQuery(document).ready(function($){
console.log( "ready!" );
function calculateVATAjax() {
var taxable = document.getElementById("jform_taxable");
var amount_exc_VAT = document.getElementById("jform_amount_exc_VAT");
jQuery.ajax({
method: "POST",
url: "index.php?option=com_emc&task=invoice.calculateVAT&format=json",
data: { taxable: taxable.value,
amount_exc_VAT: amount_exc_VAT.value,
<?php echo(JSession::getFormToken());?>: 1
},
success: function(r) {
if (!r.success && r.message) {
// Success flag is set to 'false' and main response message given
// So you can alert it or insert it into some HTML element
alert(r.message);
}
if (r.messages) {
// All the enqueued messages of the $app object can simple be
// rendered by the respective helper function of Joomla!
// They will automatically be displayed at the messages section of the template
Joomla.renderMessages(r.messages);
}
document.getElementById("jform_VAT_rate").value = r.data.VATrate;
document.getElementById("jform_VAT_amount").value = r.data.VAT_amount;
document.getElementById("jform_amount_inc_VAT").value = r.data.amount_inc_VAT;
//if (r.data)
//{
// Here you can access all the data of your response
//alert(r.data);
//}
},
failure: function(xhr) {
// Reaching this point means that the Ajax request itself was not successful
// So JResponseJson was never called
alert('Ajax error');
},
error: function(text, error) {
// Reaching this point means that the Ajax request was answered by the server, but
// the response was no valid JSON (this happens sometimes if there were PHP errors,
// warnings or notices during the development process of a new Ajax request).
alert("Ajax request was answered by the server"+"\n"+error + "\n" + text);
}
});
}
// Add the event handlers
$("#jform_taxable").change(calculateVAT);
$("#jform_billable_items_table_table").change(checkAmount);
$(".save-modal-data").click(calculateAmount);
});
</script>
Related
I want to write the dropdown-change into to an ACF field.
i have a ninja table with a dropdown and i added this code on dropdown:
<?php
wp_register_script( 'custom-acf-js', get_template_directory_uri() . '/library/scripts/script-js.js', ['acf-input'], '1.0.0', true);
wp_enqueue_script('custom-acf-js');
function feldUpdate($selector,$value,$post_id){
update_field('bewerber_einstufen', $value , $post_id );
};
//feldUpdate('bewerber_notiz','eingeladen', 192);
?>
<script type="text/javascript">
// Ninja Table Loaded initially
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
console.log('ninja_table_loaded');
let changeButton = document.querySelectorAll('select');
var acfVersion = acf.get('acf_version');
//alert(acfVersion);
for(let i=0; i < changeButton.length; i++){
changeButton[i].addEventListener("change",function(){
let rowidparent = this.parentElement.parentElement;
let rowid = (rowidparent.querySelector("p").innerHTML);
console.log(rowid);
//feldUpdate('bewerber_notiz','eingeladen', rowid);
});
};
});
</script>
So how can i write the javascript code (variables) into my php function.
Kind regards, Daniel
You cannot call a PHP function directly with JavaScript like that. PHP is executed by the server and JavaScript is executed by the browser (in this context anyway)
To achieve what you want here you need to use Ajax. Which is the front-end making a http request to the server and then the server will call your PHP function and return an appropriate response.
Creating the Ajax endpoint for WordPress
<?php
// functions.php
add_action('wp_ajax_call_feld_update', 'feldUpdateCallback');
add_action('wp_ajax_nopriv_call_feld_update', 'feldUpdateCallback'); // nopriv for unauthenticated users
/**
* Ajax call for updating bewerber_einstufen field
*
* #return void
*/
function feldUpdateCallback(): void {
}
So now you have an ajax endpoint you can call from your JavaScript. Now you need to setup the front end and have WordPress create a nonce for you, which is essentially the way you ensure the request came from the front-end of your own website.
<script type="text/javascript">
var wp_nonce = '<?= wp_create_nonce('updating-field-nonce'); ?>';
var ajax_url = '<?= admin_url('admin-ajax.php'); ?>';
// Ninja Table Loaded initially
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
// your code was here
});
</script>
Now the JavaScript variable wp_nonce will have have the nonce stored in it and the ajax_url will have the url for ajax stored in it. This is normally achieved with wp_localize_script however this is a simplified example for you.
Now you can create your ajax request like so
jQuery(document).on('ninja_table_loaded', function (event, $table, settings) {
console.log('ninja_table_loaded');
let changeButton = document.querySelectorAll('select');
var acfVersion = acf.get('acf_version');
//alert(acfVersion);
for(let i=0; i < changeButton.length; i++){
changeButton[i].addEventListener("change",function(){
let rowidparent = this.parentElement.parentElement;
let rowid = (rowidparent.querySelector("p").innerHTML);
console.log(rowid);
// ajax request
jQuery.ajax({
type: "POST",
url: ajax_url,
data: {
action: 'call_feld_update', // the action is set when you added wp_ajax_ at the beginning of this answer.
postId: rowid,
value: 'eingeladen',
nonce: wp_nonce
},
success: function (response) {
console.log(response);
},
error: function (jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
};
});
With that, WordPress will call the feldUpdateCallback function when the ajax request is sent. Now we update the PHP function that was created before so it can deal with that request...
// functions.php
/**
* Ajax call for for updating bewerber_einstufen field
*
* #return void
*/
function feldUpdateCallback(): void {
// nonce - The key you set when sending the request from ajax
// updating-field-nonce - The parameter for the wp_create_nonce function
if (!wp_verify_nonce($_REQUEST['nonce'], 'updating-field-nonce')) {
// The string we received does not match the nonce that was set on the front by WP
die('nonce validation failed');
}
// now you can deal with the request...
feldUpdate(
'bewerber_notiz',
sanitize_text_field($_REQUEST['value']), // https://developer.wordpress.org/reference/functions/sanitize_text_field/
sanitize_text_field($_REQUEST['postId'])
);
die('successful');
}
I'm trying to deduplicate a js code of major of form that do an ajax request, I initially do a php function that generate any form onsubmit function passing the different code as parameters but don't seems good.
After I tried to a javascript function instead, for simple variables I did it working, for example:
// <script> inside of the page generate by php (and in some cases in html received by other ajax request)
$('#f_man-marker_edit-marker').on('submit', function(e){
TM.editMarker(e, $(this), 'man-marker_edit-marker');
});
...
// in other js file
TM.editMarker = function (e, form, ajax_request) {
// stop browser from submitting form!
e.preventDefault();
// Abort any pending request
if (request) request.abort();
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
};
Now is missed pass request.done instructions as parameter but I not found a good and working way to do it.
Put them in a function gave me the variable response not defined, also adding it as parameter.
More exactly I tried:
$('#f_man-marker_edit-marker').on('submit', function(e){
let req_done = function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
};
TM.editMarker(e, $(this), 'man-marker_edit-marker', req_done());
});
...
// in other js file
TM.editMarker = function (e, form, ajax_request, req_done()) {
...
request.done(function (response) {
req_done(response);
});
...
};
Thas is not working.
Is possible to pass the instructions as they are and have them working or must be in a function? If must be in a function what is the right way to do it? Probably is possibile with eval() but seems highly discouraged and I not tried it for now.
EDIT:
I try to explain better: what I try to do is have a php or js function to call and pass as parameters the only things that changes, for example on on hundreds of similar forms that I will do on the project it will be fine there will be thousands or tens of thousands of lines of duplicate code avoided and a possible refactor or future improvements much simpler and faster.
I started with a generation from php, for example:
...
// "f_man-marker_add-marker" is the id of the form, "man-marker_add-marker" is the id of the ajax request, $man_marker_jap1 contain that instructions printed inside of request.done function (they can be different on any form)
TM\UI\JSHelper::jqueryAjaxPost(
"f_man-marker_add-marker", "man-marker_add-marker", $man_marker_jap1);
.....
// in the file of TM\UI\JSHelper:
...
/**
* Generate a jquery ajax of type post and datatype html
* will call the url ajax.php?req=$request_name
* and request.done will do what define in $done_content
*
* #param string $form_id Id of the form
* #param string $request_name Name of the ajax request parameter
* #param string $done_content Content of request.done
*/
public static function jqueryAjaxPost(string $form_id, string $request_name, string $done_content){
echo <<<HTML
$("#$form_id").submit(function(event){
// Prevent default posting of form - put here to work in case of errors
event.preventDefault();
// Abort any pending request
if (request) { request.abort(); }
let form = $(this);
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=$request_name",
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response){
$done_content
});
request.fail(function (jqXHR, textStatus, errorThrown){
console.error(
"Ajax $request_name request failed. The following error occurred: "+
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
});
HTML;
}
but not have js "issue" (if done correctly) because the generated code is specific per form and "full js" without call to other external functions.
I then thinked to do it mainly in js only file (which to logic would seem more correct rather generate all the js from php) and was ok except of the content of request.done that must change, so I open this post to aswer what is the best and correct way to do it.
If instead there is no better method to do what I need mainly in js and the less worst seems to remain in the php generation tell me.
EDIT2:
I did other tests and found a working solution without using eval (I don't know if good):
// inside a <script> of part of page generated by php or html code received from ajax request
$('#f_man-marker_edit-marker').on('submit', function(e){
let req_done = function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
};
TM.jqueryAjaxPost(e, $(this), 'man-marker_edit-marker', req_done);
});
...
// in other js-only file
/**
* Basic jquery ajax request of type post from form
* where changes only request.done content
* #param e Event received from onsubmit of the form
* #param form Receive the element with $(this)
* #param ajax_request Name of the ajax request send to php
* #param req_done Instruction to do on request.done
*/
TM.jqueryAjaxPost = function (e, form, ajax_request, req_done) {
// stop browser from submitting form!
e.preventDefault();
// Abort any pending request
if (request) request.abort();
// Let's select and cache all the fields
let inputs = form.find("input, select, button, textarea");
// Serialize the data in the form
let serializedData = form.serialize();
// Let's disable the inputs for the duration of the Ajax request.
// Note: we disable elements AFTER the form data has been serialized.
// Disabled form elements will not be serialized.
inputs.prop("disabled", true);
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
type: "post",
data: serializedData,
dataType: "html"
});
request.done(function (response) {
req_done(response);
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
request.always(function () {
inputs.prop("disabled", false);
});
};
Is this good or is there a better way to do it and/or possible improvement?
EDIT3:
I tried also to do something working with additional parameters:
TM.deleteMarker = function (id) {
let req_done = function (response, parArray) {
$("#ajaxoutput").empty().append(response);
$('#link_open-marker' + parArray[id]).remove();
};
TM.jqueryAjaxGet('man-marker_delete-marker&id=' + id, req_done, {id: id});
};
/**
* Basic jquery ajax request of method get and datatype html
* #param ajax_request Name of the ajax request send to php and get parameters, it will be
* will be added to the end of the url
* #param req_done Instruction to do on request.done
* #param parArray Additional parameters used in req_done
*/
TM.jqueryAjaxGet = function (ajax_request, req_done, parArray = {}) {
// Abort any pending request
if (request) {
request.abort();
}
request = $.ajax({
url: "ajax.php?req=" + ajax_request,
method: "get",
dataType: "html"
});
request.done(function (response) {
req_done(response, parArray);
});
request.fail(function (jqXHR, textStatus, errorThrown) {
console.error(
"Ajax " + ajax_request + " request failed. The following error occurred: " +
textStatus, errorThrown
);
});
};
don't gave errors or warning and work all except
$('#link_open-marker' + parArray[id]).remove();
so I suppose I did something wrong about parArray but I not undestand what, Can someone help me to solve (or do in a different way if not good this) please?
Thanks for any reply and sorry for my bad english.
I'm not quite sure if i understood your question right, but if its about getting a done callback outside of your method you have two possible ways of doing that.
Use closures:
TM.editMarker = function (e, form, ajax_request, doneHandler) {
...
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
if(doneHandler !== undefined)
doneHandler();
});
}
TM.editMarker(e, $(this), 'man-marker_edit-marker', function() {
console.log("done");
});
Use promises:
TM.editMarker = function (e, form, ajax_request) {
...
var prom= jQuery.Deferred();
request.done(function (response) {
$("#ajaxoutput2").empty().append(response);
$("#ResultModal2").modal("show");
prom.resolve();
});
return prom.promise();
}
TM.editMarker(e, $(this), 'man-marker_edit-marker').then(function() {
console.log("done");
});
Answer on edit:
Ok, so what you are trying to do is executing a javascript function through the ajax response. You could achieve this by doing something like this:
$.ajax({
url: "somejs.js",
context: document.body,
success: function(responseText) {
eval(responseText);
}
});
However this is really dirty and not good practice because javascript is usually UI manipulating commands. Keep the UI stuff in the frontend and only return raw data / json from your backend. Can you give me an example of what the response looks like then I can give you an example of how I would solve it.
I am trying to pass my $model['id'] from a foreach to a modal which contains a form which heavily requires the $model['id'] for if statements and functions.
I have tried putting a link around the button to use the usual $_GET however that forces the page to refresh and therefore closes the modal box, is there a way to prevent the modal from closing if the url contains an id?
Alternatively I have tried using the data-id passing through an AJAX post method and retrieving it in the modal. However the $_POST is not being defined, have I missed something or can it not $_POST to the same page? I am not good with AJAX so any help or ideas would be greatly appreciated.
There is way too much code in my page to post it all so here's a snippet of the important stuff
<button data-id="<?php echo $model['id']; ?>" data-modal-type="type3" class="modal_button customer_button right">New Customer</button>
<div class="modal" id="type3">
<div class="modal-content">
<div class="modal-title"><h3>New Customer</h3></div>
<div class="modal-padding">
<?php
$customer_model_id = (isset($_POST['id'])) ? $_POST['id'] : 'ID not found';
echo $customer_model_id; // Always shows ID not found
?>
</div>
</div>
</div>
<script>
$(".modal_button").click(function () {
$(".modal").hide();
var Type = $(this).data("modal-type");
$("#" + Type).show();
var id = $(this).data("id");
alert($(this).data("id")); // Alert box shows the correct ID
$.ajax({
type: "POST",
url: '<?php echo doc_root('index.php');//post to the same page we are currently on ?>',
data: "id=" + id,
});
});
</script>
EDIT:
I think I'm getting closer with this JavaScript.
<script>
$(".modal_button").click(function(){
$(".modal").hide();
var Type = $(this).data("modal-type");
var id = $(this).data('id');
$.ajax({
type : 'POST',
url : 'customer_complete.php',
data : 'id='+ id,
cache: false,
success : function(data){
$('.customer_complete').html(data);
}
})
$("#"+Type).show();
});
</script>
I decided to write some code for you, because I found the task an interesting one. The code simulates the situation that you've presented in your question and comments, and is relatively easy to follow. You can run it as it is, but don't forget to replace my db credentials with yours, in connection.php. All files are on the same niveau in the file system hierarchy. So you can create a folder, bring all files in it, and run the index.php page. I used prepared statements to insert into db, thus avoiding any sql injections risc. I also commented that part, just in case you are not familiarize with it.
Have fun.
index.php
This is the main page.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" />
<meta charset="UTF-8" />
<!-- The above 3 meta tags must come first in the head -->
<title>Demo - Modal</title>
<!-- CSS assets -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<style type="text/css">
body { padding: 20px; }
.success { color: #32cd32; }
.error { color: #ff0000; }
</style>
<!-- JS assets -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#type3').on('show.bs.modal', function (event) {
var modal = $(this);
var button = $(event.relatedTarget);
var modelId = button.data('model-id');
$.ajax({
method: 'post',
dataType: 'html',
url: 'new_customer.php',
data: {
'modelId': modelId,
'modalId': 'type3'
},
success: function (response, textStatus, jqXHR) {
modal
.find('.modal-padding')
.html(response);
},
error: function (jqXHR, textStatus, errorThrown) {
modal
.find('.modal-messages')
.removeClass('success')
.addClass('error')
.html('An error occurred during your request. Please try again, or contact us.');
}
});
});
$('#type3').on('hide.bs.modal', function (event) {
var modal = $(this);
modal.find('.modal-padding').html('');
modal
.find('.modal-messages')
.removeClass('success error')
.html('');
});
});
</script>
</head>
<body>
<button type="button" data-model-id="13" data-modal-type="type3" data-toggle="modal" data-target="#type3" class="modal_button customer_button right">
New Customer
</button>
<div class="modal" id="type3">
<div class="modal-content">
<div class="modal-title">
<h3>New Customer</h3>
</div>
<div class="modal-messages"></div>
<div class="modal-padding"></div>
</div>
</div>
</body>
</html>
new_customer.php
This page contains the form for adding a new customer into customers table.
<?php
$modelId = $_POST['modelId'] ?? NULL;
$modalId = $_POST['modalId'] ?? NULL;
?>
<script type="text/javascript">
$(document).ready(function () {
$('#saveCustomerButton').on('click', function (event) {
var form = $('#addCustomerForm');
var button = $(this);
var modalId = button.data('modal-id');
var modal = $('#' + modalId);
$.ajax({
method: 'post',
dataType: 'html',
url: 'add_customer.php',
data: form.serialize(),
success: function (response, textStatus, jqXHR) {
modal
.find('.modal-messages')
.removeClass('error')
.addClass('success')
.html('Customer successfully added.');
$('#resetAddCustomerFormButton').click();
},
error: function (jqXHR, textStatus, errorThrown) {
var message = errorThrown;
if (jqXHR.responseText !== null && jqXHR.responseText !== 'undefined' && jqXHR.responseText !== '') {
message = jqXHR.responseText;
}
modal
.find('.modal-messages')
.removeClass('success')
.addClass('error')
.html(message);
}
});
});
});
</script>
<style type="text/css">
#addCustomerForm {
padding: 20px;
}
</style>
<form id="addCustomerForm" action="" method="post">
<input type="hidden" id="modelId" name="modelId" value="<?php echo $modelId; ?>" />
<div class="form-group">
<label for="customerName">Name</label>
<input type="text" id="customerName" name="customerName" placeholder="Customer name">
</div>
<button type="button" data-modal-id="<?php echo $modalId; ?>" id="saveCustomerButton" name="saveCustomerButton" value="saveCustomer">
Save
</button>
<button type="reset" id="resetAddCustomerFormButton" name="resetAddCustomerFormButton">
Reset
</button>
</form>
add_customer.php
This page consists of code for handling the saving of the customer into the database.
<?php
require 'connection.php';
require 'InvalidInputValue.php';
use App\InvalidInputValue;
try {
$modelId = $_POST['modelId'] ?? NULL;
$customerName = $_POST['customerName'] ?? NULL;
// Validate the model id.
if (empty($modelId)) {
throw new InvalidInputValue('Please provide the model id.');
} /* Other validations here using elseif statements */
// Validate the customer name.
if (empty($customerName)) {
throw new InvalidInputValue('Please provide the customer name.');
} /* Other validations here using elseif statements */
/*
* Save the customer into db. On failure exceptions are thrown if and
* only if you are setting the connection options correspondingly.
* See "connection.php" for details.
*/
$sql = 'INSERT INTO customers (
model_id,
name
) VALUES (
?, ?
)';
/*
* Prepare the SQL statement for execution - ONLY ONCE.
*
* #link http://php.net/manual/en/mysqli.prepare.php
*/
$statement = mysqli_prepare($connection, $sql);
/*
* Bind variables for the parameter markers (?) in the
* SQL statement that was passed to prepare(). The first
* argument of bind_param() is a string that contains one
* or more characters which specify the types for the
* corresponding bind variables.
*
* #link http://php.net/manual/en/mysqli-stmt.bind-param.php
*/
mysqli_stmt_bind_param($statement, 'is', $modelId, $customerName);
/*
* Execute the prepared SQL statement.
* When executed any parameter markers which exist will
* automatically be replaced with the appropriate data.
*
* #link http://php.net/manual/en/mysqli-stmt.execute.php
*/
mysqli_stmt_execute($statement);
/*
* Close the prepared statement. It also deallocates the statement handle.
* If the statement has pending or unread results, it cancels them
* so that the next query can be executed.
*
* #link http://php.net/manual/en/mysqli-stmt.close.php
*/
mysqli_stmt_close($statement);
/*
* Close the previously opened database connection.
* Not really needed because the PHP engine closes
* the connection anyway when the PHP script is finished.
*
* #link http://php.net/manual/en/mysqli.close.php
*/
mysqli_close($connection);
} catch (InvalidInputValue $exc) {
/*
* Throw an error to be catched by the "error" callback of the ajax request.
* This can be achieved by sending a specific or a custom response header to the client.
*
* - Specific header: A header containing any already assigned status code.
* - Custom header: A header containing any NOT already assigned status code. This type of
* headers have the reason phrase "Unassigned" in the official HTTP Status Code Registry.
*
* #link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml HTTP Status Code Registry.
*/
header('HTTP/1.1 500 Internal Server Error', TRUE, 500);
echo $exc->getMessage();
exit();
} catch (Exception $exc) {
// For all other system failures display a user-friendly message.
header('HTTP/1.1 500 Internal Server Error', TRUE, 500);
echo 'An error occurred during your request. Please try again, or contact us.';
exit();
}
connection.php
<?php
/*
* This page contains the code for creating a mysqli connection instance.
*/
// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'root');
define('PASSWORD', 'root');
/*
* Enable internal report functions. This enables the exception handling,
* e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions
* (mysqli_sql_exception).
*
* MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
* MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings.
*
* #link http://php.net/manual/en/class.mysqli-driver.php
* #link http://php.net/manual/en/mysqli-driver.report-mode.php
* #link http://php.net/manual/en/mysqli.constants.php
*/
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
/*
* Create a new db connection.
*
* #see http://php.net/manual/en/mysqli.construct.php
*/
$connection = mysqli_connect(HOST, USERNAME, PASSWORD, DATABASE, PORT);
InvalidInputValue.php
This is a custom exception class. An exception of this type is thrown when posted user input values are invalid.
<?php
namespace App;
use Exception;
/**
* Custom exception. Thrown when posted user input values are invalid.
*/
class InvalidInputValue extends Exception {
}
Definition of "customers" table
I didn't create a models table, so there is no FK.
CREATE TABLE `customers` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`model_id` int(11) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
As I understood, you already have correct id value on the page. Looks like you get it from php script ($model['id']) and store in data-id of your button.
Also, looks like you're already able to get this id, when button is clicked. The further action depends on what exactly you are going to do.
$(".modal_button").click(function () {
var id = $(this).data("id"); //here you have an id
$(some_selector).html(id); //to put it inside elements html
$(another_selector).attr("placeholder", id); //to use it as placeholder (or any other attribute
});
This is for usage with js on the same page.
For POSTing it to the server:
$.ajax({
type: "POST",
url: your_url,
data: {
id: id
},
success: function(result) {
console.log(result);
//some actions after POSTing
}
});
On the server access it via $_POST["id"].
Why what you did was wrong?
Your POST request worked. You can check this using Chrome Dev Tools (Network tab). It posted to the same page and it's ok. The response of the server was an html page with id's built in modals, just as you wanted. But that was the response to the AJAX call and it had no influence to the page you already have loaded. Also, reloading the page you always had "ID not found" because reloading page doesn't make POST request.
Here is the general logic of what you need:
You already have id on the page. To transfer it to other elements on the same page, building into html markup and so on use JS.
To transfer data to the server (for SQL for example) use AJAX. You'd better create a separate file that would be an AJAX handler. That script will deal with POSTed id, make all required actions (like inserting new user to db) and send response (simple success-error code, string or JSON) back to the caller. Then, in AJAX.success you can handle the response and for example notify user if the operation was failed.
Hope this helps.
Your data parameter is wrong.
try this:
var idx = $(this).data("id");
$.ajax({
type: "POST",
url: '<?php echo doc_root('index.php'); ?>',
data: {id: idx}
}).done(function( data ) {
console.log( data );
});
I've been looking at this for a while and I think the major issue is the file i am referencing but I am not sure. I am working with a large amount of php files scattered all over the project folder but in the immediate folder I am working with files NavBar.php which is called using a require() statement in layout.php
here's the code I am having trouble with (btw all of this code is in NavBar.php):
<?php
$db=mysql_connect('localhost','root','');
if(!$db) {
die('Could not connect: '.mysql_error());
}
$connection_string=mysql_select_db('shipreq_stagetest',$db);
$selectSQL='SELECT * FROM color_patterns';
$queryset=mysql_query($selectSQL);
$num=mysql_num_rows($queryset);
if(0==$num) {
echo "No record";
exit;
} else {
while($row=mysql_fetch_assoc($queryset)) {?>
<li class= "list_item" onclick="<?php $indx = $_POST['pat_id'];?>">
<?php echo($row['name']);?></li><?php
}
}
?>
I know the sql calls are outdate and I should change it to PDOs I will make the switch as soon as I can figure out why the AJAX isn't working. this php code makes a db call and retrieves some data which displayed in the li (new li generated for each row in the table)(dropdown) and when a user clicks it I want to use this JS function to save the index of the clicked li to a php variable (hence the AJAX, I am really new to AJAX so I am having trouble figuring it out):
<script>
$(document).on('click', '.list_item', function() {
var indx = $(this).index();
$.ajax({ // add ajax code here
type: 'POST',
url: 'layout.phtml',
data: {pat_id: indx}, // send parameter like this
success: function(response) {
console.log(response);
}
});
});
</script>
I think the major issue might be the file I am referencing since NavBar.php is referenced by layout.phtml which is probably required by some other document in the hierarchy. this is the error I get in the console when I click on the li:
jquery.min.js:4 XHR finished loading: POST "http://localhost/shiprequest/layout.phtml".send # jquery.min.js:4ajax # jquery.min.js:4(anonymous function) # shiprequest?lang=en:235dispatch # jquery.min.js:3r.handle # jquery.min.js:3
shiprequest?lang=en:240
( ! ) Fatal error: Uncaught exception 'Zend_Acl_Exception' with message 'Resource 'shiprequest_layout.phtml' not found' in C:\sgm\library\Zend\Acl.php on line 364
( ! ) Zend_Acl_Exception: Resource 'shiprequest_layout.phtml' not found in C:\sgm\library\Zend\Acl.php on line 364
Call Stack
#TimeMemoryFunctionLocation
10.0006145888{main}( )..\index.php:0
20.0018168016require_once( 'C:\sgm\application\bootstrap.php' )..\index.php:5
30.11182860576Zend_Controller_Front->dispatch( )..\bootstrap.php:124
From the message error provided by you:
Uncaught exception 'Zend_Acl_Exception' with message 'Resource
'shiprequest_layout.phtml' not found
Validate if shiprequest_layout.phtml exist.
You probably wanted to write shiprequest_layout.html and not .phtml
<script>
$(document).on('click', '.list_item', function() {
var indx = $(this).index();
$.ajax({ // add ajax code here
type: 'POST',
url: 'layout.html', <------ here
data: {pat_id: indx}, // send parameter like this
success: function(response) {
console.log(response);
}
});
});
</script>
EDIT from Comments:
If you file is really layout.phtml, then your error is in file Acl.php (C:\sgm\library\Zend\Acl.php) at line 364. Line 364 is trying to find shiprequest_layout.phtml if this file do not exist, you will get this error.
You probably mean layout.phtml instead of shiprequest_layout.phtml
I am trying to do the following:
1: Load an XML file (with a list devices that has a static name, and a changing value and note) - this works
2: Load the XML (t=0) into varaiables for easy use in the HTML - this works
3: Load XML again (t=200ms) - this works (I think)
4: Check if any values have changed between the two XML's
5: If TRUE then update one or more <DIV id=>
Task 1: I guess I need to have the loadxml script run again whenever it is done or say every 200 ms
Task 2: I need to write and call a script that can update the <DIV id=>
I have made my code with only two parameters for easy understanding and put in comments where I guess I need to have something.
If this is a crazy overall architecture, please give me a direction to look to.
<?php
loadxml() ;
function loadxml() {
$feed_url = "demoxml.xml";
$xml = file_get_contents($feed_url);
$array = json_decode(json_encode((array)simplexml_load_string($xml)),1);
for ($id=1; $id<=157; $id++) {
//dynamic
$generation='new';
$hs3device_note[$id][$generation]= $array['device'][$id]['#attributes']['note'] ;
if ($hs3device_note[$id]['current'] != $hs3device_note[$id]['new']) { ;
$hs3device_note[$id]['current'] = $hs3device_note[$id]['new'] ;
//CALL SCRIPT (like ReplaceContentInContainer) TO UPDATE <DIV id = $id> WITH CONTENT $hs3device_note[$id]['new'])
} ;
$hs3device_value[$id][$generation]= $array['device'][$id]['#attributes']['value'] ;
if ($hs3device_value[$id]['current'] != $hs3device_value[$id]['new']) { ;
$hs3device_value[$id]['current'] = $hs3device_value[$id]['new'] ;
//CALL SCRIPT (like ReplaceContentInContainer) TO UPDATE <DIV id = $id> WITH CONTENT $hs3device_note[$id]['new'])
} ;
}
//MAKE loadxml() call it self or restart in 200 ms
} ;
<script type='text/javascript' src='jquery-1.7.2.js'>
function ReplaceContentInContainer() {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<DIV id="hs3device_note[34]['current']">...</DIV>
<DIV id="hs3device_value[34]['current']">...</DIV>
AJAX or Asynchronous JavaScript and XML is a method of sending requests to a server from JavaScript asynchronously (hence the name), with your question it would mean you can send a request to the server (at a specified interval) to see if some data has changed and if the PHP script evaluates true (ie it has) then it is sent back to the HTML page to replace the existing data that is being displayed.
function myXMLRequest() {
var request = $.ajax({
url: "script.php",
type: "POST",
data: { action:'testmyxml' },
dataType: "html"
});
request.done(function( msg ) {
setTimeout(function() {
myXMLRequest();
}, 5000);
if(msg != "") {
$( "#mydiv" ).html( msg );
}
});
request.fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
}
$(document).ready(function() {
myXMLRequest();
});
Reference: JQuery API documentation.
http://api.jquery.com/jquery.ajax/
the script.php is your php script that does all the logic, data is sent back using PHP's 'echo' command, if not don't echo anything... (you can test if msg is empty client side). msg will hold all the information that has been echoed by PHP in script.php and can be put into a div as shown in my example.