Jquery validation for div - javascript

I've set up a page with a bunch of contenteditbale divs, along with some js/ajax functionality so that a user can inline edit.
<div class="inlineEdit" contenteditable="true"></div>
JS is a s such:
$(document).ready(function(){
$('div.inline-edit').blur(function()
{
var pathArray = window.location.pathname.split( '/' );
var segment_3 = pathArray[3];
var editableObj = $(this);
var token_input = $('input.token');
var save_data ={};
var token_name = token_input.attr('name');
save_data['field'] = editableObj.attr('id');
save_data['id'] = editableObj.closest('.inline-id').attr('id');
save_data['editedValue'] = editableObj.text();
$.ajax({
url: segment_3+'/update',
type: 'POST',
data:save_data,
success: function(){
//on success functionality
}
});
});
});
This part all works perfectly grand, all the right fields get updated with the right info. All i need is some way to validate that information before it get to the ajax
I know of JQuery Validation however I'm pretty sure it doesn't work with divs.
Is there a solution or am I stuck/have to change up the divs?

You can create a temporary input box and pass the value through it to check validity. I wrote a function to use HTML5 validation to check for validity.
function validityChecker(value, type) {
type = type?type:'text'
$('body').append('<input id="checkValidity" type="'+type+'" style="display:none;">');
$('#checkValidity').val(value)
validity = $('#checkValidity').val()?$('#checkValidity').val().length>0:false && $('#checkValidity')[0].checkValidity()
$('#checkValidity').remove();
return validity;
}
In your case use like this:
if(validityChecker(save_data['editedValue'], 'number')){ // if you want to check for number
$.ajax({
url: segment_3+'/update',
type: 'POST',
data:save_data,
success: function(){
//on success functionality
}
})
}
Demo:
function validityChecker(value, type) {
type = type?type:'text'
$('body').append('<input id="checkValidity" type="'+type+'" style="display:none;">');
$('#checkValidity').val(value)
validity = $('#checkValidity').val()?$('#checkValidity').val().length>0:false && $('#checkValidity')[0].checkValidity()
$('#checkValidity').remove();
return validity;
}
save_data = 'This is not a number';
alert(validityChecker(save_data, 'number')) // false
alert(validityChecker(save_data, 'text')) // true
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

POST output into a modal from any form class on page

Sorry I am a beginner with jQuery and Javascript. I want to be able to get the results into my modal from any form on the page that has class ajax. My code is below but not working correctly. Currently it opens the post result in a new page and not in the modal. Can anyone shed any light on my code?
Many thanks
$(document).ready(function() {
$('.ajax').click(function() {
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;
});
console.log(value);
// AJAX request
$.ajax({
url: url,
type: type,
data: data,
success: function(response){
// Add response in Modal body
$('.modal-body').html(response);
// Display Modal
$('#aaModal').modal('show');
}
});
});
});
This probably happens because your browser submits the form by default. It doesnt know youre doing AJAX stuff. To prevent this, use preventDefault().
In addition to that, jQuery has a built in function for serializing (1 and 2) form data.
$(document).ready(function() {
$('form.ajax').click(function(event) {
event.preventDefault(); // prevents opening the form action url
var $form = $(this),
url = $form.attr('action'),
type = $form.attr('method'),
data = $form.serialize();
// console.log(value); // value doesnt exist outside of your loop btw
// AJAX request
$.ajax({
url: url,
type: type,
data: data,
success: function(response){
// Add response in Modal body
$('.modal-body').html(response);
// Display Modal
$('#aaModal').modal('show');
}
});
});
});
Also, its not quite clear if you bind the click event handler to a form or a button, I guess the first one. You should change the handler to the following:
$(document).ready(function() {
$('form.ajax').on('submit', function(event) {

How to Replace Form Without Triggering the Change Event?

I would like to validate a form with an AJAX request to the server and then swap the form html in the web browser with the form html from the server because this would be an easy implementation in theory. It is proving a nightmare though because the change event is triggered without the user interacting further after the first interaction which triggered the first change event. Consequently an infinite loop of AJAX requests to the server is happening.
The html form sits inside a div which has classes 'container mb-4'. This is the JS code -
var _cont = $('.container.mb-4')
var _form = $('.custom-form')
function ajax_validation(form) {
form.on('change', 'input, select, textarea', function() {
form_data = form.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.empty()
_cont.append(data['form_html'])
form = _cont.find('form')
ajax_validation(form)
}
},
error: function () {
form.find('.error-message').show()
}
});
})
}
ajax_validation(_form)
The change event I am assuming is triggered because the server returns a form input field with a different csrf token as the value to the previous input field - all other fields are the same. So an obvious solution would be to keep the same csrf token. But I want to understand why the JS code isn't working. I thought destroying the form would destroy the change event bound to it. So am at a loss to explain this infinite loop. How do I change this so I can just swap the form and not trigger another change event until the user really does change something?
It's not a good thing to use events in function no need to do that
Also your event here for input , select , textarea for serialize you need to select the closest() form
Try the next code
var _cont = $('.container.mb-4');
var _form = $('.custom-form');
_cont.on('change', 'form input,form select,form textarea', function() {
var ThisForm = $(this).closest('form');
var form_data = ThisForm.serialize();
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.html(data['form_html']);
}
},
error: function () {
ThisForm.find('.error-message').show()
}
});
});
And logically if(!(data['success'])) { should be if(data['success']) {
First let's understand the issue that you have. You have a function called ajax_validation that is defining a change event on the form's elements which, on response will call ajax_validation. So, if any change happens on your elements, then a new request is sent to the server. So, if any value is changed, like a token, the request will be sent again. You could use a semaphore, like this:
var semaphore = true;
function ajax_validation(form) {
form.on('change', 'input, select, textarea', function() {
if (!semaphore) return;
semaphore = false;
form_data = form.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.empty()
_cont.append(data['form_html'])
form = _cont.find('form')
ajax_validation(form)
}
semaphore = true;
},
error: function () {
form.find('.error-message').show()
}
});
})
}
Something like this should solve your issue for the time being, but you should consider refactoring your code, because what you experience is well-known and is called callback hell.
Turns out the password field was coming back blank from the server - this django must do out of the box if the PasswordInput widget is used. So the form is replaced with a new form which lacks the password input from the before. The browser was then applying the autofill password value to the form which was triggering the change event.
This is my code now. It checks that the form_data about to be sent for validation really is different to before minus the csrf token which will be different.
It is based on Mohamed's answer -
var _cont = $('.container.mb-4');
var _form = $('.custom-form');
var prev_data = undefined
_cont.on('change', 'form input,form select,form textarea', function() {
var ThisForm = $(this).closest('form');
var form_data_wo_csrf = ThisForm.find("input, textarea, select").not("input[type='hidden']").serialize()
if(form_data_wo_csrf == prev_data) {
return
}
var form_data = ThisForm.serialize()
$.ajax({
url: "/form/6/",
type: "POST",
data: form_data,
success: function(data) {
if(!(data['success'])) {
_cont.html(data['form_html']);
prev_data = form_data_wo_csrf
}
},
error: function () {
ThisForm.find('.error-message').show()
}
});
});

