I tried to convert the codeigniter form handling using ajax then display validation error if validation is false but in my current state, it always throw an error. Check the code below for reference.
PHP:
public function add () {
$post_data = $this->input->post('formdata');
$data = array (
'identity' => $post_data ['email'],
'password' => $post_data ['password'],
'email' => $post_data ['email'],
'group' => array($post_data['group_id']),
'additional_data' => array (
'first_name' => $post_data['first_name'],
'last_name' => $post_data['last_name'],
'active' => $post_data['active'],
'date_registered' => date('Y/m/d h:i:sa')
)
);
// custom error message
$this->form_validation->set_message('alpha_dash_space', '%s appears to be invalid. Must contain only alphabets.');
$this->form_validation->set_message('matches', '%s does not match the Confirm Password field. ');
if ($this->form_validation->run() == TRUE) {
$result['data'] = $this->ion_auth->register($data['identity'], $data['password'], $data['email'], $data['additional_data'], $data['group']);
} else {
$result['message'] = validation_errors();
}
echo json_encode($result);
}
JS:
function submit_form (form_id) {
var url = $(form_id).attr("action");
var formData = {};
$(form_id).find("input[name]").each(function (index, node) {
formData[node.name] = node.value;
});
$(form_id).find('select[name]').each(function (index, node) {
formData[node.name] = node.value;
});
$(form_id).find('textarea[name]').each(function (index, node) {
formData[node.name] = node.value;
});
$.ajax({
type: "POST",
data: {
'formdata': formData
},
url: url,
dataType: 'json',
success: function(result) {
if (result.data) {
console.log(success);
swal({
title: "Success!",
text: "You've done it great!",
type: "success"
},
function(){
location.reload();
});
} else {
$('#error-msg').html(result.message);
}
},
error: function(data) {
swal({
title: "Error!",
text: "Oops, something went wrong. Check and try again.",
type: "error"
});
}
});
}
Note: Form validation are set in config directory. So no issues in form rules. All are running good except I think the jquery that handles the condition.
Edit like below:
if ($this->form_validation->run() == FALSE) {
$result['message'] = validation_errors();
} else {
$result['data'] = $this->ion_auth->register($data['identity'],
$data['password'], $data['email'], $data['additional_data'],
$data['group']);
}
Also you have set_message but not set_rules. If you want to use form_validation library, you should set some rules.
Related
I'm working on a project in CodeIgniter4. I'm trying to make an Ajax call to an endpoint (/adjustments/store). I'm validating the form using CodeIgniter and showing the validation errors in my view. The issue is when the first time, i submit the form, it works and shows some validation errors. But when i fill the form correclty (to get not validation errors) and resubmit it again it gives me 403 forbidden error in the console.
Ajax call
$.ajax({
type: 'post',
url: '/adjustments/store',
dataType: 'html',
data: {
number,
date,
type,
account,
description,
adjData,
csrf_test_name
},
success: function (res) {
if (IsJsonString(res)) {
const response = JSON.parse(res);
if (response.hasOwnProperty('validation_errors')) {
const errors = response.validation_errors;
for (err in errors) {
$(`input[name=${ err }]`)
.parent()
.append(`<small class="text-danger">${ errors[err] }</small>`)
}
}
}
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
console.log(res);
}
CodeIgniter Controller
public function store () {
$data = $this->request->getPost(NULL);
// Validate
if (! $this->validate([
'number' => 'required',
'date' => 'required',
'type' => 'required',
'adjData' => 'required',
]))
{
echo json_encode(['validation_errors' => $this->validator->getErrors()]);
return;
}
echo json_encode($data);
}
Any solution to this?
If you are resubmitting a form then you have update csrf token on every request with ajax.
Whenever validation fails pass csrf token and update it every time.
In your controller -
public function store () {
$data = $this->request->getPost(NULL);
// Validate
if (! $this->validate([
'number' => 'required',
'date' => 'required',
'type' => 'required',
'adjData' => 'required',
]))
{
echo json_encode(['validation_errors' => $this->validator->getErrors(), 'csrf' => csrf_hash()]);
return;
}
echo json_encode($data);
}
In you ajax -
$.ajax({
type: 'post',
url: '/adjustments/store',
dataType: 'html',
data: {
number,
date,
type,
account,
description,
adjData,
csrf_test_name
},
success: function (res) {
if (IsJsonString(res)) {
const response = JSON.parse(res);
$("input[name='csrf_test_name']").val(response ["csrf"]);
if (response.hasOwnProperty('validation_errors')) {
const errors = response.validation_errors;
for (err in errors) {
$(`input[name=${ err }]`)
.parent()
.append(`<small class="text-danger">${ errors[err] }</small>`)
}
}
}
function IsJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
So once you update csrf then it will work fine.
Thanks.
So. I am trying create a fields validation using ajax. I have created the class "validate-field" on the fields where is a necessary a validation.
One Field is email_addres and another is taxvat. On my controller I just created thea action "validate" and then I am trying get the Field ID and Field Value.
Follow the codes below:
-the jQuery:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery(".continuar").on("click", function(){
url = "<?php echo Mage::getUrl('awmajax/ajax/validar')?>";
jQuery(".required-entry").each(function(){
if(jQuery(this).val() == ""){
jQuery(this).addClass("validation-failed");
}
else {
jQuery(this).removeClass("validation-failed");
}
});
jQuery(".validate-field").each(function(){
fieldName = jQuery(this).attr('id');
fieldValue = jQuery(this).val();
jQuery.ajax({
type: "GET",
url: url,
dataType: "json",
data: ({
field : fieldName,
value : fieldValue
}),
success: function(result){
console.log(result);
}
});
});
});
});
</script>
and the php:
public function validarAction(){
$params = $this->getRequest()->getParams();
if($params['field'] == 'taxvat'){
$taxvat = $params['value'];
$validacao = Mage::helper('awm_awmajax')->validaCPF($taxvat);
if($validacao == false){
$resultTaxvat = array(
"response" => "Taxvat is not valid",
"field" => $params['field']
);
}
$this->getResponse()->setBody(json_encode($resultTaxvat));
}
if($params['field'] = 'email_address'){
$emailAddress = $params['value'];
$validacaoEmail = Mage::helper('awm_awmajax')->checkEmailExists($emailAddress);
$resultEmail = array(
"response" => $validacaoEmail, //Type a valid Email
"field" => $params['field']
);
$this->getResponse()->setBody(json_encode($resultEmail));
}
}
What is the problem:
I get always just the email response on the second "If".
Any help is welcome.
Cheers
your second IF statement is passing a value and not comparing... I think you were supposed to write if ($params['field'] === 'email_address')
regarding your issue, try this:
public function validarAction()
{
$params = $this->getRequest()->getParams();
$error = false;
$errors = [];
if ($params['field'] == 'taxvat') {
$taxvat = $params['value'];
$validacao = Mage::helper('awm_awmajax')->validaCPF($taxvat);
if (!$validacao) {
$error = true;
$errors[] = [
'field' => $params['field'],
'message' => 'Taxvat is not valid',
];
}
}
if ($params['field'] === 'email_address') {
$emailAddress = $params['value'];
$validacaoEmail = Mage::helper('awm_awmajax')->checkEmailExists($emailAddress);
if (!$$validacaoEmail) {
$error = true;
$errors[] = [
'field' => $params['field'],
'message' => 'Type a valid Email',
];
}
}
$this->getResponse()->setBody(json_encode([
'error' => $error,
'errors' => $errors
]));
}
...tyr to use a loop construct to refactor this. as this may result in a lot of IF statements if you are going to validate a lot of fields.
EDIT:
Changed $result to $errors and the JSON index status to error. It would be easier to iterate with the updated code on your JS.
I Insert Ledger Record using Ajax and Jquery in Laravel. Success Message has been Displayed Correctly but Error Custom Message Cannot Display in blade View. Whats My Mistake Please Mention.
Jquery :
$("#add").click(function(event) {
event.preventDefault();
$.ajax({
type: 'post',
url: $("#add").attr('data-url'),
data: {
'_token': $("input[name=_token]").val(),
'form_data': $('#Form').serialize(),
},
success: function(data) {
$('#ledger_name').val('');
$('#openning_balance').val('');
$('#ob_type').val('');
$('#under').val('');
$('#ledger_address').val('');
$("#newLedger .close").click();
$(".result").html(data.success).css({
'color': 'green',
'text-align': 'center'
}).delay(5000).fadeOut();
},
error: function(data) {
$('#response').show().html(data.error).css({
'color': 'red',
'text-align': 'center'
}).delay(5000).fadeOut();
}
});
});
Controller :
$values = array();
parse_str($_POST['form_data'], $values);
$validation = $this->validator($values,true );
if($validation->fails()){
$errors = $validation->errors();
return response()->json(['error' => 'Please Fill all Mandatory Fields',],500);
}
$insertledgers=Ledger::create(['ledger_name'=>$values['ledger_name'],'openning_balance'=>$values['openning_balance'],'ob_type'=>$values['ob_type'],'under'=>$values['under'],'ledger_address'=>$values['ledger_address'],'company_id'=>$companyids,'user_id'=>$usersid,'created_by'=>$usersid]);
$ledgerinsertids=$insertledgers->id;
if($values['ob_type'] == 'Cr'){
$creditamts=$values['openning_balance'];
$debitamts= 0;
} else {
$creditamts=0;
$debitamts= $values['openning_balance'];
}
$insertledgeropenningbalance=Openningbalance::create(['ledgerid'=>$ledgerinsertids,'opening_credit'=>$creditamts,'opening_debit'=>$debitamts,'company_id' => $companyids,'user_id' => $usersid,'created_by' => $usersid,]);
return response()->json(['success' => 'Ledger Details Added Successfully',],200);
Try this:
<?php
use Validator;
class SomeController extends Controller {
public function SomeFunction(Request $request) {
$values = array();
parse_str($_POST['form_data'], $values);
$validation = Validator::make($values, true);
if($validation->fails()){
$errors = $validation->errors();
return response()->json(['error' => 'Please Fill all Mandatory Fields'], 500);
}
$insertledgers=Ledger::create(['ledger_name'=>$values['ledger_name'],'openning_balance'=>$values['openning_balance'],'ob_type'=>$values['ob_type'],'under'=>$values['under'],'ledger_address'=>$values['ledger_address'],'company_id'=>$companyids,'user_id'=>$usersid,'created_by'=>$usersid]);
$ledgerinsertids=$insertledgers->id;
if($values['ob_type'] == 'Cr'){
$creditamts=$values['openning_balance'];
$debitamts= 0;
} else {
$creditamts=0;
$debitamts= $values['openning_balance'];
}
$insertledgeropenningbalance=Openningbalance::create(['ledgerid'=>$ledgerinsertids,'opening_credit'=>$creditamts,'opening_debit'=>$debitamts,'company_id'
=> $companyids,'user_id' => $usersid,'created_by' => $usersid,]);
return response()->json(['success' => 'Ledger Details Added Successfully',],200);
And in view:
error: function(data)
{
$('#response').html(data.error).css({'color': 'red', 'text-align': 'center'})
$('#response').show().delay(5000).fadeOut();
}
You just need to modify your error callback function as below:
error : function (data) {
$('#response').show().html(data.responseJSON.error).css({
'color': 'red',
'text-align': 'center'
}).delay(5000).fadeOut();
}
Thanks #voodoo417
There is my form:
$form = ActiveForm::begin([
'id' => 'user-create-form',
'enableAjaxValidation' => true,
'enableClientValidation' => false,
'validationUrl' => Url::toRoute(Yii::$app->controller->id . '/validation'),
'validateOnType' => true,
]);
JS-script is registered on this form and performed Russian to English transliteration according to some rules on .keyup() event. Transliteration result is added to samname field.
There is validation rule in UserCreateForm model:
public function rules()
{
return [
[['samname'], 'validateUserExist'],
];
}
public function validateUserExist()
{
$check = Yii::$app->CustomComponents->checkUserExist($this->samname);
if ($check) {
$errorMessage = 'User exists: ' . $check;
$this->addError('samname', $errorMessage);
}
}
Function checkUserExist() checks existing of created name and returns an error in matching case.
There is action on controller:
public function actionValidation()
{
$model = new UserCreateForm();
if (\Yii::$app->request->isAjax && $model->load(\Yii::$app->request->post())) {
\Yii::$app->response->format = Response::FORMAT_JSON;
echo json_encode(ActiveForm::validate($model));
\Yii::$app->end();
}
}
It works great, validation is performed, matching case returns an error...
But!
It's required that JS-script is run again and added next letter to the name on error (JS-script provides this functionality). How to run JS-script again after validator was return an error?
#yafater Thanks for help! I find solution.
$('form').on('afterValidateAttribute', function (event, attribute, message) {
if (attribute.name === 'samname')
{
$.ajax({
url: "url-to-action",
type: "POST",
dataType: "json",
data: $(this).serialize(),
success: function(response) {
if ( typeof(response["form-samname"]) != "undefined" && response["form-samname"] !== null ) {
// code here
}
},
});
return false;
}
});
I want to check data in database through ajax in codeigniter how can get check name already exist through ajax
controller
public function insert(){
$user = array('Name' => $this->input->post('name'),
'Cnic' => $this->input->post('cnic'),
'Phone' => $this->input->post('phone'),
'Address' => $this->input->post('address'),
);
$this->load->model('suppliermodel');
if($this->suppliermodel->checkData($user['Name'])){
if ($this->session->userdata('user_id'))
$detail = 'Already exist';
$this->load->view('admin/includes/header');
$this->load->view('admin/includes/sidemenu');
$this->load->view('admin/add_supplier',['exist'=>$detail]);
$this->load->view('admin/includes/footer');
$this->load->view('admin/includes/add_supplier_footer');
}
else{
$this->suppliermodel->add($user);
}
}
model
public function checkData()
{
$name = $this->input->post('name');
$this->db->select('*');
$this->db->where('Name', $name);
$this->db->from('suppliers');
$query = $this->db->get();
if($query->num_rows() >0){
return $query->result();
}
else{
return $query->result();
return false;
}
}
what is ajax code and controller function
How about this?
Controller
public function insert(){
// set a rule that make the Name field is unique by 'set_rules'
$this->form_validation->set_rules('Name', 'Name Field', 'required|is_unique[suppliers.name]');
//$this->form_validation->set_rules('[Other Field]', '[Field Name to Display]', '[Restriction]');
// if the field cannot pass the rule
if ($this->form_validation->run() === FALSE) {
$errors = array();
foreach ($this->input->post() as $key => $value) {
// Add the error message for this field
$errors[$key] = strip_tags(form_error($key));
}
// Clear the empty fields (correct)
$response['errors'] = array_filter($errors);
$response['status'] = false;
}
else {
// otherwise, call the model
$result = $this->suppliermodel->add($user);
if ( $result ) {
$response['status'] = true;
}
}
echo json_encode($response);
}
JavaScript
$.ajax({
url: '//localhost/insert',
data: {
Name: $('input[name=Name]').val(),
Cnic: $('input[name=Cnic]').val(),
Phone: $('input[name=Phone]').val(),
Address: $('input[name=Address]').val()
},
dataType: 'JSON',
type: 'POST',
error: function(xhr) {
alert('request failed!');
},
success: function(response) {
var response = $.parseJSON(JSON.stringify(response));
if (response.status != true) {
$.each(response.errors, function(field, i) {
alert( field+ ' errors with ' + i)
});
}
else {
alert('success!');
}
}
});
Use is_unique[table.fieldToCompare] to make the field is always unique.
Wish it helps.
set_rules restrictions, see the Codeigniter User Guide Form validation
If fails, the controller would return a set of JSON, with field and error message. Then you can handle it in $.ajax's success.