CodeIgniter ajax form validation not showing any message on screen - php

I'd like some help please.
I'm having a form placed inside a bootstrap modal window.
<div class="modal-content">
<div class="modal-body">
<div id="ajaxResults"></div>
<?php echo form_open('controller-name/form-process'), array('id' => 'modal-form'); ?>
<input type="hidden" name="title" id="hid-title" />
<div class="form-group">
<?php echo form_input('first_name', set_value('first_name', $this->input->post('first_name')), 'id="first-name" class="form-control" placeholder="First name"'); ?>
</div>
<div class="form-group">
<?php echo form_input('last_name', set_value('last_name', $this->input->post('last_name')), 'id="last-name" class="form-control" placeholder="Last name"'); ?>
</div>
<div class="form-group">
<?php echo form_input('email', set_value('email', $this->input->post('email')), 'id="email" class="form-control" placeholder="Email"'); ?>
</div>
<div class="form-group">
<?php echo form_input('company', set_value('company', $this->input->post('company')), 'id="company" class="form-control" placeholder="Company"'); ?>
</div>
<?php echo form_close(); ?>
</div><!-- /.modal-body -->
<div class="modal-footer">
<button type="button" class="btn btn border-black" data-dismiss="modal">Close</button>
<button type="button" class="btn btn border-theme" id="form-submit-btn">Submit form</button>
</div><!-- /.modal-footer -->
</div><!-- /.modal-content -->
When I click the Submit the Form button I'm sending an ajax request to my form_process controller where I do the form validation. Here's my code for the form_process function and the ajax script
public function form_process() {
if ($this->input->post()) {
$rules = array(
'first_name' => array(
'field' => 'first_name',
'label' => 'First name',
'rules' => 'required|trim|min_length[2]',
),
'last_name' => array(
'field' => 'last_name',
'label' => 'Last name',
'rules' => 'required|trim|min_length[2]',
),
'email' => array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required|trim|valid_email',
),
'company' => array(
'field' => 'company',
'label' => 'Company',
'rules' => 'required|trim',
),
);
$this->load->library('form_validation');
$this->form_validation->set_rules($rules);
// validate the form
if ($this->form_validation->run()) {
$response = array(
'status' => '200',
'message' => 'Thank you! We have sent an email to ' . $this->input->post('email') . ' to get your white paper.',
);
} else {
$response = array(
'status' => '400',
'message' => validation_errors(),
);
}
// return the result of the form process
$this->output->set_status_header($response['status'])->set_content_type('application/json', 'utf-8')
->set_output(json_encode($response, JSON_PRETTY_PRINT))->_display();
exit();
}
The ajax script looks like this
$('#myModal').on('show.bs.modal', function (event) {
$('#modal-form').show();
$('#ajaxResults').removeClass('alert alert-success alert-error');
// Button that triggered the modal
var button = $(event.relatedTarget);
// Extract info from data-* attributes
var recipient = button.data('whatever');
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this);
modal.find('.modal-title').html('New message to <br/>' + recipient);
modal.find('.modal-body input[type=hidden]').val(recipient);
// submit the form
$('#form-submit-btn').on('click', function (event){
event.preventDefault();
var url = $('#modal-form').attr('action');
// send ajax request
$.ajax({
url: url,
type : 'POST',
data : {
'first_name' : $('#first-name').val(),
'last_name' : $('#last-name').val(),
'email' : $('#email').val(),
'company' : $('#company').val(),
'title' : $('#hid-title').val(),
},
dataType: 'json',
success : function(response) {
alert(response.message);
// console.log(response.message);
$('#ajaxResults').removeClass('alert alert-success alert-error');
if (response.status == 200) {
$('#modal-form').hide();
$('#ajaxResults').addClass('alert alert-success').html(response.message);
alert('AAAAAAAAAAAAAAAAAAAAAAAAAAAA');
}
if (response.status == 400) {
$('#modal-form').show();
$('#ajaxResults').addClass('alert alert-error').html(response.reason);
alert('BBBBBBBBBBBBBBBBBBBBBBBBBBBB');
}
},
error: function(response){
// code ...
$('#ajaxResults').removeClass('alert alert-success alert-error');
if (response.status == 200) {
$('#modal-form').hide();
$('#ajaxResults').addClass('alert alert-success').html(response.message);
alert('CCCCCCCCCCCCCCCCCCCCCCCCCCC');
}
if (response.status == 400) {
$('#modal-form').show();
$('#ajaxResults').addClass('alert alert-error').html(response.reason);
alert('DDDDDDDDDDDDDDDDDDDDDDDDDDDD');
}
}
});
});
});
EDIT I did an update on my ajax script and placed some alert messages, as you can see. When I click the submit button without submitting the form ( so there are errors), the alert DDDDDDD pops up.
When I fill all fields and submit the form the alert CCCCCCC pops up (!!!). In addition the ajaxResults div gets the .alert and .allert-success classes, but still can't see any message.
Any ideas what I'm doing wrong ?
Additional question: Is the error: function(response) used to show the the case where validation fails ?
I have also tried to move the validation errors inside this function and keep on success : function(response) only the success submition of the form, but still no luck.

