Passing an ID from foreach to modal - javascript

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 );
});

Related

Javascript window.addEventListener() fails to trigger after calling a jQuery .load() command to a new PHP page

I currently have a PHP based website with a mix of Javascript & jQuery. On this page, I have buttons to load a new page through a jQuery script that refreshes a div. This is so that only a portion of my page refreshes instead of the entire page, as this avoids reloading a series of other code that takes longer to load yet wouldn't need to be refreshed when navigating through my website.
On the 1st page, I have a window.addEventListener("load") that updates once the page fully loads. However, when I load the next page through my jQuery script, window.addEventListener("load") doesn't trigger.
I fully understand why this fails, since I'm technically only refreshing a portion of the page instead of the entire document. However, what sort of replacement would be needed for page2.php's window.addEventListener("load")?
Below is my code, thanks
page1.php
<!-- page1.php -->
<script>
function NewPage(userID, page) {
$(document).ready(function(){
$("#tabcontent").load("page2.php", {
userID: userID,
page: page
});
});
}
<script>
<?php
echo '<div id="tabcontent">
echo '<script type="text/javascript">
window.addEventListener("load", function() {
window.web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/<key>"))
try {
web3.eth.getBalance("'.$addrHash.'", function (err, result) {
if (result) {
document.getElementById("'.$id.'").innerHTML = web3.utils.fromWei(result, "ether");
}
})
} catch (err) {
document.getElementById("'.$id.'").innerHTML = "-";
}
})
</script>
<span style="font-weight:bold" id="'.$id.'"></span>';
<button onclick="NewPage(`'.$userID.'`, `.($page-1).`)">Previous Page</button>
<button onclick="NewPage(`'.$userID.'`, `.($page+1).`)">Next Page</button>
</div>';
?>
page2.php
<!-- page2.php -->
<?php
$userID = $_POST['userID'];
$page = $_POST['page'];
echo '<script type="text/javascript">
window.addEventListener("load", function() {
window.web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/v3/<key>"))
try {
web3.eth.getBalance("'.$addrHash.'", function (err, result) {
if (result) {
document.getElementById("'.$id.'").innerHTML = web3.utils.fromWei(result, "ether");
}
})
} catch (err) {
document.getElementById("'.$id.'").innerHTML = "-";
}
})
</script>
<span style="font-weight:bold" id="'.$id.'"></span>';
<button onclick="NewPage(`'.$userID.'`, `.($page-1).`)">Previous Page</button>
<button onclick="NewPage(`'.$userID.'`, `.($page+1).`)">Next Page</button>';
?>
Since jQuery is already being used, you should use the jQuery AJAX functionality to asynchronously load a portion of the page (this is not a page-load event - there is only one per page request).
I have attempted to simplify the code and organize it a little so that you may get rid of some of the PHP/HTML throughout the page an limit it to the beginning. Also, there is an always method to use if you wish, similar to a finally block in Java. This can be read about in the documentation link provided.
<script>
/**
* create JS vars for the user and current page.
*/
var userID = <?=$userID?>;
var curPage = <?=$page?>;
//-replaced ready event handler with short-hand.
$(function(e){
$("#tabcontent").load("page2.php", {
userID: userID,
page: page
}, function(e){
console.log('page2.php loaded.'); //<--new code here.
});
});
});
/**
* Create function to handle next content loading.
*/
function nextPage(e){
$.ajax({
url: 'page2.php',
dataType: 'html',
data: '{"userID":userID,"page":}'
}).done(function(data, textStatus, jqXHR){
/** Just for debugging to see what you have to utilize. Remove for production. */
console.log(data);
console.log(textStatus);
console.log(jqXHR);
/** end debugging. */
/** Load retrieved HTML into tab. */
$('#tabcontent').html(data);
}).fail(function(jqXHR, txtStatus, errorThrown){
/** display friendly error to user. */
$('#tabcontent').html('There has been an error. Please contact ......'));
/** show error message to console and any additional params jQuery provides to figure out issue. */
console.error("Error loading page2: " + txtStatus);
});
});
};
</script>
<button onclick="nextPage(<?=$page--?>)">Prev</button>
<button onclick="nextPage(<?=$page++?>)">Next</button>
</div>';
</script>
<div id="tabcontent">
</div>

