I am trying to validate list of dynamic text fields.
Validation needs an AJAX call to interact with server.
At the backend I have written just one php file that reads the input request data and performs operation. Below is the example.
abc.js
row_count = 6
for (i = 1; i <=row_count; i++) {
id = "#val"+i.toString() ;
$(id).change(function(){
input_val="random";
$.ajax({
url:"url.php",
type:post,
async:true,
dataType: 'json',
data : {temp:input_val},
success:function(result){},
error: function (request, status, error) {}
});
});
}
url.php
<?php
$random_val = $_POST['temp'];
$cmd = 'systemcommand '.$random_val;
$flag = exec($cmd);
if ($flag == 0){
echo json_encode(array("status"=>'Fail'));
}
else{
echo json_encode(array("status"=>'Success'));
}
?>
It works fine when the row_count = 1 (Just one text field) but fails when the input is more than 1.
When the count is more than 1, the php script is not able to read the request data(The key in JSON data "temp"). it is blank in that case.
Any lead or help should be appreciated.
Thanks
Your javascript bit needs some adjusting, because you do not need to define an ajax for every single element. Use events based on a class. Also, since input behave differently than select, you should setup two different event class handlers.
function validateAjax ( element ) {
var input_val = element.val();// get the value of the element firing this off
$.ajax({
url: "url.php",
type: 'post',
async: true,
dataType: 'json',
data : { temp: input_val },
success: function(result) {
// check your result.status here
},
error: function (request, status, error) { }
});
}
$(".validate_change").on("change",function() { // for selects
validateAjax( $(this) );
});
$(".validate_input").on("input",function() { // for text inputs
validateAjax( $(this) );
});
And for your select or input you add that appropriate class.
<select class="validate_change" name="whatever"><options/></select>
<input class="validate_input" name="blah">
PS
I really worry about this code you have:
$cmd = 'systemcommand '.$random_val;
$flag = exec($cmd);
So, you are just executing anything that is coming in from a webpage POST var??? Please say this website will be under trusted high security access, and only people using it are trusted authenticated users :-)
I made an AJAX filter for woocommerce, which filters products based on attributes.
The query works fine, and it always prints the right products and content. That it actually prints something.
Every once i a while it will run but not add any html. If i log the data received it's clearly there. Sometimes the html() function just doesnt do anything.
It seems the error occurs more often if i doubleclick the filter button before it's done with its previous operation. I've tried adding a data attribute to check if the ajax is done filtering, to stop any calls from happening before the first is done. It doesn't seem to really work though.
The AJAX function:
function getPosts(page){
var filter = $('#filter');
if(filter.length < 1){
return false;
}
if(filter.data('loading') == true){
return false;
}
var buttonText = $('#filter #product-ajax-submit').text();
$.ajax({
url:filter.attr('action'),
data:filter.serialize() + '&page=' + page, // form data
type:filter.attr('method'), // POST
dataType: 'json',
beforeSend:function(xhr){
filter.attr('data-loading', true);
filter.find('#product-ajax-submit').text('Filtrerer...'); // changing the button label
$('#bbh-ajax-loader').fadeIn(200, function(){
var productsHeight = $('ul.products').outerHeight();
$('ul.products').parent().css('height', productsHeight);
$('ul.products').html(''); // delete current content
$('.woocommerce-pagination').html('');
});
},
success:function(data){
$('ul.products').empty().append(data[0]);
filter.find('#product-ajax-submit').text(buttonText); // changing the button label back
$('.woocommerce-pagination').html(data[1]);
$('ul.products').parent().css('height', 'auto');
$('#bbh-ajax-loader').fadeOut(300);
filter.find('select, button').prop( "disabled", false );
},
error:function(data){
$('ul.products').html(data.responseText);
$('ul.products').parent().css('height', 'auto');
$('#bbh-ajax-loader').fadeOut(300);
// insert data
filter.find('#product-ajax-submit').text(buttonText);
},
complete:function(data){
filter.attr('data-loading', false);
}
});
}
$('#filter[data-live-sort="false"]').on('submit', function(){
getPosts(1);
return false;
});
As I said, if I log the returned data, the markup is always correct. Both on success and error. I suspect maybe clearing the html from ul.products on beforeSend could create problems with the success data being displayed if multiple calls are made simultaniously.
I' m using cms ModX and want to send Ajax request to server using post method. The problem is that the post data of the second, the third and so one requests doesn't change and remains the same as in the first request.
To clarify the situation I provide the following example.
The javascript is the following:
var reqCount = 0;
$(document).ready(function () {
$(window).scroll(function() {
var dataToPost = {'reqCount' :reqCount};
$.ajax({
url: 'http://example.com/ajaxTest',
method: 'POST',
data: dataToPost,
dataType:"json",
success: function(data){
ajaxCountFromServer = data['ajaxCount'];
reqCount=reqCount+1;
}
});
}
}
Also I created resource with address http://example.com/ajaxTest in Modx with the code, running the snippet:
[[getAJAX]]
getAJAX snippet is the following:
<?php
if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
$reqCount = $_REQUEST['reqCount'];
$json_obj = array("ajaxCount" =>$reqCount);
return json_encode($json_obj);
}
?>
So, after the first scroll reqCount=0, it's passed to server and after the server responses(success callback) ajaxCountFromServer=0 and reqCount=1. There all works well.
However, after the second scroll reqCount=1 and after the server response ajaxCountFromServer=0,but it should be 1.
How to fix it?
The solution is quite simple. In the page customizing of the resource http://example.com/ajaxTest, where snippet getAJAX is called, I just unchecked the checkbox "Cacheable".
The correct way to do it is
[[!getAJAX]]
The snippet is not cached now
At this moment I am using laravel. In this context I am having a form which is successfully submitted by using ajax to a controller. and that controller make it to the database. But the problem is as the ajax is doing its job the whole page remain unmoved / unchanged after the submission even the database is updated.
Now what I want
I want to give feedback to the user that your post is successfully submitted there. or what I want to do in further, I want to refresh the section in which the post is collected from the database as this post can be retrieved from there. But by using ajax only.
So there is no need to collect the whole page or refresh.
here is my form structure
`
{{ Form::open(array('route' => array('questions.store'), 'class' => 'form-horizontal' )) }}
blah blah blaaa .......
<script type="text/javascript">
$(".form-horizontal").submit(function(e){
$(this).unbind("submit")
$("#ask").attr("disabled", "disabled")
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;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response){
console.log(response);
}
});
return false;
});
</script>
{{ Form::close() }}
`
As it is very much visible that the post is updated through a route & controller I want to have another dive and a success message at this script to be displayed after the success of posting. I am looking for some professional structure using what there is minimal need to have interaction with the server side and give user a better page viewing experience.
Thanks a lot for helping me in this research.
I am not sure if I understand you well, but if you want to notify the user about the result of an ajax-called db update you need to have
a route for the ajax save db call - it should point to a method that does the db update.
the db update method should return some value indicating the success/failure of update (for example OK or FAIL)
the only result of calling the method will be just plain text page with OK or FAIL as body
fetch the result by ajax and inform user accordingly (after form submit button)
check out the below code for ajax call itself (inside the form submit handler) to see what I mean
var db_ajax_handler = "URL_TO_YOUR_SITE_AND_ROUTE";
var $id = 1; //some id of post to update
var $content = "blablabla" //the cotent to update
$.ajax({
cache: false,
timeout: 10000,
type: 'POST',
tryCount : 0,
retryLimit : 3,
url: db_ajax_handler,
data: { content: $content, id: $id }, /* best to give a CSRF security token here as well */
beforeSend:function(){
},
success:function(data, textStatus, xhr){
if(data == "OK")
{
$('div.result').html('The new Question has been created');
}
else
{
$('div.result').html('Sorry, the new Question has not been created');
}
},
error : function(xhr, textStatus, errorThrown ) {
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
alert("Error 500: "+xhr.status+": "+xhr.statusText);
} else {
alert("Error: "+xhr.status+": "+xhr.statusText);
}
},
complete : function(xhr, textStatus) {
}
});
EDIT: as per comment, in step 2 (the method that is called with AJAX) replace
if($s)
{
return Redirect::route('questions.index') ->with('flash', 'The new Question has been created');
}
with
return ($s) ? Response::make("OK") : Response::make("FAIL");
EDIT 2:
To pass validation errors to the ajax-returned-results, you cannot use
return Response::make("FAIL")
->withInput()
->withErrors($s->errors());
as in your GIST. Instead you have to modify the suggested solution to work on JSON response instead of a plain text OK/FAIL. That way you can include the errors in the response and still benefit from the AJAX call (not having to refresh the page to retrieve the $errors from session). Check this post on the Laravel Forum for a working solution - you will get the idea and be able to fix your code.
I have the following code making a GET request on a URL:
$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val());
});
But the returned result is not always reflected. For example, I made a change in the response that spit out a stack trace but the stack trace did not appear when I clicked on the search button. I looked at the underlying PHP code that controls the ajax response and it had the correct code and visiting the page directly showed the correct result but the output returned by .load was old.
If I close the browser and reopen it it works once and then starts to return the stale information. Can I control this by jQuery or do I need to have my PHP script output headers to control caching?
You have to use a more complex function like $.ajax() if you want to control caching on a per-request basis. Or, if you just want to turn it off for everything, put this at the top of your script:
$.ajaxSetup ({
// Disable caching of AJAX responses
cache: false
});
Here is an example of how to control caching on a per-request basis
$.ajax({
url: "/YourController",
cache: false,
dataType: "html",
success: function(data) {
$("#content").html(data);
}
});
One way is to add a unique number to the end of the url:
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&uid='+uniqueId());
Where you write uniqueId() to return something different each time it's called.
Another approach to put the below line only when require to get data from server,Append the below line along with your ajax url.
'?_='+Math.round(Math.random()*10000)
/**
* Use this function as jQuery "load" to disable request caching in IE
* Example: $('selector').loadWithoutCache('url', function(){ //success function callback... });
**/
$.fn.loadWithoutCache = function (){
var elem = $(this);
var func = arguments[1];
$.ajax({
url: arguments[0],
cache: false,
dataType: "html",
success: function(data, textStatus, XMLHttpRequest) {
elem.html(data);
if(func != undefined){
func(data, textStatus, XMLHttpRequest);
}
}
});
return elem;
}
Sasha is good idea, i use a mix.
I create a function
LoadWithoutCache: function (url, source) {
$.ajax({
url: url,
cache: false,
dataType: "html",
success: function (data) {
$("#" + source).html(data);
return false;
}
});
}
And invoke for diferents parts of my page for example on init:
Init: function (actionUrl1, actionUrl2, actionUrl3) {
var ExampleJS= {
Init: function (actionUrl1, actionUrl2, actionUrl3) ExampleJS.LoadWithoutCache(actionUrl1, "div1");
ExampleJS.LoadWithoutCache(actionUrl2, "div2");
ExampleJS.LoadWithoutCache(actionUrl3, "div3");
}
},
This is of particular annoyance in IE. Basically you have to send 'no-cache' HTTP headers back with your response from the server.
For PHP, add this line to your script which serves the information you want:
header("cache-control: no-cache");
or, add a unique variable to the query string:
"/portal/?f=searchBilling&x=" + (new Date()).getTime()
If you want to stick with Jquery's .load() method, add something unique to the URL like a JavaScript timestamp. "+new Date().getTime()". Notice I had to add an "&time=" so it does not alter your pid variable.
$('#searchButton').click(function() {
$('#inquiry').load('/portal/?f=searchBilling&pid=' + $('#query').val()+'&time='+new Date().getTime());
});
Do NOT use timestamp to make an unique URL as for every page you visit is cached in DOM by jquery mobile and you soon run into trouble of running out of memory on mobiles.
$jqm(document).bind('pagebeforeload', function(event, data) {
var url = data.url;
var savePageInDOM = true;
if (url.toLowerCase().indexOf("vacancies") >= 0) {
savePageInDOM = false;
}
$jqm.mobile.cache = savePageInDOM;
})
This code activates before page is loaded, you can use url.indexOf() to determine if the URL is the one you want to cache or not and set the cache parameter accordingly.
Do not use window.location = ""; to change URL otherwise you will navigate to the address and pagebeforeload will not fire. In order to get around this problem simply use window.location.hash = "";
You can replace the jquery load function with a version that has cache set to false.
(function($) {
var _load = jQuery.fn.load;
$.fn.load = function(url, params, callback) {
if ( typeof url !== "string" && _load ) {
return _load.apply( this, arguments );
}
var selector, type, response,
self = this,
off = url.indexOf(" ");
if (off > -1) {
selector = stripAndCollapse(url.slice(off));
url = url.slice(0, off);
}
// If it's a function
if (jQuery.isFunction(params)) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if (params && typeof params === "object") {
type = "POST";
}
// If we have elements to modify, make the request
if (self.length > 0) {
jQuery.ajax({
url: url,
// If "type" variable is undefined, then "GET" method will be used.
// Make value of this field explicit since
// user can override it through ajaxSetup method
type: type || "GET",
dataType: "html",
cache: false,
data: params
}).done(function(responseText) {
// Save response for use in complete callback
response = arguments;
self.html(selector ?
// If a selector was specified, locate the right elements in a dummy div
// Exclude scripts to avoid IE 'Permission Denied' errors
jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
// Otherwise use the full result
responseText);
// If the request succeeds, this function gets "data", "status", "jqXHR"
// but they are ignored because response was set above.
// If it fails, this function gets "jqXHR", "status", "error"
}).always(callback && function(jqXHR, status) {
self.each(function() {
callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
});
});
}
return this;
}
})(jQuery);
Place this somewhere global where it will run after jquery loads and you should be all set. Your existing load code will no longer be cached.
Try this:
$("#Search_Result").load("AJAX-Search.aspx?q=" + $("#q").val() + "&rnd=" + String((new Date()).getTime()).replace(/\D/gi, ''));
It works fine when i used it.
I noticed that if some servers (like Apache2) are not configured to specifically allow or deny any "caching", then the server may by default send a "cached" response, even if you set the HTTP headers to "no-cache". So make sure that your server is not "caching" anything before it sents a response:
In the case of Apache2 you have to
1) edit the "disk_cache.conf" file - to disable cache add "CacheDisable /local_files" directive
2) load mod_cache modules (On Ubuntu "sudo a2enmod cache" and "sudo a2enmod disk_cache")
3) restart the Apache2 (Ubuntu "sudo service apache2 restart");
This should do the trick disabling cache on the servers side.
Cheers! :)
This code may help you
var sr = $("#Search Result");
sr.load("AJAX-Search.aspx?q=" + $("#q")
.val() + "&rnd=" + String((new Date).getTime())
.replace(/\D/gi, ""));