Run PHP function without reloading doesnt work with AJAX - ajax

I know this question has been asked a lot, but I can't solve my problem.
I want to run the PHP function without reloading the page. Why does this not work? The php file is indexTest.php.
The page is just scrolling to the top and nothing works.
I am new to AJAX so I really dont know what to do.
HTML:
<script type="text/javascript">
function submitdata()
{
var nameForm=document.getElementById( "nameForm" );
var emailForm=document.getElementById( "emailForm" );
var messageForm=document.getElementById( "messageForm" );
$.ajax({
type: 'post',
url: 'indexTest.php',
data: {
name:nameForm,
email:emailForm,
message:messageForm
},
});
return false;
}
</script>
<form onsubmit="return submitdata()" method="POST" id="contactForm">
<input spellcheck="false" class="first" type="text" name="name" placeholder="name" id="nameForm">
<input spellcheck="false" class="first" type="text" name="email" placeholder="email" id="emailForm">
<textarea rows="8" spellcheck="false" class="last" type="text" name="message" placeholder="message" id="messageForm"></textarea>
<input type="submit" name="submit" value="" id="button">
</form>
PHP:
<?php
if(isset($_POST['submit'])){
$to = "*"; // this is your Email address
$from = $_POST['email']; // this is the sender's Email address
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Invalid email format";
};
$first_name = $_POST['name'];
$subject = "Form submission";
$subject2 = "Copy of your form submission";
$message = "Email from: " . $from . "\n\n" . $first_name . " wrote the following:" . "\n\n" . $_POST['message'];
$message2 = "Here is a copy of your message " . $first_name . "\n\n" . $_POST['message'];
$headers = "From:" . $from;
$headers2 = "From:" . $to;
mail($to,$subject,$message,$headers);
mail($from,$subject2,$message2,$headers2); // sends a copy of the message to the sender
echo '<script language="javascript">';
echo 'alert("message successfully sent")';
echo '</script>';
// You can also use header('Location: thank_you.php'); to redirect to another page.
}
?>

The problem is that you are posting through the form itself, when you actually want to post through AJAX. Essentially, because you are calling your JavaScript function in onsubmit, the JavaScript will get run in addition to the default form submission.
What you need to do is disable default form submission with e.preventDefault();, and then run your JavaScript instead:
$("#contactForm").submit(function(e) {
e.preventDefault();
submitdata();
});
Hope this helps! :)

Related

How to fix AJAX modal form in Laravel 5.3