toggle button coded with javascript in blade file cannot save status in database

in my blade file (written in PHP with a javascript section) I am trying to update an SQLite database field depending on the status of like, unlike button.
I tried to use some code I found on the pusher website (realtime-likes-laravel), but the snip that is supposed to update the DB is not working, the button changes status but it does not keep the status (when I refresh it the status is back to like and it does not keep unlike active).
I believe that the issue is the lack of connection with the DB, unfortunately, I am not a Java dev, so I am not sure how to do it properly.
This is my button in the Blade file
id }}">Like
This is my js section where I toggle
<script>
var toggleButtonText = {
Like: function(button) {
button.textContent = "Unlike";
},
Unlike: function(button) {
button.textContent = "Like";
}
};
var actOnPushB = function (event) {
var action = event.target.textContent;
toggleButtonText[action](event.target);
};
</script>
the page shows the button and the button toggles without any issue, but when I refresh the button is back to like status, also the DB is not updated.
I need the field likes_count in my database table answer to increment from 0 to 1 when liked and from 1 to 0 when unliked.
Ok, I worked with a friend who is a JS dev and he helped me to understand how to do the like / unlike buttons.
#section('js')
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
/* selector is like CSS selectors, it recalls the class automatically when it finds it in the code */
/*
* <div id="content"></div> --> $('#content')
* <input data-id="4" /> --> $('input[data-id="4"]')
*
* */
$('.like-button').click(function () {
var button = $(this);
var status = parseInt(button.attr('data-status'));
if(status==0) {
button.html('Unlike');
status = 1;
}
else{
button.html('Like');
status = 0;
}
$.ajax({
type: 'post',
url: 'toggleLike',
data: {answer_id:button.attr('data-id'), status:status},
success: function(data){
button.attr('data-status', status);
}
});
});
});
</script>
#endsection
in the PHP part, I added this to reference the page that will be used for the toggle
</a>
<button class="like-button" data-status="{{$answer->likes_count}}" data-id="{{ $answer->id }}">#if($answer->likes_count>0){{'Unlike'}}#else{{'Like'}}#endif</button>
</div>
then in the controller I added the function to handle the button toggling.
public function like(Request $request, $id)
{
$action = $request->get('action');
switch ($action) {
case 'Like':
Answer::where('id', $id)->increment('likes_count');
break;
case 'Unlike':
Answer::where('id', $id)->decrement('likes_count');
break;
}
return '';
}
the last part was to add to the web routes the following line :
Route::post('/question/toggleLike', 'AnswerController#toggleLike')->name('answers.toggleLike');
and that was it.
Do not judge if this code is useful or not, it was for homework so only the logged-in user can answer the questions, create the questions and like the answers he gave to his own question.

How to receive json from an array php in AJAX