I can see you are not parsing the data properly
example : in alert('DDDDDDDDDDDDDDDDDDDDDDDDDDDD'); line
before appending data to your ajaxResults you need to convert data Properly
response.responseText => will give you json string .
JSON.parse => will convert string to JSON Obj so that you can
use it like .variableName
Please add the following code before your
$('#ajaxResults').addClass('alert alert-error').html(response.reason);
add following line
var mess = JSON.parse(response.responseText).message;
replace response.reason to mess it should show you error Messages
Please mark it as answer if it works
full Code :
if (response.status == 400) {
$('#modal-form').show();
var mess = JSON.parse(response.responseText).message;
$('#ajaxResults').addClass('alert alert-error').html(mess);
alert('DDDDDDDDDDDDDDDDDDDDDDDDDDDD');
}
working

If it takes you to the error part, then you must use something like this to catch it:
,
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError) ; // or alert(xhr.responseText);
$('#ajaxResults').addClass('alert alert-error').html(thrownError) ;
}
And if the ajax call is successful, something like this:
,
succes: function(data, status, jqXHR){
if (status == 200) {
$('#modal-form').hide();
$('#ajaxResults').addClass('alert alert-success').html(response.message);
alert(data);
}
}

The "problem" was this output->set_status_header($response['status']) the request was always successful, but setting a header to 400 messed up the functionality.
I removed this piece of code and now works fine! However I still needed to add the
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError) ; // or alert(xhr.responseText);
$('#ajaxResults').addClass('alert alert-error').html(thrownError) ;
}
to get any errors in cases that the request fail.

Related

Codeigniter 4 reuse of CSRF token in AJAX modal

