August 6, 2015

Dispose submit button with ajax-jquery and php

Dan Costinel’s Question:

I have the following code, for learning porpose. In short, I want to grab some data from a database, with the help of a drop-down menu. My problem is that now I’m using a submit button to make the submit action. And the improvement that I want, is to get rid of the submit button, and grab the infos when the drop-down changes.

I’ve tried to make a function for the code between line 1 and 12, and call it with: <body onload="process()">, but it’s not working. Then I tried to put the onchange="this.form.submit()" attribute to the <select> element, but this doesn’t work also, because it sends the data to process.php like any normal submission when not using ajax.
Anyone know any fix? Thank you!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body onload="viewdata()">
    <form action="process.php" method="post" id="form">
        <select name="select" id="select">
            <option value="">Choose</option>
            <option value="1">supervizor</option>
            <option value="2">sef locatie</option>
            <option value="3">muncitor</option>
            <option value="0">toti</option>
        </select><br/>
        <input type="submit" value="Go"/>
    </form>
    <script type="text/javascript">
    var frm = $('#form'); // **LINE 1**
    frm.submit(function (ev) {
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                $('#show').html(data);
            }
        });
        ev.preventDefault();
    });                    // **LINE 12**

    function viewdata(){
        $.ajax({
            type: "GET",
            url: "process.php"
        }).done(function( data ) {
            $('#show').html(data);
        });
    }
    </script>
    <br/><br/>
    <div id="show"></div>
</body>
</html>

You need to bind your processing on the change event of your drop down box.

$("#select").on("change", function(ev) {
    // Your ajax processing
    $.ajax({
        type: frm.attr('method'),
        url: frm.attr('action'),
        data: frm.serialize(),
        success: function (data) {
            $('#show').html(data);
        }
    });
    ev.preventDefault();
});
September 15, 2013

Can't get responseText from $.post

Andrey Yasinishyn’s Question:

I need to get a string from the server using jquery $.post, the issue is that I can’t get the responseText from it.
So if I run

role = $.post('user_helper/return_current_role', {id: 3}, null, "json").responseText;
console.log(role);

I get undefined
If I try

role = $.post('user_helper/return_current_role', {id: 3}, null, "json");
console.log(role);

I get an object Object { readyState=1, getResponseHeader=function(), getAllResponseHeaders=function(), more...}, where responceText is, for example, teacher.
Here is this response, copied from firebug:

readyState
    4

responseText
    "teacher"

status
    200

statusText
    "OK "

As it’s asynchronous, and has a callback function, how about:

$.post('user_helper/return_current_role', {id: 3}, function(result) {
    var role = result;
    console.log(role);
}).fail(function(a,b,c) {
    console.log(a);
    console.log(b);
    console.log(c);
});

You can not use the result of an ajax call, until it’s returned from the server.
It’s just how asynchronous calls work!

EDIT:

chained on a fail method, see if that tells you anything ?

You can do it this way too:

$.post('user_helper/return_current_role', {id: 3}, function(data) {
   var role = data; 
   // Now Do what you need
}, "json");

jQuery scripts on ajax content WITHOUT using $(document).on

Tonechild’s Question:

I am using an infinite scroll plugin which uses ajax.

When the ‘next page’ is loaded via ajax, all other ajax related scripts that are on the next page do not work. I have been told that I have to use ‘delegated events'(ie change $(id).click() to $(document).on) – problem is that means editing multiple plugins and changing dozens of function calls.

Is there any way I can avoid changing everything to $(document).on and do something cool with the infinite scroll?????

I’d much rather modify the infinite scroll plugin rather than modifying other ajax related plugins to make them fit.

Unfortunately you have very few options here, and switching to delegated events is by far the best of them.

The problem is that your old code was assigning behaviour to “particular elements” when what it should really have been doing is creating page-wide responses to “certain types of actions”.

I see 3 possibilities, and only one of them is guaranteed to work.

  1. Run any scripts that are needed on new pages each time a new page is loaded. The downside here being that unless you are careful about also “tearing down” between content loads you will have behaviours repeating or colliding with each other (eg: double popups, broken animations).
  2. Encapsulate the dynamic areas in <iframe>s. Depending on your architecture this may or may not be possible, and certainly won’t be easy to integrate with some kind of infinite scrolling plugin which already expects a certain page structure.
  3. Bite the bullet and fix the crappy code.

Loading scripts inside your ajax loaded content is a bad way to start with anyway. What you need is event delegation to attach itself to any dynamically added elements.