I've upgraded my app from Laravel 4.2 to Laravel 5.3. On an index page listing citations, I have an AJAX modal form to edit or view the login credentials for the citation. This was working fine in Laravel 4.2, but I cannot for the life of me get it to work in 5.3. After about 5 hours Googling and trying different things, I thought I would post it here so that someone way more experienced than me can point me in the right direction.
Here's the link on the index page:
<a style="cursor: pointer; " title= "Login Credentials" data-loopback="cit-pg-1" data-citationid="1079" class="getCitationdetails"><span class="glyphicon glyphicon-lock " title="Login Credentials"></span></a>
And here's the JavaScript:
<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
var citationid = $(this).data('citationid');
var loopback = $(this).data('loopback');
$.ajax({
url : '/citation-password',
type:'post',
data : {citationid :citationid, loopback :loopback},
success:function(resp){
$('#AppendLoginDetails').html(resp);
$('#LoginCredentialsModal').modal('show');
$('.loadingDiv').hide();
},
error:function(){
alert('Error');
}
})
})
Here's my route:
Route::match(['get', 'post'], '/citation-password', 'CitationsController#citationpassword');
And here's the Controller method that generates the form on get and saves the data on post:
public function citationpassword()
{
if (Request::ajax()) {
$data = Request::all();
if (!$data['citationid']) {
return redirect('/citations')
->with('flash-danger', 'Missing citation id for Login credentials form!!');
}
// Save loopback variable if we have it in order to return user to the page where they came from; default return location is citations
$loopback = 'citations';
if (array_key_exists("loopback", $data)) {
$loopback = $data['loopback'];
}
$getcitationdetails = Citation::where('id', $data['citationid'])->select('id', 'site_id', 'username', 'password', 'login_email', 'login_notes')->first();
$getcitationdetails = json_decode(json_encode($getcitationdetails), true);
$getsitedetails = Site::where('id', $getcitationdetails['site_id'])->select(
'id',
'directory_username',
'directory_password',
'security_questions',
'email_account',
'email_account_password',
'email_account_name',
'google_user',
'google_pwd',
'name_of_google_account'
)->first();
$getsitedetails = json_decode(json_encode($getsitedetails), true);
$response ="";
$response .= '<form action="'.url('/citation-password').'" method="post">
<div class="modal-body">';
if (!empty($getsitedetails['directory_username'])) {
$response .= '<div class="form-group">
<label for="recipient-name" class="col-form-label">Default login credentials for this site:</label>
<p>Username: '.$getsitedetails['directory_username'].'
<br />Password: '.$getsitedetails['directory_password'].'
<br />Email account: '.$getsitedetails['email_account'].'
<br />Email password: '.$getsitedetails['email_account_password'].'
<br />Name on email account: '.$getsitedetails['email_account_name'].'
<br />Default security questions: '.$getsitedetails['security_questions'].'</p>
<p>Gmail account: '.$getsitedetails['google_user'].'
<br />Gmail password: '.$getsitedetails['google_pwd'].'
<br />Name on Gmail account: '.$getsitedetails['name_of_google_account'].'</p>
</div>';
}
$response .= '
<input type="hidden" name="_token" value="'.csrf_token() .'" />
<input type="hidden" name="citation_id" value="'.$data['citationid'].'" />
<input type="hidden" name="loopback" value="'.$loopback.'" />
<div class="form-group">
<label for="recipient-name" class="col-form-label">Username:</label>
<input type="text" class="form-control" name="username" value="'.$getcitationdetails['username'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Password:</label>
<input type="text" class="form-control" name="password" value="'.$getcitationdetails['password'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Login email used:</label>
<input type="text" class="form-control" name="login_email" value="'.$getcitationdetails['login_email'].'" autocomplete="off">
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Login notes:</label>
<textarea class="form-control" style="height:130px;" name="login_notes">'.$getcitationdetails['login_notes'].'</textarea>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success" id="success">Save</button>
<button type="button" class="btn btn-danger" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</form>';
return $response;
} else {
// The popup modal has posted back here; process the data
$data = Request::all();
// Handle & translate loopback; returning user to the page where they came from
$loopback = 'citations';
if ($data['loopback']) {
$loopback = $data['loopback'];
// Translate pages it came from
$trackLoopback = new trackLoopback();
$loopback = $trackLoopback->translate($loopback);
}
$updatecitation = Citation::find($data['citation_id']);
$updatecitation->username = $data['username'];
$updatecitation->password = $data['password'];
$updatecitation->save();
return redirect($loopback)
->with('flash-success', 'Login credentials have been updated successfully!');
}
}
In an effort to isolate the error, I even simplified the form in the controller like this:
public function citationpassword()
{
if (Request::ajax()) {
return '<p>This is the modal form!</p>';
} else {
// The popup modal has posted back here; process the data
$data = Request::all();
// Handle & translate loopback; returning user to the page where they came from
$loopback = 'citations';
if ($data['loopback']) {
$loopback = $data['loopback'];
// Translate pages it came from
$trackLoopback = new trackLoopback();
$loopback = $trackLoopback->translate($loopback);
}
$updatecitation = Citation::find($data['citation_id']);
$updatecitation->username = $data['username'];
$updatecitation->password = $data['password'];
$updatecitation->save();
return redirect($loopback)
->with('flash-success', 'Login credentials have been updated successfully!');
}
}
and also simplified the route to this:
Route::get('/citation-password', 'CitationsController#citationpassword');
but all I get when I click the link is a popup notice, "Error."
I'm not experienced with AJAX. How do I get the form to display in Laravel 5.3?
And/or, how can I change the JavaScript function so that it shows the actual error instead of the "Error" notice? (I tried a number of methods I found on StackOverflow to display errors but all of them resulted in NO error notice; just a blank page. And, I've not been successful at getting my Firefox debugger to show the errors either.)
Thanks!
The correct way to debug the JavaScript is to post the errors this way:
<script type="text/javascript">
$(document).on('click','.getCitationdetails',function(){
var citationid = $(this).data('citationid');
var loopback = $(this).data('loopback');
$.ajax({
url : '/citation-password',
type:'post',
data : {citationid :citationid, loopback :loopback},
success:function(resp){
$('#AppendLoginDetails').html(resp);
$('#LoginCredentialsModal').modal('show');
$('.loadingDiv').hide();
},
error: function(xhr, ajaxOptions, thrownError) {
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
})
})
Once you do so, you will see that the error has to do with missing CsrfToken for the form. [The actual error message is from the Laravel framework: Illuminate\Session\TokenMismatchException: in file /home/reviewsites/moxy53/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php on line 6] Since both the get and post verbs use the same route, Laravel is requiring the CsrfToken before the form with the Csrf field gets generated.
It is possible (but NOT recommended!) to exclude this route from CSRF protection by editing App\Http\Middleware\VerifyCsrfToken.php with the following exception:
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'/citation-password',
];
However, a much better approach is to add the token. It is correct that since you are using a post method to send the data values to the controller, you cannot use the controller to generate the token field in the form. Hence, the solution is to take the html out of the controller and put it in the blade. These lines:
$response .= '<form action="'.url('/citation-password').'" method="post">
<div class="modal-body">';
...
</div>
</form>';
should not be in the $response generated by the controller, but should instead be in the modal div in the blade itself. THEN, you can add the CSRF field in the blade thus:
<form action="{{url('/citation-password')}}" method="post">
{{ csrf_field() }}
<div class="modal-body" id="AppendLoginDetails">
</div>
</form>

Web form - bots getting past all checks when human cant.?

I have the following code, pretty standard - but it seems that the bots get by without even entering anything into the input fields! where as a normal person cannot since it checks upon submit, so I keep just getting empty emails.
Here is my code, if anyone has any ideas:
the javascript:
$('form.ajax').on('submit', function () {
if($(".field-b").val()) {
return false;
}
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
for(var property in data) {
if(data.hasOwnProperty(property)) {
if(data[property] == "") {
$('[name="' + property + '"]').parent().addClass("error");
return false;
}
}
}
$.ajax({
url: url,
type: type,
data: data,
success: function(response) {
$(".info,.ajax").hide();
$(".success-send").fadeIn(300);
return false;
}
});
return false;
});
The HTML:
<form class="ajax" action="../email.php" method="post"autocomplete="off">
<div class="form-field">
<input name="form_name" type="text" class="form-field-name">
<label>Your Name</label>
<div class="field-icon-name"></div>
</div>
<div class="form-field">
<input name="form_business" type="text" class="form-field-business">
<label>Business</label>
<div class="field-icon-business"></div>
</div>
<div class="form-field">
<input name="form_email" type="email" class="form-field-email">
<label>Email Address</label>
<div class="field-icon-email"></div>
</div>
<div class="form-field">
<input name="form_phone" type="text" class="form-field-phone">
<label>Phone #</label>
<div class="field-icon-phone"></div>
</div>
<div class="form-field special">
<input name="form_b" type="text" class="form-field-b">
<label>question</label>
</div>
<div class="form-field">
<textarea name="form_message"></textarea>
<label>Message</label>
<div class="field-icon-message"></div>
</div>
<button type="submit">Send Message</button>
</form>
And finally the PHP.
<?php
session_start();
$to = "myemail#domain.com";
$name = $_POST['form_name'];
$phone = $_POST['form_phone'];
$email = $_POST['form_email'];
$business = $_POST['form_business'];
$email = $_POST['form_email'];
$subject = 'Contact Form mattscorner';
$message = 'Name:'.$name.'\n Email + phone:'.$email.", ".$phone."\n Business: ".$business."\n\n".$message;
$headers = "From: $email\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-type: text/html; charset=iso-8859-1\n";
mail($to, $subject, $message, $headers);
if (mail($to, $subject, $message, $headers)) echo "mail sent"; else echo "mail NOT sent";
?>
It's pretty standard code I think, but I just cant seem to get the bots to even get blocked by the field requirements.
I literally get emails that are just:
Name:\n Email + phone:, Business:
There's a fundamental misunderstanding here. Bots don't run JavaScript, so none of that matters, and you're not doing the same validations on the server side, so they have no trouble getting by. Implement your validations in PHP too.
Also, you really need to do more validation for security anyway - your script is open to all kinds of vulnerabilities, and you're building malformed, non-compliant messages.
I suggest you use an email library such as PHPMailer, which you tagged this question with.

Joomla, Filezilla, Contact, changing automatic answer

I have a problem with my website. I made the lines where my problem lays thick(bottom). Here it is:
" **result = '<p style="color:white;"><?php echo** JText::_('VG_SK_CONTACT_SUCCESS'); ?></p>'; } else {
**result = '<p style="color:white;"><?php echo**
"
If I write between >< "Thank you for..." then it says in the automatic answer "Thank you for..." and there is another sentence which is maybe called by a function. I don't know very well programming, so can someone tell me maybe where I could find this data file, where I can change the automatic answer.
//CODE
// no direct access defined('_JEXEC') or die;
//library jimport('joomla.application.module.helper');
//vars //$class_sfx = htmlspecialchars($params->get('moduleclass_sfx')); $c_emailto = explode( '#', $params->get('emailto') ); $c_justdata = $params->get('justdata'); $c_justsocial = $params->get('justsocial');
echo '<div class="contactform"> <span class="error"></span> <span class="error"></span> <span class="error"></span> <span class="error"></span>
<form id="contactForm" method="post" action="">
<input type="hidden" name="emailto1" value="' . $c_emailto[0] . '" />
<input type="hidden" name="emailto2" value="' . $c_emailto[1] . '" />
<input type="text" name="contactName" id="contactName" class="requiredField" value="" placeholder="' . JText::_('VG_SK_CONTACT_NAME') . '" />
<input type="text" name="email" id="email" value="" class="requiredField email" placeholder="' . JText::_('VG_SK_CONTACT_EMAIL') . '" />
<textarea class="requiredField" name="comments" id="comments" placeholder="' . JText::_('VG_SK_CONTACT_MESSAGE') . '"></textarea>
<input type="hidden" name="submitted" id="submitted" value="true" />
<div class="clearfix"></div>
<button type="submit" name="submit" id="submitMsg" class="large_btn contact-btn">' . JText::_('VG_SK_CONTACT_SUBMIT') . '</button>
</form> <div id="note"></div>
</div>
<div class="contactinfo">
' . $c_justdata . ' ' . $c_justsocial . '
</div>'; ?>
<script> // mail-form jQuery(document).ready(function($){ $("#contactForm").submit(function(){ var str = $(this).serialize();
$.ajax({ type: "POST", url: "<?php echo JURI::base(); ?>modules/mod_circle_contact/ajax/send.php", data: str, success: function(msg){
$("#note").ajaxComplete(function(event, request, settings){ if(msg == 'OK') {
**result = '<p style="color:white;"><?php echo** JText::_('VG_SK_CONTACT_SUCCESS'); ?></p>'; } else {
**result = '<p style="color:white;"><?php echo** JText::_('VG_SK_CONTACT_FORGOT'); ?></p>'; }
$(this).html(result).fadeIn("slow"); $(this).html(result);
}); //alert(msg);
}
}); return false; }); }); </script>
//CODE
Thank you, greetings
You should change the strings inside the JText::_('VG_SK_CONTACT_FORGOT'); that is the VG_SK_CONTACT_FORGOT inside en-GB.tpl_vg_grettla.ini see this relevant answer: Customize Joomla Text