How can I validate form using JS and after that with PHP and Ajax?

I have an HTML form which I am validating using JavaScript like below code. All the JavasCript code is in an app.js file.
App.js file
function validateForm () {
var amount = document.forms["salesform"]["amount"];
var buyer = document.forms["salesform"]["buyer"];
var buyerRegex = /^[a-zA-Z0-9_ ]*$/;
var receipt_id = document.forms["salesform"]["receipt_id"];
var receiptIdRegex = /^[a-zA-Z_ ]*$/;
let items = document.querySelectorAll(".items")
var itemsRegex = /^[a-zA-Z_ ]*$/;
var buyer_email = document.forms["salesform"]["buyer_email"];
var note = document.forms["salesform"]["note"];
var city = document.forms["salesform"]["city"];
var cityRegex = /^[a-zA-Z_ ]*$/;
var phone = document.forms["salesform"]["phone"];
var phoneRegex = /^[0-9]*$/;
var entry_by = document.forms["salesform"]["entry_by"];
var entryByRegex = /^[0-9]*$/;
function validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(String(email).toLowerCase());
}
if (amount.value == "") {
alert("Please enter the amount.");
amount.focus();
return false;
} else if (isNaN(amount.value)) {
alert("Amount must be only numeric value.");
amount.focus();
return false;
} else if (amount.length > 10 ) {
alert("Amount must be less than 10 characters long.");
amount.focus();
return false;
}
// more validation.....
return true;
}
In this file I have another jQuery Ajax code validate the form using Server. So that I have added following Ajax code blow that JS validation code:
$("#salesForm").submit(function(e) {
e.preventDefault();
$.ajax({
url : '../process/add-data.php',
type: 'POST',
dataType: "html",
data : $(this).serialize(),
beforeSend : function () {
$(".formResult").html("Please wait...");
},
success : function ( data ) {
$(".formResult").html( data );
}
});
});
for the HTML form
<form name="salesform" id="salesForm" onsubmit="return validateForm();" method="POST">
Now when the form is validating using JavaScript then it also vaidating the form using Ajax.
But first its should validate using JavaScript and then Ajax.
Remove onSubmit from the element and modify your Ajax function to return invalid form BEFORE making the call.
$("#salesForm").submit(function(e) {
e.preventDefault();
if(!validateForm()) return;
$.ajax({
url : '../process/add-data.php',
type: 'POST',
dataType: "html",
data : $(this).serialize(),
beforeSend : function () {
$(".formResult").html("Please wait...");
},
success : function ( data ) {
$(".formResult").html( data );
}
});
});
You need to return false inside beforeSend callback, as it is described in official jQuery documentation:
beforeSend Type: Function( jqXHR jqXHR, PlainObject settings )
A pre-request callback function that can be used to modify the jqXHR (in
jQuery 1.4.x, XMLHTTPRequest) object before it is sent. Use this to
set custom headers, etc. The jqXHR and settings objects are passed as
arguments. This is an Ajax Event. Returning false in the beforeSend
function will cancel the request. As of jQuery 1.5, the beforeSend
option will be called regardless of the type of request.
So, you need to do something like this:
beforeSend : function () {
$(".formResult").html("Please wait...");
if(!validateForm()) {
// Here you remove your "Please wait..." message
return false;
}
// Or simply return the value from validateForm():
// return validateForm();
},
And, of course, remove the onsubmit="return validateForm();" from your form tag.