I'm making a AJAX call and I'm trying to receive json from an array json_encode(), but doesn't seem to be working. Thanks for any help.
I'm not getting any errors and i've checked some other stackoverflow questions, but can't find a complete example.
The problem is i'm nothing it going in to the div (#form_response) when the ajax is called and its returning everything from results
The response I get using the code below is:
{"success":true,"error":false,"complete":"<div class=\"ser_mess\">success<\/div>","error_msg":{"empty":"<div class=\"ser_mess\">empty<\/div>"}}
HTML & AJAX:
<script type="text/javascript" src="js/jquery.js"></script>
<div class="" id="form_response"></div>
<form id="add_property_form" action="" method="POST">
<input type="text" name="input">
<button type="submit">Send</button>
</form>
<script type="text/javascript">
$("#add_property_form").submit(function(evt){
evt.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: 'thescript.php',
type: 'POST',
data: formData,
async: false,
cache:false,
contentType: false,
processData: false,
dataType: "json",
success: function (data) {
$('#form_response').html(data);
}
});
return false;
});
</script>
thescript.php
header('Content-Type: application/json');
$success = true;
$false = false;
$results = array(
'success' => $success,
'complete' => '<div class="ser_mess">success</div>',
'error' => $false,
'error_msg' => array('empty' => '<div class="ser_mess">empty</div>',)
);
if(empty($_POST['input']) ){
$results['error'];
$results['error_msg']['empty'];
}else{
$results['success'];
$results['complete'];
}
echo json_encode($results);
exit();
My testing steps with your code. Resolving problems.
If you are submitting the data with an ajax request, then you don't want to natively submit the form. So, use just a button of type "button", not of type "submit". Statements like evt.preventDefault(); and return false are correctly used only when the form should be natively submitted (e.g. not through a button of type "submit", or similar) and, for example, you are validating it. If the user input is not valid, then you apply such statements, so that you can stop the form from submitting.
Your ajax doesn't start, because it's not included into a $(document).ready(function () {...}.
I receive "TypeError: 'append' called on an object that does not implement interface FormData. Use var formData = $('add_property_form').serialize(); instead of var formData = new FormData($(this)[0]);.
The async:false property gave the warning: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user’s experience. For more help http://xhr.spec.whatwg.org/ jquery-3.2.1.min.js:4:15845". So, remove async. Also, you don't need cache, contentType, processData. Remove them.
Since, by setting dataType: "json", you are already telling the server that you are expecting JSON encoded data back from the server, you don't need to send the response header with header('Content-Type: application/json');. Remove it.
Use method: "post" instead of type: "post", because the latter is used only up to version 1.9.0 of jquery. Read the ajax specification.
Your php code inside the if statements was error-prone. I made my version out of it.
If you are receiving JSON encoded data from the server, you can not directly pass it as html content into a div. You must read its values separately and do something with them. In analogy: in php you can also not simply write echo $results, because then you would receive Notice: Array to string conversion. The same is with the client-side code.
test.php
<!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></title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#add_property_form").submit(function (evt) {
evt.preventDefault();
var formData = $('#add_property_form').serialize();
$.ajax({
url: 'thescript.php',
type: 'POST',
dataType: "json",
data: formData,
success: function (data, textStatus, jqXHR) {
var formResponse = $('#form_response');
var success = data.success;
var message = data.message;
if (success) {
formResponse.removeClass('error').addClass('success');
} else {
formResponse.removeClass('success').addClass('error');
}
formResponse.html(message);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
}
});
return false;
});
});
</script>
<style type="text/css">
.success,
.error {
max-width: 400px;
color: white;
margin-bottom: 15px;
}
.success {
background-color: green;
}
.error {
color: white;
background-color: red;
}
</style>
</head>
<body>
<div id="form_response" class="message"></div>
<form id="add_property_form" action="" method="POST">
<input type="text" name="input">
<button type="submit">Send</button>
</form>
</body>
</html>
thescript.php
<?php
if (empty($_POST['input'])) {
$results['success'] = false;
$results['message'] = 'No input value provided!';
} else {
$results['success'] = true;
$results['message'] = 'You provided the value ' . $_POST['input'];
}
echo json_encode($results);
exit();
Another example
Since you were looking for a complete example I took the liberty to create one for you.
The main point of it is to define an "error" callback for the ajax request. Because, when you throw errors, you actually want your ajax "error" callback take its role. For activating it, you just have to send a custom response header - having a status code of class "4xx: Client errors" - from the server (search.php) to the client (custom.js). Such a header is used like this: "Dear browser, I, the server, am sending you this response: 'HTTP/1.1 420 Please provide the city.'. As you see, its status code is 420, e.g. of class 4xx. So please be so kind and handle it in the 'error' callback of your ajax request". Here is the List ofStatus Codes.
You can run the code as it is. Create a folder in your document root, paste the files in it, then let test.php running.
test.php
<!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</title>
<!-- CSS resources -->
<link href="custom.css" type="text/css" rel="stylesheet" />
<!-- JS resources -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script src="custom.js" type="text/javascript"></script>
</head>
<body>
<div class="page-container">
<form class="user-input">
<div class="messages">
Here come the error/success messages
</div>
<div class="form-group">
<label for="city">City:</label>
<input type="text" id="city" name="city" placeholder="City">
</div>
<div class="form-group">
<button type="button" id="searchButton" name="submit" value="search">
Search
</button>
</div>
</form>
<div class="cities">
Here comes the list of the found cities
</div>
</div>
</body>
</html>
search.php
<?php
// Get the posted values.
$city = isset($_POST['city']) ? $_POST['city'] : '';
// Validate the posted values.
if (empty($city)) {
/*
* This custom response header triggers the ajax error because the status
* code begins with 4xx (which corresponds to the client errors). Here is
* defined "420" as the custom status code. One can choose whatever code
* between 401-499 which is not officially assigned, e.g. which is marked
* as "Unassigned" in the official HTTP Status Code Registry. See the link.
*
* #link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml HTTP Status Code Registry.
*/
header('HTTP/1.1 420 Please provide the city.');
exit();
} /* Other validations here using elseif statements */
/* The user input is valid. */
/*
* Perform the search operation in a database, for example, and get the data.
* Here just an array simulating a database result set with two records.
*/
$foundCities = [
[
'name' => 'Athens',
'isCapital' => 'is a capital',
],
[
'name' => 'Constanta',
'isCapital' => 'is not a capital',
],
];
// Print the response.
$response = [
'message' => 'Great. ' . count($foundCities) . ' cities were found.',
'cities' => $foundCities,
];
echo json_encode($response);
exit();
custom.js
$(document).ready(function () {
$('#searchButton').click(function (event) {
ajaxSearch();
});
});
function ajaxSearch() {
$.ajax({
method: 'post',
dataType: 'json',
url: 'search.php',
data: $('.user-input').serialize(),
success: function (response, textStatus, jqXHR) {
/*
* Just for testing: diplay the whole response
* in the console. So look unto the console log.
*/
console.log(response);
// Get the success message from the response object.
var successMessage = response.message;
// Get the list of the found cities from the response object.
var cities = response.cities;
// Display the success message.
displayMessage('.messages', 'success', successMessage);
// Display the list of the found cities.
$('.cities').html('');
$.each(cities, function (index, value) {
var city = index + ": " + value.name + ' (' + value.isCapital + ')' + '<br/>';
$('.cities').append(city);
});
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle the raised errors. In your case, display the error message.
handleAjaxError(jqXHR);
},
complete: function (jqXHR, textStatus) {
// ... Do something here, after all ajax processes are finished.
}
});
}
/**
* Display a user message.
*
* #param selector string The jQuery selector of a message container.
* #param type string The message type: success|danger|warning.
* #param message string The message text.
* #return void
*/
function displayMessage(selector, type, message) {
$(selector).html('<div class="message ' + type + '">' + message + '</div>');
}
/**
* Handle an error raised by an ajax request.
*
* If the status code of the response is a custom one (420), defined by
* the developer, then the corresponding error message is displayed.
* Otherwise, e.g. if a system error occurres, the displayed message must
* be a general, user-friendly one. So, that no system-related infos will be shown.
*
* #param jqXHR object The jQuery XMLHttpRequest object returned by the ajax request.
* #return void
*/
function handleAjaxError(jqXHR) {
var message = 'An error occurred during your request. Please try again, or contact us.';
if (jqXHR.status === 420) {
message = jqXHR.statusText;
}
displayMessage('.messages', 'danger', message);
}
custom.css
body {
margin: 0;
padding: 20px;
}
.page-container {
padding: 30px;
background-color: #f4f4f4;
}
.messages {
margin-bottom: 20px;
}
.message {
padding: 10px;
margin-bottom: 10px;
border: 1px solid transparent;
}
.success {
color: #3c763d;
border-color: #d6e9c6;
background-color: #dff0d8;
}
.danger {
color: #a94442;
border-color: #ebccd1;
background-color: #f2dede;
}
.warning {
color: #8a6d3b;
border-color: #faebcc;
background-color: #fcf8e3;
}
form {
width: 400px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: inline-block;
min-width: 40px;
}
button {
padding: 7px 10px;
margin: 10px;
display: block;
color: #fff;
font-size: 14px;
border: none;
background-color: #8daf15;
}
success: function (data) {
$('#form_response').html(data);
}
this block is your response handler - and data is the JSON object you're getting back from the AJAX call. if you want to display a particular attribute of your JSON object, you'll want to reference something like data.complete, which looks like a little bit of HTML, which you can then put into your div#form_response
success: function (data) {
$('#form_response').html(data.success);
}
you can access all of the object in the same way:
{"success":true,"error":false,"complete":"<div class=\"ser_mess\">success<\/div>","error_msg":{"empty":"<div class=\"ser_mess\">empty<\/div>"}}
so to get the html for the "empty" error message, you'd use
$('#form_response').html(data.error_msg.empty);
alternatively, if i misunderstand the question, if you want the RAW json to appear in div#form_response, you can convert the json object into a string:
json_string = JSON.stringify( data );
$('#form_response').html( json_string );
I am fairly confident this should work for you :)
Your HTML/JS file:
<script type="text/javascript" src="js/jquery.js"></script>
<div class="" id="form_response"></div>
<form id="add_property_form" action="" method="POST">
<input type="text" name="input">
<button type="submit">Send</button>
</form>
<script type="text/javascript">
$("#add_property_form").submit(function(evt){
evt.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: 'thescript.php',
type: 'POST',
data: formData,
async: false,
cache:false,
contentType: false,
processData: false,
dataType: "json",
success: function (data) {
var resultData = data.response_msg; // get HTML to insert
$('#form_response').html(resultData);
// You can also use data.status (= true or false), to let you know which HTML was inserted :)
}
});
return false;
});
</script>
your PHP file:
header('Content-Type: application/json');
// construct original array
$results = array(
'status' => false,
'response_msg' => ''
);
// analyze $_POST variables
if(empty($_POST['input'])){ // if input post is not empty:
$results['status'] = false;
$results['response_msg'] = '<div class="ser_mess">empty</div>';
}else{ // if input post is empty:
$results['status'] = true;
$results['response_msg'] = '<div class="ser_mess">success</div>';
}
echo json_encode($results); // encode as JSON
exit();