$("body").on("click", ".yourclass", function() {
    //This function will run for every element with `yourclass` class you load via ajax
});
September 12, 2013

$.post callback return strange data

Miguela Anthony’s Question:

I think this might be the cause of why my code is not working.. The ‘if(name.val().length > 3)’ is never can execute so I put an alert to test the returned data, this is what it look like :

enter image description here

my js

$(document).ready(function(){

    var form = $("#customForm");
    var name = $("#name");
    var nameInfo = $("#nameInfo");
    var email = $("#email");
    var emailInfo = $("#emailInfo");
    var pass1 = $("#pass1");
    var passInfo = $("#pass1Info");
    var pass2 = $("#pass2");
    var pass2Info = $("#pass2Info");
    var state = false;

name.keyup(validateName);

function validateName(){
    if(name.val().length <= 3){
        name.removeClass("valid");
        nameInfo.removeClass("valid");
        name.addClass("error");
        nameInfo.addClass("error");
        nameInfo.text("Minimum 4 characters!");
        state = false;

    }else{

        if(name.val().length > 3){
        var username=name.val();
            $.post('validate.php',{names: username},function(data){
                alert(data);
                if(data!=0){
                    name.removeClass("valid");
                    nameInfo.removeClass("valid");
                    name.addClass("error");
                    nameInfo.addClass("error");
                    nameInfo.text("The username is already taken!");
                    state = false;
                }else{
                    name.removeClass("error");
                    nameInfo.removeClass("error");
                    name.addClass("valid");
                    nameInfo.addClass("valid");
                    nameInfo.text("username available");
                    state = true;
                }
            });

        }
    }    
}
return state;

//end
});

my PHP code :

<?php 
$name = $_POST['names'];
$email = $_POST['emails'];

if($name !=""){
    mysql_connect("localhost","root","") or die("Fail to connect to database");
    mysql_select_db("reglog");

    $uname = mysql_query("SELECT username FROM users WHERE username='$name'");
    $count = mysql_num_rows($uname);

    if($count !=0){
        echo 1;
    }else{
        echo 0;
    }
}

if($email !=""){
    mysql_connect("localhost","root","") or die("Fail to connect to database");
    mysql_select_db("reglog");

    $useremail = mysql_query("SELECT email FROM users WHERE email='$email'");
    $countemail = mysql_num_rows($useremail);

    if($countemail !=0){
        echo 1; 
    }else{
        echo 0;
    }
}

?>

It is throwing an warning. Make a habit of checking if a index is available in an array, thus removing possibilities of such error.

$email = isset($_POST['emails']) ? $_POST['emails'] : '';

or do not display any errors to suppress such warning (not recommended).

And as mentioned by Kai, you haven’t passed any variables as emails.

$.post('validate.php',{ names: username, 'emails' : email }, ... }
May 31, 2013

Calling ajax once

User2310422’s Question:

I have created a button on my website when it is clicked, I sent data on some php file using ajax and return the results. The code I am using is below,

My Goal :

  1. When that button is clicked for the first time. I want to send the data on some php file using ajax and return the results, and
  2. When it is clicked for the second time, I just want to hide the content, and
  3. When it is clicked for the third time, I just want to show the container without calling the ajax again.

jQuery:

$(function() {
    $('#click_me').click(function(){
        var container = $('#container').css('display');
        var id = $('#id').html();
            if(container == 'none'){
                $.ajax({
                type: 'POST',
                data: {id: id},
                url: "ajax/get_items.php",
                }).done(function(data) {
                $('#container').html(data);
                }).success(function(){
                $('#container').show('fast');
                });
                }else if(container == 'block'){
        $('#container').hide('fast');
        }
        });
});

Html :

<input type="button" id="click_me" value="Click Me"/>
<div id="container"></div>

You can do this by defining a simple variable counting the clicks.