Scenario:
I am developing CMS system and I wan to add some categories to the objects (pages, posts, media etc.). In my view, to save a new category I use HTML form placed in Bootstrap modal which is sent via AJAX to my controller. The CSRF protection is enabled on the entire site.
While sending the data for the first time, I pass the CSRF token name and hash via form. Once being processed by PHP code in controller, I want to pass CSRF values in the response so I will be able to "re-use" the form in the modal (e.g. display error messages or/and create another category).
Yet, I am not able to access the get_csrf_token_name() and get_csrf_hash() methods to pass values back to the view.
In my view admmin/category/create.php:
...
<!-- CREATE CATEGORY MODAL MODAL -->
<div class="modal" id="createCategory" tabindex="-1">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Nová kategorie</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Zavřít"></button>
</div>
<div class="modal-body">
<form action="" method="post" id="createCategoryForm">
<input type="hidden" value="<?= csrf_hash(); ?>" name="<?= csrf_token(); ?>" id="csrf">
<div class="form-group mb-3">
<label for="title" class="form-label">Název kategorie</label>
<input type="text" class="form-control" name="title" id="title" value="">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" id="createCategoryConfirm">Vytvořit novou kategorii</button>
</form>
</div>
</div>
</div>
</div>
...
<script>
$('#head').on('click', '.create', function() {
$('#createCategory').modal('show');
$('#createCategoryForm').attr('action', '<?= base_url(); ?>/admin/category/create');
$('#createCategoryConfirm').click(function(e) {
e.preventDefault();
var url = $('#createCategoryForm').attr('action');
var csrfElement = $('#csrf');
var csrfName = csrfElement.attr('name');
var csrfHash = csrfElement.attr('value');
var categoryTitle = $('input[name=title]').val();
var data = {
[csrfName]: csrfHash,
'title': categoryTitle
};
console.log(data);
$.ajax({
type: 'ajax',
method: 'POST',
url: url,
data: data,
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
headers: {'X-Requested-With': 'XMLHttpRequest'},
success: function(result) {
console.log(result);
},
error: function(result) {
console.log(result);
},
});
});
});
</script>
In my controller Category.php:
<?php
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
use App\Models\CategoryModel;
use CodeIgniter\I18n\Time;
class Category extends BaseController {
protected $model;
protected $validator;
protected $security;
public function __construct() {
$this->model = new CategoryModel();
$this->validation = \Config\Services::validation();
$this->security = \Config\Services::security();
helper(['form', 'date', 'url']);
}
...
public function create() {
$response = [];
// This part of code returns error
//
// $response['csrf'] = array(
// 'name' => $this->security->get_csrf_token_name(),
// 'hash' => $this->security->get_csrf_hash()
// );
$response['security'] = $this->security;
if ($this->request->isAJAX()) {
$newCategory = [
'title' => $this->request->getVar('title'),
'slug' => url_title($this->request->getVar('title')),
'author' => session()->get('id'),
'created_at' => Time::now('Europe/Prague')->toDateTimeString(),
'updated_at' => Time::now('Europe/Prague')->toDateTimeString(),
'parent' => '0'
];
$this->validation->run($newCategory, 'categoryRules');
if (!empty($this->validation->getErrors())) {
$this->model->save($newCategory);
$response['errors'] = $this->validation->getErrors();
echo json_encode($response);
} else {
$this->model->save($newCategory);
$response['success'] = 'New category was created';
echo json_encode($response);
}
}
}
...
In the browser console, the AJAX response is POST http://localhost/admin/category/create 500 (Internal Server Error) with full response:
code: 500
file: "D:\Web\XAMPP\htdocs\lenka\app\Controllers\Admin\Category.php"
line: 38
message: "Call to undefined method CodeIgniter\Security\Security::get_csrf_token_name()"
title: "Error"
Could anyone please see the issue here? Is there any good solution on how to reuse CSRF tokens in CI4? I tried set config values of CSRF regenerate both to true and false, with no effect.
update this line cod in .ENV
or
app/config/security
CSRF Regenerate = false

LARAVEL - Missing required parameters

hi im new to coding and ive been watching this youtube tutorial about a simple server side processing crud and datatable in laravel and im getting this error which i have no idea why im getting it.
I am trying to create an update function to my code but cant cuz of this error. I have a feeling this is because of my update url but im using the same syntax in the tutorial so can you god tier people help me.
Missing required parameters for [Route: Clients.update] [URI:
Clients/{Client}]. (View:
C:\xampp\htdocs\project\resources\views\clients\clients.blade.php)
this is my view code
<div id="formmodal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Client Form</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>{{-- header --}}
<div class="modal-body">
<span class="result" id="result"></span>
<form method="post" id="client_form" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="client_name">Name</label>
<input type="text" class="form-control" name="client_name" id="client_name" placeholder="Enter Name">
</div>
<div class="form-group">
<label for="client_address">Addres</label>
<input type="text" class="form-control" name="client_address" id="client_address" placeholder="Enter Addres">
</div>
<div class="form-group">
<label for="client_date">Birth Date</label>
<input type="date" class="form-control" name="client_bdate" id="client_bdate">
</div>
<div class="modal-footer">
<input type="text" name="action" id="action">
<input type="text" name="hidden_id" id="hidden_id">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" name="savebtn" id="savebtn" value="Add">
</div>
</form>
</div>
</div>
</div>
</div>
$('#client_form').on('submit', function(event){
event.preventDefault();
var url;
if($('#action').val() == 'Add')
{
url = "{{ route('Clients.store') }}";
}else{
url = "{{ route('Clients.update') }}";
}
$.ajax({
url: url,
method: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
dataType: "json",
success:function(data)
{
var html = '';
if(data.errors)
{
html = '<diV class="alert alert-danger">';
for(var count = 0; count < data.errors.length; count++)
{
html += '<p>' + data.errors[count] + '</p>';
}
html += '</div>';
}
if(data.success)
{
alert("add");
html = '<diV class="alert alert-success">' + data.success + '</div>';
$('#client_form')[0].reset();
$('#table_id').DataTable().ajax.reload();
}
$('#result').html(html);
}
})
});
my controller code
public function update(Request $request)
{
$rules = array(
'client_name' => 'required',
'client_address' => 'required',
'client_bdate' => 'required'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
{
return response()->json(['errors'=>$error->errors()->all()]);
}
$form_data = array(
'client_name' => $request->client_name,
'client_address' => $request->client_address,
'client_bdate' => $request->client_bdate
);
Clients::find($request->hidden_id)->update($form_data);
return response()->json(['success' => 'Data Updated']);
}
Edit...
My route
Route::resource('/Clients', 'clientsCont');
In your controller you are missing second parameter.
So try like this:
public function update(Request $request, Client $client)
{
$rules = array(
'client_name' => 'required',
'client_address' => 'required',
'client_bdate' => 'required'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
{
return response()->json(['errors'=>$error->errors()->all()]);
}
$form_data = array(
'client_name' => $request->client_name,
'client_address' => $request->client_address,
'client_bdate' => $request->client_bdate
);
// You should get your client in variable $client
//Clients::find($request->hidden_id)->update($form_data);
$client->update($form_data);
return response()->json(['success' => 'Data Updated']);
}
Also note if you want to your code look simplier you can validate your request like this:
public function update(Request $request, Client $client)
{
$request->validate([
'client_name' => 'required',
'client_address' => 'required',
'client_bdate' => 'required'
])
$client->update($form_data);
return response()->json(['success' => 'Data Updated']);
}
You can read more here.
Good luck!
In your routes file remove the {} from Clients/{Client} or preferably change it to: Clients/update, when you put {} around some text, you are binding some parameter (actually Eloquent Model), and you should provide it (provide the ID) when you call the route.
Read more Laravel Documentations
Firstly, let's put certain conventions in place.
Change your route definition to
Route::resource('clients', 'ClientsCont');
By convention, controller names should be camel case and start with a capital letter. The route names are usually lower case.
Next, ensure that your controller file is correctly named ClientsCont.php and also the class name should be ClientsCont. Finally, you have to provide a second parameter to your update() method to hold the client object to update.
ClientsCont.php
namespace App\Http\Controllers;
use App\Client;
class ClientsCont extends Controller
{
// class definition
public function update(Request $request, Client $client)
{
$rules = array(
'client_name' => 'required',
'client_address' => 'required',
'client_bdate' => 'required'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
{
return response()->json(['errors'=>$error->errors()->all()]);
}
$form_data = array(
'client_name' => $request->client_name,
'client_address' => $request->client_address,
'client_bdate' => $request->client_bdate
);
$client->update($form_data);
return response()->json(['success' => 'Data Updated']);
}
}
Now, setup your Ajax request properly.
$('#client_form').on('submit', function(event){
var url;
if($('#action').val() == 'Add')
{
url = "{{ route('clients.store') }}";
}else{
url = "{{ route('clients.update') }}";
}
$.ajax({
url: url,
method: "POST",
data: new FormData(this),
cache: false,
dataType: "json",
success:function(data)
{
var html = '';
if(data.errors)
{
html = '<diV class="alert alert-danger">';
for(var count = 0; count < data.errors.length; count++)
{
html += '<p>' + data.errors[count] + '</p>';
}
html += '</div>';
}
if(data.success)
{
alert("add");
html = '<diV class="alert alert-success">' + data.success + '</div>';
$('#client_form')[0].reset();
$('#table_id').DataTable().ajax.reload();
}
$('#result').html(html);
}
})
return false;
});
Usually using return false; is the preferred way for stopping default event action and propagation.
[return false;] Usually seen in jQuery code, it Prevents the browsers default behaviour, Prevents the event from bubbling up the DOM, and immediately Returns from any callback.
See this medium write-up for full details.
Also, from your code, certain of your ajax settings are unnecessary and should be omitted so that their default values are used. These default values are usually sufficient for most forms.
For instance, using jQuery Ajax setting of processData: false disables processing the form data and uses the toString() method of the object to form the request data string.
When you set data to a general object other than a string with processData set to false jQuery doesn't process the object. The object is passed to the Ajax call exactly as it is and used as if it was a String. This by default calls the toString method and sends the result to the sever as the data in the Ajax request.
See this for full description. Be sure you need this setting or you discard it all together.
Another Ajax setting you probably need to discard is contentType: false, except you have a good reason for setting it.

I got "timeout-or-duplicate" error using ReCaptcha v3

I got a contact form on my website on Laravel and I'd like to place a ReCaptcha v3 but for now the result I got from the verification is the error "timeout-or-duplicate".
Can you help me from A to Z ? I don't know where to go...
My head :
<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute('My_Site_Key', { action: 'contact' }).then(function (token) {
var recaptchaResponse = document.getElementById('recaptchaResponse');
recaptchaResponse.value = token;
});
});
</script>
The contact form :
<form action="{{ route('contact.post') }}" id="contact-form" method="post" name="contactForm">
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
<input type="hidden" name="recaptcha_response" id="recaptchaResponse">
<fieldset>
<div class="col-sm-12">
<input id="name" name="name" placeholder="Nom*" type="text">
</div>
<div class="col-sm-12">
<input id="email" name="email" placeholder="Email*" type="text">
</div>
<div class="col-sm-12">
<input id="object" name="object" placeholder="Objet*" type="text" autocomplete="off">
</div>
<div class="col-xs-12">
<textarea cols="5" id="message" name="message" placeholder="Votre message...*"></textarea>
</div>
<div class="col-xs-12">
<button class="submit active" id="contact-submit">ENVOYER</button>
</div>
<div class="error col-xs-12">
<h3></h3>
</div>
<div class="success col-xs-12">
<h3>Merci ! Votre message a été envoyé !</h3>
</div>
</fieldset>
</form>
Route:
Route::post('/contact', array('as' => 'contact.post', 'uses' => 'ContactController#send'));
The Contact Controller :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
public function send() {
$info = array(
'name' => Input::get('name'),
'email' => Input::get('email'),
'object' => Input::get('object'),
'message' => Input::get('message')
);
if($info['name'] == "" || $info['email'] == "" || $info['object'] == "" || $info['message'] == "") {
return json_encode(['response' => 'Tous les champs doivent être remplis !']);
}
if(!filter_var($info['email'], FILTER_VALIDATE_EMAIL)) {
return json_encode(['response' => 'Vous devez rentrer une adresse e-mail valide !']);
}
$ip = Request()->ip();
// Build POST request:
$recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify';
$recaptcha_secret = 'My_Secret_Key';
$recaptcha_response = $_POST['recaptcha_response'];
// Make and decode POST request:
$recaptcha = file_get_contents($recaptcha_url . '?secret=' . $recaptcha_secret . '&response=' . $recaptcha_response);
$recaptcha = json_decode($recaptcha);
// Take action based on the score returned:
if ($recaptcha->score < 0.5) {
return json_encode(['response' => 'Vous êtes considéré comme Bot/Spammer !', 'score' => $recaptcha->score]);
}
Mail::send(['email.html.contact', 'email.text.contact'], ['info' => $info, 'ip' => $ip], function($message) use ($info) {
$message->to('contact#bryangossuin.be')->subject('Bryan Gossuin | Formulaire de contact');
$message->replyTo($info['email'], $info['name']);
});
return json_encode(['response' => 'success','']);
}
}
Finaly the javascript
$('#contact-form').on('submit', function(e) {
e.preventDefault();
swal({
title: "Souhaitez-vous vraiment envoyer ce mail ?",
icon: "warning",
buttons: {
cancel: {
text: "Annuler",
value: false,
visible: true,
closeModal: true,
},
confirm: "Envoyer",
}
})
.then((value) => {
if (value) {
$.ajax({
method: "POST",
url: "contact",
cache: false,
data: $(this).serialize(),
dataType: 'json',
success: function(json) {
console.log(json.score);
if (json.response == 'success') {
$('#contact-form').trigger("reset");
swal("E-mail envoyé", "Merci de votre demande !", "success");
} else {
swal("Erreur !", json.response, "error");
}
}
}
)
}
});
});
The output I got from google is
{
"success": false,
"error-codes": [
"timeout-or-duplicate"
]
}
and I expect it to be
{
"success": true,
"score" : x,
"error-codes": '',
}
I guess the problem is because the « method post » is used two times because when I Check directly
On the API Google to verify the user token it show le thé code but right after I refresh the page it show me « timeout or duplicate » but I dont know how to fix this
I got this from people double clicking the submit button on the form.
As stated in the documentation this error is caused by:
Validity time of the token expired (After you get the response token, you need to verify it within two minutes)
Token has been used previously. To confirm that, log the token value before is used (error log, local file, whatever)
My resolution for 1, set an interval that calls the set token function, so it is refreshed every 2 minutes.
$(document).ready(function() {
SetCaptchaToken();
setInterval(function () { SetCaptchaToken(); }, 2 * 60 * 1000);
});
Resolution for 2, fix your code :)
The problem is this piece of code:
<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
<script>
grecaptcha.ready(function () {
grecaptcha.execute('My_Site_Key', { action: 'contact' }).then(function (token) {
var recaptchaResponse = document.getElementById('recaptchaResponse');
recaptchaResponse.value = token;
});
});
</script>
The token is only valid for 2 minutes after you execute is called as stated in the docs:
Note: reCAPTCHA tokens expire after two minutes. If you're protecting an action with reCAPTCHA, make sure to call execute when the user takes the action.
Thus, if you spend more then 2 minutes on the contact-form, you get the timout error,. Thats why its recommended in the docs to only call execute if the user actually submits your form / takes action. In vanilla JS it would look like this:
<script src="https://www.google.com/recaptcha/api.js?render=My_Site_Key"></script>
<script>
grecaptcha.ready(function() {
document.getElementById('contact-form').addEventListener("submit", function(event) {
event.preventDefault();
grecaptcha.execute('My_Site_Key', {action: 'contact'}).then(function(token) {
document.getElementById("recaptchaResponse").value= token;
document.getElementById('contact-form').submit();
});
}, false);
});
</script>
Every time the page reloads you get a new token from google . You can use that token only once . Somehow if you are using that token more than once to get the response from google Api , you will get that error . Check this error reference https://developers.google.com/recaptcha/docs/verify?hl=en
I been googling looking for answers specifically similar to your use case.
reCaptcha V3 does not have reset API.
I solve the problem by when Password or Email authentication failed on your side, execute this again on your AJAX if failed. So that the value get replace with new g-token without reloading the site again, since following Google Documentation like me, the script execute on ready at your "signin page"
grecaptcha.ready(function() {
grecaptcha.execute('abhkdfhlasdfhldafhlashflasdhl', {action: 'submit'}).then(function(token) {
document.getElementById('g-token').value = token;
});
});
The issue is likely caused because the script is running more than once.
Is there anywhere else in the code that could be submitting the form more than once?
I had a similar issue and a simple console log in the results part of the JS showed that it was being printed twice i.e. the form was submitting twice.
If it is not a code issue, a user may be double clicking the button. You could do a simple on click event to disable the button and this would remove the error.