Value posts firstly and then only it finishes input (if clicked). needed backwards(code is corect)

I have dropdown list of country suggestions and input above. When i click on one of them - AJAX should work(and it does) and add value to #msg_native. HTML:
echo '<div class="search_native"><input type="text" name="native_input" id="native"/>';
echo "<div id='output'></div></div>";
All JQUERY :
<script type="text/javascript">
$(document).ready(function() {
$("input").keyup(function(){
$array = ['usa','france','germany'];
$input_val = $("input[name='native_input']").val();
$('#output').text('')
r = new RegExp($input_val)
for (i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>')
}
}
});
$(document).on('click', '.match', function(){
$value = $(this).text();
$('#native').val($value);
});
});
</script>
<script type="text/javascript">
$(function() {
$('#native').change(function() {
alert('cl');
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: {native_input: $("input[name='native_input']").val()},
cache: false,
success: function(data){
alert(data);
$("#msg_native").after(data);
}});
return false;
});
});
</script>
The problem is that the value that gets posted is only what Ive typed myself, regardless on clicked element. But I want complete value- not only typed letters...so it firstly posts value and then 'finishes' the input (if clicked)
What can you practically advice to me?
data: {native_input: $value},
returns empty string
Some of this might be debatable but I put those in place for maintainability of the code and/or to match the most recent jQuery.
Only use one document ready handler (if possible)
Remove all the global objects (put var in front of them)
Use the native id when possible as fastest selector (not $("input[name='native_input']") for instance)
use this in the event handler, not the full selector (see next item)
If I enter "France" not "france" match does not work so need to case that input to equality var $input_val = $(this).val().toLowerCase();
You start with an empty field, might be good to show the match for that - simply trigger the keyup on startup to show all the array: }).trigger('keyup'); Now they are available for your clicking.
Attach the click handler on the wrapper for the "match" elements: $('#output').on('click', '.match', function() {
Use the promise form of the ajax .done(
Create a new custom event instead of the "change" on the native. We can then trigger that event as/when needed (the real issue you describe) Example: $('#native').trigger('myMatch'); and as I use it here:
trigger the event on a full match:
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
Revised code:
$(document).ready(function() {
$("#native").on('keyup', function() {
var $array = ['usa', 'france', 'germany'];
var $input_val = $(this).val().toLowerCase();
$('#output').html('');
var r = new RegExp($input_val);
for (var i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>');
}
}
// full match entered, trigger the match
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
}).on('myMatch', function() {
alert('cl');
var nativeMatch = {
native_input: $("#native").val()
};
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: nativeMatch,
cache: false
}).done(function(data) {
alert(data);
$("#msg_native").after(data);
});
return false;
}).trigger('keyup');
$('#output').on('click', '.match', function() {
var $value = $(this).text();
$('#native').val($value).trigger('myMatch');
});
});

Automatically submit input on page open with javascript

I have this code
var file = getUrlVars()["file"];
if(file){
document.getElementById('search').value = file;
}
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
It reads the parameter file from url and then puts the value in the search field.
The search field is ajax powered, when a user enters a letter it starts searching and outputs results.
The problem is that when the scripts puts the value in the search field nothing happens, how do i make the search to fire up?
This is my search field
<input type="text" id="search" class='search_input' />
UPDATE:
My Ajax search code is this
// Search
$(document).ready(function()
{
$(".search_input").focus();
$(".search_input").keyup(function()
{
var search_input = $(this).val();
var keyword= encodeURIComponent(search_input);
var yt_url='http://domain.com/search.php?q='+keyword;
$.ajax({
type: "GET",
url: yt_url,
success: function(response)
{
$("#result").html('');
if(response.length)
{
$("#result").append(response);
}
else
{
$("#result").html("<div id='no'>No results</div>");
}
}
});
});
} );
Your search will only "fire" if the event that initilizes the AJAX functionality is triggered. Thus, you need to trigger the event. My wild guess is the event is bound to either:
- keyup
- click
- blur
You haven't posted the relevant code, but that should be enough of an answer...
After your update
A quick solution is to initiate the keyup event on the search field:
$(".search_input").keyup(function() { ... }).keyup();
Or, you could re-factor the code:
function searchlogic() { ... };
$(".search_input").keyup(searchlogic);
searchlogic();

Categories