$(function() {
    var clickCount = 1; //Start with first click

    $('#click_me').click(function(){
        switch(clickCount) {
             case 1: //Code for the first click

                 // I am just pasting your code, if may have to change this
                 var container = $('#container').css('display');
                 var id = $('#id').html();
                     if(container == 'none'){
                         $.ajax({
                         type: 'POST',
                         data: {id: id},
                         url: "ajax/get_items.php",
                         }).done(function(data) {
                         $('#container').html(data);
                         }).success(function(){
                         $('#container').show('fast');
                         });
                         }else if(container == 'block'){
                 $('#container').hide('fast');
                 }
              break;
              case 2: 
                 //code for second click
                 break; 
              case 3:
                 //Code for the third click
                 break;      
        });
        clickCount++; //Add to the click.
});
May 21, 2013

jQuery complete replace DOM of element with another DOM – faster way?

Tomis’s Question:

I’m using jQuery’s AJAX for getting new content from server. Data is loaded in JSON:

$.ajax({
    url: url,
    data: {
        'ajax': '1',
    },
    dataType: 'json',
    success: somefunction
});

For server-side application limitation, I’m not able to setup more JSON variables inside so I have to load everything into content. That is why I have to load result into jQuery, than search and replace some elements on page, like this (used in somefunction):

var somefunction = function(data) {
    var con = $('<div></div>').html(data.content); // just $(data.content) is not working
    $('div#mainContent').html(con.find('div#ajax-content').html());
    ... // same process with three more divs
}

EDIT: Please, note that I have to do same process to replace three divs!

There is more about that, but as example, it’s enough I hope. My question: For some logic way, I expect that loading result into DOM ($(data.content)), parsing to html (con.find('dix#ajax-content').html()) and back to DOM ($('div#mainContent').html()) seems to me like loosing some resources and decreasing the perfomance so I would like to know if there is any faster way to do it and load DOM directly, like:

$('div#mainContent').dom(con.find('div#ajax-content').dom());

I tried to google it but maybe I don’t know what to type in. Also jQuery documentation does not helped me a lot.

Some facts:

  • jQuery 1.9.1
  • jQuery UI 1.10.3 available

Finally, I know that it would be much more better to do something with server-side app to provide more JSON variables, however, I need to write not-so-easy peace of code which is requiring longer time to develop which I don’t have right now. Doing it on client side would be temporary solution for now, however, I don’t want to decrease performace a lot.

Side-question:

is it correct to use find() function in this case or there is any better one?

EDIT 2 (not working parsing string)
I’m expecting this working but it’s not:

content = '<div id="ajax-title">Pečivo běžné, sladké, slané</div>
<div id="ajax-whereami"><a href="/category/4">Chléba a pečivo</a> » Pečivo běžné, sladké, slané</div>';
$(content);

Actually, $(data.content) should work just fine, but you have to keep in mind that the top level elements can only be reached via .filter() instead of .find(). If the elements you wish to target are at least one level deeper than the root you should use .find() though; in the examples below you can replace .filter() with .find() where appropriate.

var $con = $(data.content);
$('div#mainContent')
  .empty()
  .append($con.filter('div#ajax-content'))
  .append($con.filter('div#another-id'))
  .append($con.filter('div#and-another-id'));

You can also combine the selectors together:

  .append($con.filter('div#ajax-content, div#another-id, div#and-another-id'));

Lastly, since identifiers should only appear once inside a document, you can drop the div part:

  .append($con.filter('#ajax-content, #another-id, #and-another-id'));

Update

Okay, it seems that jQuery doesn’t evaluate data.content properly when there are newlines in the wrong places; this should work in all cases:

var wrapper = document.createElement('div');
wrapper.innerHTML = data.content;

var $con = $(wrapper);

No, There aren’t any other way that will speed up the performance.

In order to traverse along the content, the content has to be loaded somewhere. So what you are doing is perfectly valid.

April 4, 2013

$.ajax doesn't response

Nurhidayat Fembrianto’s Questions:

i have some code here that doesn’t work at all:

    <script type="text/javascript">
    function get_all(){
        var mutation = document.getElementById("mutation");
        $.ajax({
            url:"http://localhost/mandala/test/xx",
            success: function(msg){
                mutation.innerHTML = msg;
            },
            error: function(x,status,error){
                alert(status+":"+error);
            }
        });

    }
</script>

<html>
    <body>
        <input type="button" onclick="get_all()" value="Click">
        <div id="mutation">

        </div>
    </body>
</html>

I don’t think so if there is any problem with my url neither the code. But i hope some body can help me out with this problem.

Your HTML Structure in invalid. At the time of Script execution, it will not find the element. So use this instead.

function get_all(){
    $.ajax({
        url:"http://localhost/mandala/test/xx",
        success: function(msg){
            $("#mutation").html(msg); //<!-- jQuery Selector
        },
        error: function(x,status,error){
            alert(status+":"+error);
        }
    });

}
March 27, 2013

Ajax Animation JQuery 1.9.2

Question by Chris Nevill

How would i upgrade the solution provided in this question
jQuery "Please Wait, Loading…" animation?

to work with JQuery 1.9.2?

I can’t seem to get it to work.
I’ve tried the following
http://jsfiddle.net/VpDUG/2485/

$(document).ajaxStart(function(){   $("body").addClass("loading"); });
$(document).ajaxStart(function(){   $("body").removeClass("loading"); });

but that hasn’t worked?

Answer by jfriend00

I think you meant to do this (using ajaxStop() for the second one):

$(document).ajaxStart(function(){   $("body").addClass("loading"); });
$(document).ajaxStop(function(){   $("body").removeClass("loading"); });

See it working here on a modified version of your jsFiddle: http://jsfiddle.net/jfriend00/gk3RL/


Also, a little more efficient to use document.body instead of "body":

$(document).ajaxStart(function(){   $(document.body).addClass("loading"); });
$(document).ajaxStop(function(){   $(document.body).removeClass("loading"); });

Answer by Starx

The second event should be ajaxComplete

$(document).ajaxComplete(function(){   $("body").removeClass("loading"); });
March 18, 2013

jQuery Ajax Appears to be POSTing but can't catch the values

Question by MG55114

What am I missing here?

I am trying to pass an array of strings via a jQuery AJAX POST.

var json = JSON.stringify( selectedTags );
var data = json;

var apiCall = $.ajax({
    url: "service-getemails-multiple.php",
    data: data,
    type: "POST"
    //beforeSend: alert(data)
}).done(function(data) {
    $(".ui-dialog-titlebar-close").show();
    var html = '<textarea style="width: 100%; height: 90%" id="emailsTextbox">' + data + '</textarea>';
    html += data;
    html += "" target="new">Send Email</a></p>";
    $("#dialog").html(html);
    $("#emailsTextbox").focus();
    $("#emailsTextbox").select();
});

My catcher (“service-getemails-multiple.php”) is currently extremely simple and I don’t understand why it’s failing to catch the AJAX request (POST).

<?php

var_dump($_POST);

?>

In Firebug, I can see the values being passed under XHR/Post as parameters and under source. If I uncomment “beforeSend: alert(data)” that alerts the values just fine.

So what am I doing wrong?

Answer by ITroubs

try this:

var json = JSON.stringify( selectedTags );
var thedata = json;
....
var apiCall = $.ajax({
    url: "service-getemails-multiple.php",
    data: {mydata: thedata},
    type: "POST"
    //beforeSend: alert(data)
}).done(function(data) {
    $(".ui-dialog-titlebar-close").show();
    var html = '<textarea style="width: 100%; height: 90%" id="emailsTextbox">' + data + '</textarea>';
    html += data;
    html += "" target="new">Send Email</a></p>";
    $("#dialog").html(html);
    $("#emailsTextbox").focus();
    $("#emailsTextbox").select();
});

Answer by Starx

I think the function is confused about data: data part.

Try this

var apiCall = $.ajax({
    url: "service-getemails-multiple.php",
    data: json, // <!-- Use json instead. Its the same thing
    type: "POST"
    //beforeSend: alert(data)
}).done(function(data) {
    $(".ui-dialog-titlebar-close").show();
    var html = '<textarea style="width: 100%; height: 90%" id="emailsTextbox">' + data + '</textarea>';
    html += data;
    html += "" target="new">Send Email</a></p>";
    $("#dialog").html(html);
    $("#emailsTextbox").focus();
    $("#emailsTextbox").select();
});
March 16, 2013

OnClick fopen fread fwrite fclose

Question by artur99

I have a image:

 <img src="imagini/floo.gif" onclick="score()">

and i want “on click” to be opened a file “c.txt”.
That file’s content is:
0

And i want on every click, to be added 100 in c.txt.

I want something like this:

 <img src="imagini/floo.gif" onclick="score()">
<script> function score(){ (..do file add.php ...) }</script>

And add.php:

<?php
$c = "c.txt";
$fh = fopen($c, "r");
$current = fread($fh, filesize($c));
fclose($fh);
$current++;
$fh = fopen($c, "w");
fwrite($fh,$current);
fclose($fh);
?>

What to put in place: “(..do file add.php …)” for the code to work?

Answer by Starx

You need to send an AJAX request to process the file. Here is a jQuery version of the code:

function score() {
    $.post("add.php", function(data) {
       //This callback executes after the request was successfull
       // echo something back to read from here as `data`
       console.log(data);
    });
}
...

Please fill the form - I will response as fast as I can!