Codeigniter twitter bootstrap login using Jquery

Am fairly new to using Jquery and am creating a login for a simple site am creating using CodeIgniter and bootstrap. After submitting the Log in button, it won't show any error or success message, meaning that I don't even know if it actually post the data to the controller
here's my code,
Jquery Code
<script>
//Wait until the DOM is fully loaded
$(document).ready(function(){
//Listen for the form submit
$('#loginform').submit(logIn);
});
//The function that handles the process
function logIn(event)
{
//Stop the form from submitting
event.preventDefault();
//Hide our form
// $('#loginform').slideUp();
//Collect our form data.
var form_data = {
email : $("[name='email']").val(),
password : $("[name='password']").val(),
};
//Begin the ajax call
$.ajax({
url: "admin",
type: "POST",
data: form_data,
dataType: "json",
cache: false,
success: function (json) {
if (json.error==1)
{
//Show the user the errors.
$('#message').html(json.message);
} else {
//Hide our form
$('#loginform').slideUp();
//Show the success message
$('#message').html(json.message).show();
}
}
});
}
</script>
login.php
<?php
echo $this->session->flashdata('alert');
?>
<div id="message"></div>
<?php
$attr = array('class' => 'admin-login form-horizontal well form-signin', 'id' => 'loginform');
echo validation_errors('<div class="alert alert-error">', '</div>');
?>
<?php echo form_open(site_url('admin'), $attr) ?>
<!--<form action="<?php echo site_url('track-order'); ?>" method="post" class="form-horizontal form-search" id="trackModalform">-->
<div class="control-group">
<label class="control-label">Track Your Order</label>
</div>
<div class="control-group">
<label class="control-label" >Email:</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-qrcode"></i></span>
<input type="text" name="email" class="input-block-level email" placeholder="Email address">
</div>
</div>
</div>
<div class="control-group">
<label class="control-label" >Password:</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-key"></i></span>
<input type="password" name="password" class="input-block-level password" placeholder="Password">
</div>
</div>
</div>
<div class="form-actions" style="margin-bottom: 0px; padding-bottom: 0px;">
<input type="submit" class="btn btn-primary " name="signin" value="Sign In!" id="login">
</div>
</form>
my controller
public function index()
{
if (!file_exists('application/views/admin/index.php'))
{
//sorry that page is not available
show_404();
}
$this->form_validation->set_rules('email', 'Name', 'required|min_length[5]|max_length[50]|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required|min_length[5]');
if($this->form_validation->run() === TRUE)
{
echo json_encode(array('error' => '1', 'message' => validation_errors('<div class="alert alert-error"><strong>Error!</strong> ', '</div>')));
} else {
//Save the data to the database, of course you will need all the data first.
if($this->admin_model->validate_admin_login()):
//Send the success to our javascript file.
echo json_encode(array('error' => '0', 'message' => '<div class="alert alert-success"><strong>Success!</strong> You have been registered!</div>'));
endif;
}
$data['title'] = ucfirst('Admin - Home');
$data['currentpage'] = 'home';
$this->load->view('admin/index', $data);
}
model
public function validate_admin_login()
{
$this->str = do_hash($this->input->post('password')); // SHA1
$this->db->where('email', $this->input->post('email'));
$this->db->where('password', $this->str);
$query = $this->db->get('ip_admin');
if($query->num_rows == 1)
{
$data['admin_sess'] = $this->admin_model->admin_details($this->input->post('email'));
$data = array(
'email' => $this->input->post('email'),
'is_admin_logged_in' => true
);
$this->session->set_userdata($data);
return true;
}
}
public function admin_details($user)
{
$query = $this->db->select('*')->from('ip_admin')->where('email', $user);
$query = $query->get();
return $data['admin_sess'] = $query->row();
}
I don't really responding or outputting any message to indicate success or failure, maybe I got everything wrong to start with.
I need it to query the db, returns the message for me on the view page using the json parameter on my controller.
Thanks all.
I suggest you add a data in var_data like this:
var form_data = {
email : $("[name='email']").val(),
password : $("[name='password']").val(),
//add a data which is
ajax: '1'
};
And in your controller check if it is POST'ed:
if($this->input->post('ajax'){
//do something
}else{
//do something
}
so from there you could check if it is working or not. and also install firebug for debugging purposes in Firefox. In Chrome try to inspect element and see console
I honestly haven't gone through all your code as it really isn't that complicated, instead I'd like to suggest you install Firebug to debug your jquery if you haven't already installed it. Its essential when developing with javascript. It will print any errors or success as events are called and handled.
How to use: Firebug FAQ
EDIT:
As you asked for code:
if($this->form_validation->run() === TRUE)
{
echo json_encode(array('error' => '1', 'message' => validation_errors('<div class="alert alert-error"><strong>Error!</strong> ', '</div>')));
} else {
//Save the data to the database, of course you will need all the data first.
if($this->admin_model->validate_admin_login()):
//Send the success to our javascript file.
echo json_encode(array('error' => '0', 'message' => '<div class="alert alert-success"><strong>Success!</strong> You have been registered!</div>'));
endif;
}
$data['title'] = ucfirst('Admin - Home');
$data['currentpage'] = 'home';
$this->load->view('admin/index', $data);
Wtihin this block, you're echo'ing json once and then spitting out the HTML view afterwards. Just try removing the:
$data['title'] = ucfirst('Admin - Home');
$data['currentpage'] = 'home';
$this->load->view('admin/index', $data);
Or create separate controller functions for your requests, things get really messy when you try to stuff everything into a single function.

Using AJAX request with CodeIgniter forms

I am having trouble in combining CodeIgniter and AJAX. I have a sign up form. What I want is that when user clicks on sign up button on my home page, he gets a sign up form in pop up. If he enter wrong details in the form , he is prompted on the pop up itself that your details are invalid, He must not be redirected to new page to show errors. So I am using bpopup to make my form pop up and ajax request, but I am not able to perform form_validation, I am little confused. If user does not pass form validation a HTML document is alerted to the user because of view being loaded. If I will not load the view , it will not show login page. If I will directly load view , how will I show user individual errors , like password must be 6 characters long. Here is my code :
My login view :
<html>
<head>
<title>Sign In</title>
<script type="text/javascript">
var frm = $('form');
frm.submit(function () {
$("#status").empty();
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
if (data == "invalid") {
$('#status').html("Invalid Login Details");
}
else if(data == "valid")
{
$('#status').html("Login successful");
setTimeout(function(){
location.reload();
},600);
}
else
{
$('#status').html("Your Account is not Activated");
}
}
});
return false;
});
</script>
</head>
<body>
<div class="Header">
<h3>Sign In </h3>
</div>
<div id="status"></div>
<div class="main">
<?php echo form_open('xyz/signin'); //Renders the form element and adds extra functionality like Adds a hidden CSFR prevention field.?>
<h5>Email</h5> // For the time being I have remove echo form_error.
<input type="text" name="email" value="<?php echo set_value('email'); ?>" size="25"/>
<h5>Password *</h5> // For the time being I have remove echo form_error.
<input type="password" name="password" size="25"/>
<div><input type="submit" value="Submit" "/></div>
</form>
</div>
</body>
</html>
and here is my sign in function of xyz controller :
public function signin()
{
$this->load->helper(array('form','url'));
$this->load->library('form_validation');
$config = array(
array(
'field' => 'email',
'label' => 'Email Address',
'rules' => 'trim|required|valid_email|xss_clean'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'trim|required|xss_clean'
)
);
$this->form_validation->set_rules($config);
if($this->form_validation->run() == FALSE) /
{
$this->load->view('pinflag/login.php');
}
else //format of form is correct
{
$email = $this->input->post('email');
$password = md5($this->input->post('password'));
$data = array(
'email' => $email,
'password' => $password
);
$result = $this->user_model->get_users($data);
if($result->num_rows == 1) //login details are correct
{
$result = $result->result_array();
if($result[0]['status'] == 0)
{
echo "notActivated";
}
else
{
$this->session->set_userdata('id',$result[0]['id']);
$this->session->set_userdata('name',$result[0]['fname']);
echo "valid";
}
}
else //when user enter invalid login details
{
echo "invalid";
}
}
}
Sorry, indentation got all messed up when I pasted the code here.
i didn't get how your pop is coming but for error and success messages try
$this->session->set_flashdata("msg","<span class='m_error'>".$this->lang->line('global_insert_error')."</span>");
before your page to be loaded.
and inside your login view any part
if($this->session->flashdata('msg'))
{
echo $this->session->flashdata('msg');
}

Categories