An input field is being generated by ng-repeat. The input tag includes ng-model and ng-blur. The ng-blur action is not triggered and the console doesn't show any errors.
The HTML is generated by a Zend Framework 3 app. I'm using angularjs 1.7.8 and jquery 3.1.0.
Here is the body of the web page
<body ng-app='byDomainApp' ng-controller='ByDomainCtrl'>
<center>
<h2>Maintenance By Domain</h2>
</center>
<p>You may edit/correct any of the following details. Note that an
update will be ignored if the email address is changed to one that has
been tried previously.</p>
<div class='row'>
<div class='col-xs-3'>
Choose a domain: <select class='form-control' ng-model="myDomain"
ng-change="domainUsers(myDomain)"
ng-options="domain.domain_name for domain in domains track by domain.domain_id"></select>
<p ng-hide 'message=null' >
<br> <br>{{message}}
</p>
</div>
</div>
<div class='row'>
<div class='col-xs-2'>Name</div>
<div class='col-xs-2'>Email</div>
<div class='col-xs-2'>Company</div>
<div class='col-xs-2'>Job title</div>
<div class='col-xs-2'>Country</div>
<div class='col-xs-2'>Confirmed?</div>
</div>
<div ng-repeat="user in users" class='row'>
<div class='col-xs-2'>
<input ng-model="user.user_name" ng-blur="updateUser(user)">
</div>
<div class='col-xs-2'>{{user.user_email}}</div>
<div class='col-xs-2'>{{user.user_company}}</div>
<div class='col-xs-2'>{{user.user_jobtitle}}</div>
<div class='col-xs-2'>{{user.user_country}}</div>
<div class='col-xs-2'>{{user.user_confirmed}}</div>
</div>
The Javascript angular code
angular.module('byListApp', []).constant("listUrl",
"http://elms2.com/list-rest").constant("userUrl",
"http://elms2.com/user-rest").controller(
"ByListCtrl",
function($scope, $http, listUrl, userUrl) {
$scope.hide = true;
$scope.showMessage = false;
$http.get(listUrl + '/' + ownerId).then(function(response) {
$scope.lists = response.data;
}, function(error) {
$scope.error = error;
alert(error);
});
$scope.listUsers = function(list) {
$scope.message = '';
$scope.hide = true;
$scope.showMessage = false;
// $scope.booksFound[0].message = '';
$http.get(userUrl + '/byList:' + list.list_id).then(
function(response) {
$scope.users = response.data;
});
};
});
angular.module('byDomainApp', []).constant("domainUrl",
"http://elms2.com/domain-rest").constant("userUrl",
"http://elms2.com/user-rest").controller(
"ByDomainCtrl",
function($scope, $http, domainUrl, userUrl) {
$scope.hide = true;
$scope.showMessage = false;
$http.get(domainUrl).then(function(response) {
$scope.domains = response.data;
}, function(error) {
$scope.error = error;
alert(error);
});
$scope.domainUsers = function(domain) {
$scope.message = '';
$scope.hide = true;
$scope.showMessage = false;
$http.get(userUrl + '/byDomain:' + domain.domain_id).then(
function(response) {
$scope.users = response.data;
}, function(error) {
$scope.error = error;
alert(error);
});
};
$scope.updateUser = function(user) {
$http.get(userUrl + '/updateUser:' + user).then(
function(response) {
$scope.userData = response.data;
}, function(error) {
$scope.error = error;
alert(error);
});
};
});
The list of domains is generated correctly and the ng-repeat fills with the correct data when a domain is selected. However nothing happens when the input field contents are edited and then loses focus. I can prove that by deleting the updateUser function from the angular code or replacing the ng-blur action with an alert or similar.
This is now working and I can't explain why as nothing has changed.
Related
I need to update the data from MySQL DB using AngularJS + PHP.
Dashboard.html is my first page I just give only two field: name and position, and I fetch the data from DB using ng-repeat after fetch the code the user will click the edit button it will redirect to the edit.html page with the same fields: name and position. Help me to fetch that name and position data in edit.html page
Dashboard.html
<div ng-app="myapp" ng-controller="usercontroller">
<table>
<th>Name</th>
<th>Position</th>
<tbody>
<tr ng-repeat="x in names">
<td>{{x.name}}</td>
<td>{{x.position}}</td>
<td>
<span class="glyphicon glyphicon-edit" ng-click="updateData(x.name, x.position)" ></span>
</td </tr>
</tbody>
</table>
</div>
<script type="text/javascript">
var app = angular.module("myapp", []);
app.controller("usercontroller", function($scope, $http) {
$scope.updateData = function(name, position) {
$scope.name = name;
$scope.position = position;
$scope.btnName = "Update";
}
});
</script>
This is my edit.html page and am using ng-model to bind the data from
dashboard.html, but it is not binding. And I click the update button the data have to update with id, and I mentioned my PHP file also.
My DB name sample and table named demo.
Edit.html
<div ng-app="myapp" ng-controller="EditController">
<form name="form">
<div class="form-group">
<label for="name">Name</label>
<input class="form-control" type="text" name="name" ng-model="name" /> {{name}}
</div>
<div class="form-group">
<label for="position">Position</label>
<input class="form-control" type="text" name="position" ng-model="position" />
</div>
<input type="submit" name="btnUpdate" class="btn btn-success" ng-click="update_data()" value="{{btnName}}">
</form>
<script>
var app = angular.module("myapp", []);
app.controller("EditController", function($scope, $http) {
$scope.btnName = "Update";
$scope.update_data = function() {
$http.post(
"edit.php", {
'name': $scope.name,
'position': $scope.position,
'btnName': $scope.btnName
}
).success(function(data) {
alert(data);
$scope.name = null;
$scope.position = null;
$scope.btnName = "Update";
});
}
});
</script>
Edit.php
<?php
$connect = mysqli_connect("localhost", "root", "", "sample");
$data = json_decode(file_get_contents("php://input"));
if (count($data) > 0) {
$name = mysqli_real_escape_string($connect, $data->name);
$position = mysqli_real_escape_string($connect, $data->position);
$btn_name = $data->btnName;
if ($btn_name == 'Update') {
$id = $data->id;
$query = "UPDATE demo SET name = '$name',position = '$position' WHERE id = '$id'";
if (mysqli_query($connect, $query)) {
echo 'Updated Successfully...';
} else {
echo 'Failed';
}
}
}
?>
You have two different controllers: usercontroller and EditController. Once you leave one and enter another, you lose your bindings. So ng-model="name" in once controller is completely different from ng-model="name" in the second controller.
To make sure that they are the same, you need to create a service that will share data between controllers. You can make it like a simple storage service without any bindings.
When you want to update the data, you need to save it in the service as well. And whenever you want to edit it, you need to pull that data out of it, and populate your models.
Example of such service:
app.service("storageService", function() {
this.data = {};
this.set = function(name, position, btnName) {
this.data = {
"name": name,
"position": position,
"btnName": btnName
};
}
this.get = function() {
return this.data;
}
this.clear = function() {
this.data = {
"name": null,
"position": null,
"btnName": null
};
}
})
The you can inject it into your controllers and use it's functions:
usercontroller
app.controller("usercontroller", function($scope, $http, storageService) { // <-- note the injection
$scope.updateData = function(name, position) {
$scope.name = name;
$scope.position = position;
$scope.btnName = "Update";
storageService.set($scope.name, $scope.position, $scope.btnName); // saving data
}
});
EditController
app.controller("EditController", function($scope, $http, storageService) {
var d = storageService.get(); // loading data
$scope.name = d.name;
$scope.position = d.position;
$scope.btnName = "Update"; // = d.btnName;
$scope.update_data = function() {
$http.post(
"edit.php", {
'name': $scope.name,
'position': $scope.position,
'btnName': $scope.btnName
}
).success(function(data) {
alert(data);
$scope.name = null;
$scope.position = null;
$scope.btnName = "Update";
});
}
});
How can i go back to the view page and modal with the validation errors if the validation runs false ..
I want to show validation errors in the modal ..
Im new to jquery ajax ..
Is there needed to add in my jquery .. or what way can i do it..
Controller
public function update(){
$this->form_validation->set_rules('lname', 'Family Name', 'required');
if ($this->form_validation->run() == FALSE) {
}
else {
$this->home_model->update();
redirect(base_url());
}
}
Jquery
$(document).on('click', '#update', function() {
console.log($(this).attr('data-registerid'));
$.ajax({
url: "<?php echo base_url('home/get_data')?>",
type: "POST",
dataType: "JSON",
data: {
"id": $(this).attr('data-registerid')
},
success: function(data) {
console.log(data);
$('#no').val(data.rec['no']);
$('#lname_edit').val(data.rec['lname']);
$('#fname_edit').val(data.rec['fname']);
$('#mi_edit').val(data.rec['mi']);
$('#bdate_edit').val(data.rec['bdate']);
$('#module_edit').val(data.rec['module']);
$('.updatemodal').modal({
backdrop: 'static',
keyboard: false
});
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error get data from ajax');
}
});
});
To pass form validation status to client, use the below code in your controller. The code responds with a json-formatted, error, and notice text.
if ($this->form_validation->run() == FALSE) {
$json_response['form_errors'] = $this->form_validation->error_array();
exit(json_encode($json_response));
}
Client side, in your jquery ajax success handler, you can use the below code so the status response emitted server side is displayed to the client.
if (data.form_errors != undefined) {
var errors = '';
$.each(data.form_errors, function(i, val) {
errors = errors + "\n" + val;
});
if (errors != "") alert(errors);
}
else {
alert('no error(s) in form... submit form..');
}
Alternative to the above js code:
For updating each form elements' status when they change, use the below code. Place it outside your form submit handler.
function update_form_validation() {
$("input,select,textarea").on("change paste keyup", function() {
if ($(this).is(':checkbox') == true) {
$(this).siblings("label:last").next(".text-danger").remove();
} else if ($(this).is(':radio') == true) {
$(this).siblings('input[type="radio"][name="' + $(this).attr('name') + '"]:last').next(".text-danger").remove();
$(this).next(".text-danger").remove();
} else {
$(this).next(".text-danger").remove();
}
});
}
update_form_validation();
For displaying general notice and displaying each errors and notices right after their respective form element,
use the below code. In your form submit handler, place the code inside your ajax success function.
if (data.form_errors != undefined) {
$.each(data.form_errors, function(i, val) {
if ($('input[name="' + i + '"]').is(':hidden') == false) {
if ($('input[name="' + i + '"]').is(':radio') == true) {
$('input[name="' + i + '"]:last').after('<div class="text-danger">' + val + '</div>');
} else if ($('input[name="' + i + '"]').is(':checkbox') == true) {
$('input[name="' + i + '"]').siblings("label:last").after('<div class="text-danger">' + val + '</div>');
} else {
$('input[name="' + i + '"]').after('<div class="text-danger">' + val + '</div>');
$('select[name="' + i + '"]').after('<div class="text-danger">' + val + '</div>');
$('textarea[name="' + i + '"]').after('<div class="text-danger">' + val + '</div>');
}
}
});
} else {
alert('no errors in form... submit form..');
}
You can use CodeIgniter form validations function :
$errors = array();
if ($this->form_validation->run() == FALSE) {
$errors['validation_error'] = validation_errors();
echo json_encode($errors);
exit();
}
Now in jquery:
$(document).on('click', '#update', function() {
console.log($(this).attr('data-registerid'));
$.ajax({
url: "<?php echo base_url('home/get_data')?>",
type: "POST",
dataType: "JSON",
data: {
"id": $(this).attr('data-registerid')
},
success: function(data) {
var myObj = JSON.parse(data);
$('#error_div').html(myObj.validation_error);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error get data from ajax');
}
});
});
View
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h5 class="modal-title">Login Form</h5>
</div>
<div class="modal-body">
<div id="modelError"></div>
<form method="post" action="javascript:void(0)">
<div class="input-group">
<input type="text" name="name" id="name" placeholder="First Name">
</div>
<div class="input-group">
<input type="text" name="last_name" id="last_name" placeholder="Last Name">
</div>
<input type="submit" id="my_form" name="Save">
</form>
</div>
</div>
</div>
</div>
Script
<script>
$('#my_form').click(function(){
$.ajax({
url: "<?php echo base_url('controller/function')?>",
type: "POST",
data: {
'name': $('#name').val(),
'last_name': $('#last_name').val(),
},
success: function(data) {
var myObj = JSON.parse(data);
var msg = '<div class="alert alert-danger alert-dismissable">'+myObj.error+'</div>';
$('#modelError').html(msg);
},
error: function() {
alert('Error get data from ajax');
}
});
});
</script>
Controller
public function insert()
{
if(isset($this->input->post())){
$this->form_validation->set_rules('name','Name','required');
$this->form_validation->set_rules('last_name','Last Name','required');
if ($this->form_validation->run() == FALSE)
{
$this->msg['error'] = validation_errors();
echo json_encode($this->msg);
}else{
$this->your_model->insert($this->input->post());
redirect(base_url());
}
}else{
$this->load->view('view-page');
}
}
I'm trying to send to the php backend a file and form data, but I'm not trying to succeed.
Could someone give a hint or even fix the sending part to the backend
HTML img
<div class='form-group is-empty col-md-6'>
<input style="display: none" type="file" (change)="onFileChanged($event)" #fileInput formControlName='arquivo_cifra'>
<div class="file-cifra" [style.background-image]="'url(' + img + ' )' | safeHtml: 'style' "></div>
<button (click)="fileInput.click()" style="width: 250px">Select File</button>
</div>
<div class='box-footer'>
<button (click)='save(form.value)' [disabled]='!form.valid' class='btn btn-primary'>Salvar</button>
</div>
component.ts
selectedFile: File;
img: any = 'assets/img/user_photo.png';
onFileChanged(event) {
var tmppath = URL.createObjectURL(event.target.files[0]);
this.img = tmppath;
this.selectedFile = event.target.files[0];
}
save(form) {
const uploadData = new FormData();
uploadData.append('myFile', this.selectedFile, this.selectedFile.name);
uploadData.append('form', form); //formBuilder
// this.form.value.arquivo_cifra = this.selectedFile;
// this.cifraService.saveFile(uploadData);
this.cifraService.save(uploadData)
}
service.ts
save(form) {
return this.http.post(`${BE_API}/cifra.php?acao=salvar`, form)
.subscribe((data) => {
if (data['success'] == 'ok') {
this.notify('Registro inserido com sucesso!');
this.router.navigate(['/cifra'])
}
console.log(data);
}, (error) => {
this.notify(`Error: ${error}`);
});
}
backend php
the file its work but form builder not.
public function incluir($ar) {
var_dump($_FILES);
var_dump($_REQUEST);
$dados = $this->dados($ar);
die();
$cd = self::insert($this->table, $dados);
if($cd>0){
self::commit();
}
}
return console
I am using Laravel 5.2 + angularjs.
GOAL : Have to submit a form which have only check boxes. Based on the check box selected check box id fetch the data and return to the view. This returned data will be displayed in other div of same page.
For Example : Form is in div1 and returned data should be displayed in div2, div3 and div4. Only one division will be displayed on the view rest are hidden.
FINALLY - I am able to hide and display divisions using angular and I am able to submit the form which is in div1 using ajax. But I am unable to get the data back to the view from controller (data is returned in json format) and display on other divisions.
How can I display the returned response json object on the view ?
Below is my code :
Route :
Route::group(['middleware' => ['web']], function () {
Route::get('/form', 'PublicController#index'); // View will be displayed by using this method
Route::post('/form','PublicController#show'); // Form is submitted and data is returned using this "show" method
});
Controller :
class PublicController extends Controller
{
public function index(){
$crimetypes = crimetype::get();
$step1='';$step2='';$step3='';$step4='';$step5='';
return view('frontend.form')->withCrimetypes($crimetypes)->withStep1($step1)->withStep2($step2)->withStep3($step3)->withStep4($step4)->withStep5($step5);
}
public function show(Request $request, QuestionsRepository $questionsRepository){
$data = $questionsRepository->returnSteps($request);
$step1 = $data[0];
$step2 = $data[1];
$step3 = $data[2];
$step4 = $data[3];
$step5 = $data[4];
// Data is successfully coming till here...
return response()->json(['step1'=>$step1, 'step2'=>$step2, 'step3'=>$step3, 'step4'=>$step4, 'step5'=>$step5],200);
// Here it is not allowing to use any other return type other than response json..
}
}
View :
<div ng-show="div1">
<div>
{!! Form::open(array('method'=>'POST','url'=>'/form','id'=>'formid'))!!}
<div class="col-md-12 row">
<h2>Step - 1</h2>
<hr>
<br><p>Please select the relevant check boxes below.</p>
</div>
#foreach($crimetypes as $crimeType)
<div class="col-md-4">
<ul class="list-unstyled">
<li>
<div class="checkbox">
<label>
<input value="{{$crimeType->id}}" type="checkbox" name="id[]" id="checkid"> {{$crimeType->type}}
</label>
</div>
</li>
</ul>
</div>
#endforeach
<div class="col-md-12 row">
<div class="form-group">
<br>
<hr>
<input type="submit" ng-click="click1()" value="Next" class="btn btn-default">
</div>
</div>
{!!Form::close()!!}
</div>
</div>
<!-- On submitting above form hide the above div and display below div...this is working fine..-->
<div ng-show="div2">
<div class="col-md-12 row">
<h2>Step - 2 : Crime Details</h2>
<hr>
<h3>Can You Tell Us About The Crime</h3>
<br>
<h5><strong>#if (!empty($step1[0])) ? {{$step1[0]->question}} : ''#endif?</strong></h5>
<div class="row">
<div class="control-group">
<div class="form-group col-md-3">
<input type="number" class="form-control nbr" placeholder="xxx-xxx-xxx">
</div>
<div class="col-md-9"></div>
</div>
</div>
<h5><strong>#if (!empty($step1[1])) ? {{$step1[1]->question}} : ''#endif?</strong></h5>
<div class="row">
<div class="control-group">
<div class="form-group col-md-3">
<input type="number" class="form-control nbr" placeholder="xxx-xxx-xxx">
</div>
<div class="col-md-9"></div>
</div>
</div>
<h5><strong>#if (!empty($step1[2])) ? {{$step1[2]->question}} : ''#endif?</strong></h5>
<div class="row">
<div class="control-group">
<div class="form-group col-md-3">
<input type="textarea" class="form-control nbr">
</div>
<div class="col-md-9"></div>
</div>
</div>
<div class="row">
<br>
<hr>
<div class="form-group col-md-2">
<button ng-click="click2()" class="btn btn-default">Next</button>
</div>
<div class="form-group col-md-offset-10">
<button ng-click="click2()" class="btn btn-primary">Skip</button>
</div>
</div>
</div>
</div>
<!-- Similarly there are three more div's where I have to display the fetched data...-->
Script :
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
}
});
$(document).ready(function(){
$('#formid').on('submit', function(e){
e.preventDefault();
var id = new Array();
$('input[name="id[]"]:checked').each(function()
{
id.push($(this).val());
});
var $form = $('form');
$.ajax({
url:$form.attr('url'),
type: $form.attr('method'),
data: {id},
dataType:'json',
success: function(data){
var step1 = data.step1;
var step2 = data.step2;
var step3 = data.step3;
var step4 = data.step4;
var step5 = data.step5;
// If I use success, I am able to get data to these variables but unable to make use them on view wherever required. But now I am trying to use the returned object directly on the view without callback in the ajax. Even by using callback if it is possible, please help me out...
}
});
});
});
</script>
I solved my problem, here is the code I changed/added :
AngularJs Files :
formCtrl.js :
angular.module('formCtrl', []).controller('formController', function($scope, $http, Comment){
Comment.get().success(function(data){
$scope.crimeTypes = data[0];
});
$scope.div1 = true;
$scope.div2 = false;
$scope.div3 = false;
$scope.div4 = false;
$scope.div5 = false;
$scope.div6 = false;
$scope.div7 = false;
$scope.selected = {};
$scope.click1 = function(data){
var id = [];
for(var i in data){
if(data[i].selected==true){
id.push(data[i].id);
}
}
$scope.selected = {id};
$http({
method : 'POST',
url : '/index1',
data : $.param($scope.selected),
headers :{'Content-Type':'application/x-www-form-urlencoded'}
})
.success(function(data) {
console.log(data);
});
$scope.div1 = false;
$scope.div2 = true;
$scope.div3 = false;
$scope.div4 = false;
$scope.div5 = false;
$scope.div6 = false;
$scope.div7 = false;
};
$scope.click2 = function(){
$scope.div1 = false;
$scope.div2 = false;
$scope.div3 = true;
$scope.div4 = false;
$scope.div5 = false;
$scope.div6 = false;
$scope.div7 = false;
};
$scope.click3 = function(){
$scope.div1 = false;
$scope.div2 = false;
$scope.div3 = false;
$scope.div4 = true;
$scope.div5 = false;
$scope.div6 = false;
$scope.div7 = false;
};
$scope.click4 = function(){
$scope.div1 = false;
$scope.div2 = false;
$scope.div3 = false;
$scope.div4 = false;
$scope.div5 = true;
$scope.div6 = false;
$scope.div7 = false;
};
$scope.click5 = function(){
$scope.div1 = false;
$scope.div2 = false;
$scope.div3 = false;
$scope.div4 = false;
$scope.div5 = false;
$scope.div6 = true;
$scope.div7 = false;
};
$scope.click6 = function(){
$scope.div1 = false;
$scope.div2 = false;
$scope.div3 = false;
$scope.div4 = false;
$scope.div5 = false;
$scope.div6 = false;
$scope.div7 = true;
};
});
formService.js :
angular.module('formService',[])
.factory('Comment', function($http){
return {
get:function(){
return $http.get('/index1data');
}
}
});
main.js :
var app = angular.module('angularApp', ['mainCtrl','formCtrl','formService'], function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
No code change in Route and Controller files. In view only changed the div with checkbox class code to as shown below.
Laravel Files :
View :
<div class="checkbox">
<input value="<%crimeType.id%>" type="checkbox" ng-model="crimeType.selected" id="<%crimeType.type%>">
<label for="<%crimeType.type%>"><% crimeType.type %></label>
</div>
NOTE : I didn't used ajax script which I had posted in the question. Controller and Route files are not changed.
Attempted to post this on the Foundation forum, but for some reason it would not post.
The first code snippet below shows the working code for my form using data-abide="ajax", and the .on('valid.fndtn.abide',function(){});. The elements are disabled etc. and the modal opens. When the modal is closed I remain on the page as desired.
I am attempting to now have this use AJAX, where the request will be to a php script handling the data insert, and the element manipulation and modal will happen on success.
The second code snippet shows that attempt, which is not working. When I run this code, the alert fires, but then the page submits, with nothing written to the console, no modal, and the page refreshing. What am I doing wrong?
I have also included partial code (third snippet), for the form and modal.
If anyone has a working example using Foundation, data-abide="ajax" and reveal-modal, where the form is submitted, an AJAX call is made to a PHP script to insert data into the DB, and on success the modal window opens, please provide a sample.
SNIPPET 1 - works
<script type="text/javascript">
$(document).ready(function () {
$("#pledge_btn").attr("disabled", true);
$(document).foundation({
abide: {
validate_on: 'manual',
patterns: {
edu_address: /\.edu$/
}
}
});
$('a.custom-close-reveal-modal').click(function(){
$('#emailModal').foundation('reveal', 'close');
});
$('#pledge_form')
.on('invalid.fndtn.abide', function() {
$("#pledge_btn").attr("disabled", true);
$("#terms").prop("checked",false);
console.log('Not Submitted');
})
.on('valid.fndtn.abide', function() {
$("#pledge_form :input").prop('readonly', true);
$("#pledge_btn").attr("disabled", true);
$("#terms").attr("disabled", true);
$("#sweeps").attr("disabled", true);
console.log('Submitted: ', data);
$('#myModal').foundation('reveal', 'open');
});
});
SNIPPET 2 - Does NOT work
<script type="text/javascript">
$(document).ready(function () {
$("#pledge_btn").attr("disabled", true);
$(document).foundation({
abide: {
validate_on: 'manual',
patterns: {
edu_address: /\.edu$/
}
}
});
$('a.custom-close-reveal-modal').click(function(){
$('#emailModal').foundation('reveal', 'close');
});
$('#pledge_form')
.on('invalid.fndtn.abide', function() {
$("#pledge_btn").attr("disabled", true);
$("#terms").prop("checked",false);
alert("Form NOT submitted");
})
.on('valid.fndtn.abide', function() {
var lname = $("#lName").val();
var dataString = 'lname=' + lname;
alert("Form submitted");
$.ajax({
url : create_pledge.php,
type : $(this).attr('method'),
data : dataString,
success : function( data ) {
$("#pledge_form :input").prop('readonly', true);
$("#pledge_btn").attr("disabled", true);
$("#terms").attr("disabled", true);
$("#sweeps").attr("disabled", true);
console.log('Submitted: ', data);
$('#myModal').foundation('reveal', 'open');
},
error : function( data, xhr, err ) {
console.log('Oops: ', data, xhr , err);
}
});
return false;
});
});
</script>
PARTIAL FORM and MODAL Code
<div class="row pledge-row">
<form data-abide="ajax" id="pledge_form" method="post" name="pledge_form">
<div class="row">
<div class="large-6 medium-12 columns">
<label class="pledge-label">First Name*</label>
<input id="fName" type="text" required pattern="[a-zA-Z]+"/>
<small class="error">First Name is required</small>
</div>
</div>
<div class="row">
<div class="large-6 medium-12 columns">
<label class="pledge-label">Last Name*</label>
<input id="lName" type="text" required pattern="[a-zA-Z]+"/>
<small class="error">Last Name is required</small>
</div>
</div>
<div class="row">
<div class="large-6 medium-12 columns">
<label class="pledge-label">Email*</label>
<input id="email" type="email" required style="margin:0 0 5px 0 !important;"/>
<small class="error">.edu email address is required</small>
<span id="email-result"></span>
<div class="valid-email">(must be a properly formatted .edu email)</div>
</div>
</div>
<!-- CODE REMOVED FOR THIS POST -->
</form>
</div>
<!-- Modal -->
<div id="myModal" class="reveal-modal" data-reveal aria-labelledby="modalTitle" aria-hidden="true" role="dialog">
<h2 id="modalTitle">Thanks for pledging.</h2>
<p>please check your email for our confirmation/validation email.</p>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
Found the answer. I needed to have the ajax request in the submit, not the valid event.
So this works:
$('#pledge_form')
.on('invalid.fndtn.abide', function() {
$("#pledge_btn").attr("disabled", true);
$("#terms").prop("checked",false);
// alert("Form NOT submitted");
})
.on('valid.fndtn.abide', function() {
// alert("Form submitted");
console.log('VALID');
})
.on('submit', function(e) {
var ajaxObj = $.ajax({
url : 'create_pledge.php',
type : $(this).attr('method'),
data : $(this).serialize(),
success : function( ) {
$("#pledge_form :input").prop('readonly', true);
$("#pledge_btn").attr("disabled", true);
$("#terms").attr("disabled", true);
$("#sweeps").attr("disabled", true);
console.log('Submitted');
$('#myModal').foundation('reveal', 'open');
},
error : function( xhr, err ) {
console.log('Oops: ', xhr , err);
},
complete: function(){
console.log('COMPLETE');
}
});
});
});
I had the same problem too with fancybox and ajax check before submit.
This is my solution that works for sure
<form id="my_form" action="...." method="POST" class="popup" data-abide="ajax">
<input type="text" name="check_this_field_with_ajax" id="check_this_field_with_ajax">
....
</form>
<script type="text/javascript" src="..../js/foundation.min.js"></script>
<script type="text/javascript" src="..../js/foundation/foundation.abide.js"></script>
<script type="text/javascript">
$('#my_form')
.on('invalid.fndtn.abide', function() {
console.log('NOT Submitted');
})
.on('valid.fndtn.abide', function() {
console.log('VALID');
})
.on('submit', function(e) {
var ajaxRequest = $.ajax({
type: 'GET',
url: "....",
data: {xxx: yyy},
cache: false,
dataType: 'json',
});
....
ajaxRequest.done(function() {
if (ok) {
$('#check_this_field_with_ajax').parent().removeClass('error');
$('#my_form').attr({'submit_this_form': 'yes'});
$(document).foundation('abide', 'reflow');
$('#my_form').trigger('submit.fndtn.abide');
}
});
}
</script>
Now go to in foundation.abide.js, search line "validate : function (els, e, is_ajax) {" and add:
if (
is_ajax &&
form.attr('submit_this_form') === 'yes'
) {
return true;
}
before
if (is_ajax) {
return false;
}