Joomla component Ajax call : Uncaught SyntaxError: Unexpected identifier

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>

AJAX post data to PHP file and redirect to the same file to echo post data

I have a php file with a bunch of <a></a> elements containing user names. Upon clicking one of these links, the link's data attributes are stored and posted to the second php file via AJAX. However, once I redirect to that file, the value I posted is not being displayed, instead I get the error: Undefined index userid.
Here's my code:
Index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Post Test</title>
</head>
<body>
User 1
User 2
User 3
User 4
User 5
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
$('.user-staff').on('click',function(){
var userid = $(this).data('user-id');
var renderView = $(this).data('render-view');
$.ajax({
url: "users.php",
type: "POST",
data: {userid:userid},
success: function(data, textStatus, jqXHR){
window.location = renderView;
},
error: function (jqXHR, textStatus, errorThrown){
alert('Error!')
}
});
});
</script>
</body>
</html>
Users.php
<?php
$userIdExchanged = $_POST['userid'];
echo '<h1>user profile page</h1>';
echo $userIdExchanged; //Nothing is outputted here.
?>
Yes thats really what happened, basically, first step, you sent an ajax request, sending that value user-id.
Then after that you redirect. This means that you have two separate requests.
The first request was successful. After redirection (here comes the second) your values aren't there anymore since the data on the first request did not persist.
I don't know why do you have to make an ajax request. Might as well submit the form normally.
But if you really want to stay on this course, on the first request (the ajax request), you could save it in the session.
So that value that you sent will be saved. Then after redirection, you still have it for access:
<script type="text/javascript">
// maybe you mean `.user-name` not `.user-staff`
$('.user-name').on('click',function(){
var userid = $(this).data('user-id');
var renderView = $(this).data('render-view');
$.ajax({
url: "users.php",
type: "POST",
data: { userid: userid, setid: true }, // add a flag
success: function(data, textStatus, jqXHR){
window.location = renderView;
},
error: function (jqXHR, textStatus, errorThrown){
alert('Error!')
}
});
});
</script>
Then in PHP:
<?php
session_start();
// if the set flag is used, set it
if(isset($_POST['setid'])) {
$_SESSION['userid'] = $_POST['userid'];
}
// if no flag is set, then this will just continue and echo the value currently set
$userIdExchanged = $_SESSION['userid'];
echo '<h1>user profile page</h1>';
echo $userIdExchanged;
?>
Your class name in the html tags is "user-name" but you are listening for clicks on a class name of "user-staff" in your .js. Unsure if that is just a typo...
<a href="#" class="user-name" ......
$('.user-staff').on('click',function(){....

Categories