Joomla 2.5 Back-end Add custom Field using jquery and JFormField

I have fetched a problem to developing joomla(2.5) module. I have xml file which has custom field type addlocation.
<fieldset name="addLocations" label="Add Locations" addfieldpath="/modules /mod_pr_weather/elements">
<field type="addlocation" name="locations"></field>
</fieldset>
and has addlocation.php file,
<?php
defined('JPATH_BASE') or die;
jimport('joomla.form.formfield');
class JFormFieldAddlocation extends JFormField {
protected $type = 'Addlocations';
protected function getInput() {
$addFrom = '<div id="pr_maindiv"> <h1>'.JText::_('MOD_PR_WEATHER_HEADER_ADD_LOCATION').'</h1>'.$this->getForm("single").'</div>';
$addFromBlock = '<div id="pr_maindiv_b" style="clear:both;"><h1>'.JText::_('MOD_PR_WEATHER_HEADER_ADD_LOCATION').'</h1>'.$this->getForm("multi").'</div>';
$doc = JFactory::getDocument();
$doc->addScriptDeclaration('
jQuery(document).ready(function(){
jQuery("#pr_maindiv_b").css("display","none");
jQuery("#jform_params_slideshow_style").change(function(){
if(jQuery(this).val()==2){
jQuery("#pr_maindiv").css("display","none");
jQuery("#pr_maindiv_b").css("display","block");
}else{
jQuery("#pr_maindiv").css("display","block");
jQuery("#pr_maindiv_b").css("display","none");
}
});
});
');
return $addFrom . $addFromBlock;
}
private function getForm($type = 'single') {
$form_type_tooltip = 'class="hasTip" title="' . JText::_('MOD_PR_WEATHER_ADDLOCATION_TOOLTIP') . '"';
$from='';
if ($type=='single') {
$from = '<p><label'.$form_type_tooltip.'>'.JText::_('MOD_PR_WEATHER_ADDLOCATION_LABEL').'</label></p><p><input type="text" value="GEOLOCATION" placeholder="GEOLOCATION" name="single_location"/></p>
<p><input type="button" id="addMore" value="more"></p>';
}else{
$from = '<div style="clear:both;" id="first"><h3>Frist Block</h3><p><label'.$form_type_tooltip.'>'.JText::_('MOD_PR_WEATHER_ADDLOCATION_LABEL').'</label></p><p><input type="text" value="GEOLOCATION" placeholder="GEOLOCATION" name="first_block_loc"/></p>
<p><input type="button" id="addMoreFrist" value="more"></p></div>';
$from .= '<div style="clear:both;" id="second"><h3>Second Block</h3><p><label'.$form_type_tooltip.'>'.JText::_('MOD_PR_WEATHER_ADDLOCATION_LABEL').'</label></p><p><input type="text" value="GEOLOCATION" placeholder="GEOLOCATION" name="second_block_loc"/></p>
<p><input type="button" id="addMoreSecond" value="more"></p></div>';
$from .= '<div style="clear:both;" id="third"><h3>Third Block</h3><p><label'.$form_type_tooltip.'>'.JText::_('MOD_PR_WEATHER_ADDLOCATION_LABEL').'</label></p><p><input type="text" value="GEOLOCATION" placeholder="GEOLOCATION" name="third_block_loc"/></p>
<p><input type="button" id="addMoreThird" value="more"></p></div>';
$from .= '<div style="clear:both;" id="fourth"><h3>Fourth Block</h3><p><label'.$form_type_tooltip.'>'.JText::_('MOD_PR_WEATHER_ADDLOCATION_LABEL').'</label></p><p><input type="text" value="GEOLOCATION" placeholder="GEOLOCATION" name="fourth_block_loc"/></p>
<p><input type="button" id="addMoreFourth" value="more"></p></div>';
}
return $from;
}
}
And js file for button type triggering:
jQuery("#addMore").click(function(){
jQuery("#pr_maindiv").append("<p style='clear:both;'><input type='text' value='GEOLOCATION' placeholder='GEOLOCATION' name='single_location[]'/></p>");
});
jQuery("#addMoreFrist").click(function(){
jQuery("div#first").append("<p style='clear:both;'><input type='text' value='GEOLOCATION' placeholder='GEOLOCATION' name='first_block_loc[]'/></p>");
});
jQuery("#addMoreSecond").click(function(){
jQuery("div#second").append("<p style='clear:both;'><input type='text' value='GEOLOCATION' placeholder='GEOLOCATION' name='second_block_loc[]'/></p>");
});
jQuery("#addMoreThird").click(function(){
jQuery("div#third").append("<p style='clear:both;'><input type='text' value='GEOLOCATION' placeholder='GEOLOCATION' name='third_block_loc[]'/></p>");
});
jQuery("#addMoreFourth").click(function(){
jQuery("div#fourth").append("<p style='clear:both;'><input type='text' value='GEOLOCATION' placeholder='GEOLOCATION' name='fourth_block_loc[]'/></p>");
});
When button type click event occur, perfectly append into back-end form. But when save click, every xml field type value saved, but custom fields types do not saved into database params column. WHY? If my question is not clear, then please inform me to upload full file.
Thanks.
Joomla will only store results coming from an input field with the name you provide in your xml definition: thus your jquery should bind to change or forms' submit and concat / join the values you add and store those in a field named "location". Onload, you should have the reverse i.e. populating custom fields based on the value of location (this can be achieved easily with php).
If you will set the field name as name="jform[first_block_loc]" in the addlocation.php while defining the fields then it must store the value in the params column..

CodeIgniter POST variables

Anyone know why:
class Booking extends Controller {
function booking()
{
parent::Controller();
}
function send_instant_to_paypal()
{
print_r($_POST);
echo '<hr />';
print_r($this->input->post());
echo '<hr />';
$id_booking = $this->input->post('id_booking');
$title = $this->input->post('basket_description');
$cost = ($this->input->post('fee_per_min') * $this->input->post('amount'));
echo $id_booking;
echo $title
echo $cost
}
}
Will echo post variables in CI for $_POST
but NOT for $this->input->post();?
I've got
$this->input->post() in use and working on a search page elsewhere in the site... but on this page, it's not working..
here's my form...
<form id="add_funds" action="' . site_url('booking/send_instant_to_paypal') . '" method="post">
<input type="text" name="amount" id="amount" value="" />
<input type="hidden" name="id_booking" id="id_booking" value="0" />
<input type="hidden" name="basket_description" id="basket_description" value="Adding Credit" />
<input type="hidden" name="fee_per_min" id="fee_per_min" value="' . $fee_per_min . '" />
<input type="submit" value="Add to basket" />
</form>
It's mental ;-p
Anyone spot anything obviously stupid I'm missing?
You most likely have XSS or CSRF enabled and it will prohibit (guessing here) Paypal to get those details back to you.
This is typical of CodeIgniter, and there are some work arounds like excluding CSRF for certain controllers (via config or hook).
If you give some more details on where the POST is coming from I can answer a bit clearly.
edit
could be that you are calling $this->input->post() incorrectly? I know that CI2.1 added support for $this->input->post() to return the full array, but until this point you had to explicitly define the post variable you wanted ala:
$user = $this->input->post('username');
I resolved the issue with excluding CSRF protection for that particular method
you can add this code in application/config/config.php
if(stripos($_SERVER["REQUEST_URI"],'/Booking/send_instant_to_paypal') === FALSE)
{
$config['csrf_protection'] = TRUE;
}
else
{
$config['csrf_protection'] = FALSE;
}
The only thing I can think of right now is that you maybe did not load the form helper, but I'm not sure if it's being used for that.
you can do this in the /config/autoload.php
I for example have this:
$autoload['helper'] = array('url', 'form', 'html', 'site_helper', 'upload_helper');
you can also load it in your function itself as follow:
function send_instant_to_paypal()
{
$this->load->helper('form');
print_r($_POST);
echo '<hr />';
print_r($this->input->post());
echo '<hr />';
$id_booking = $this->input->post('id_booking');
$title = $this->input->post('basket_description');
$cost = ($this->input->post('fee_per_min') * $this->input->post('amount'));
echo $id_booking;
echo $title
echo $cost
}

Resources