September 15, 2013

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
});
June 29, 2013

Ajax response error

TNK’s Question:

I need to make a mysql query according to the value of dropdown list. Here I use ajax to send dropdown value to the server. I think this part is working for me. But problem is I can not get it to php. Note: both are in the same page.

This is my Jquery code :

$('#filter-value').change(function(){
    var filterValue = $(this).val();
    //console.log(filterValue); 

    $.ajax({
        type: 'post',
        dataType: 'html',
        data: {filter: filterValue},
        success:function(data){ 
            alert(data); 
        }, 
        error:function (xhr, ajaxOptions, thrownError){
            //On error, we alert user
            alert(thrownError);
        }, 
        complete: function(){
            //alert('update success'); 
        }
    });
});

This is HTML form

    <form method="post" action="">
        <select id="filter-value" name="filter">
            <option value="10">10</option>
            <option value="20">20</option>
            <option value="30">30</option>              
        </select>
    </form>

This is my PHP code that I am trying on the top of the page :

if (isset($_POST['filter'])) {
    $filter = $_POST['filter']; 
    echo $filter; 
    exit;
} else {
    echo 'bad';
}

But this php code is always going to else part and print ‘bad’

Can anybody tell me where I am going wrong?

Thank you.

You have missed to specify the URL of the script. Be ensure that you are querying the correct file from the AJAX.

$.ajax({
    type: 'post',
    url: 'yourpage.php', // This one 
    //.....
});
May 29, 2013

Jquery Select Box not working on dynamically generated elements

Yaar Mallang Jeha’s Question:

I am with a problem. I am using jQuery.SelectBox for the select box and dropdowns.

It is working fine when the elements are loaded with the page load. But its not working when they are loaded by the ajax i.e on dynamicaly generated elements it is not working.

You can check the file here :- http://rvtechnologies.info/brad/jquery.selectBox.js

CSS codes are style declaration and stylesheets, once the element gets added to the DOM they will be loaded or applied.

Check the name of id, classes and attributes of the generated elements using tools like firebug and see the generated markup.

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.

March 7, 2013

I need to pullback data from a jquery ajax post and break the array out to seperate outputs

Question by Ezos

I need to get the array and instead of just pushing the data into an html div – get back the php variable.

My $.ajax post —-

  <script type="text/javascript">
    $(function() {

        $("#login").click(function() {
            var theName = $.trim($("#username").val());

            if(theName.length > 0)
            {
                $.ajax({
                  type: "POST",
                  url: "callajaxdemo.php",
                  data: ({name: theName}),
                  cache: false,
                  dataType: "text",
                  success: onSuccess
                });
            }
        });

        $("#resultLog").ajaxError(function(event, request, settings, exception) {
          $("#resultLog").html("Error Calling: " + settings.url + "<br />HTTP Code: " + request.status);
        });

        function onSuccess(data)
        {
            $("#resultLog").html("Result: " + data);
            //$.mobile.changePage('stats.html', { transition: 'slideup'}, true, true);
        }

    });
</script>'

My PHP file is —–

<?php
 $username = $_POST['username']; 
 $password = $_POST['password'];

$host = 'https://api.qpme.com/api/accounts/me';

$process = curl_init($host);
curl_setopt($process, CURLOPT_HEADER, 0);
curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($process, CURLOPT_RETURNTRANSFER, 1);
$return = curl_exec($process);

$content = json_decode($return);

/*
echo "<pre>";
print_r($content);
echo "</pre>";
*/

print $content->email . "<br>";
print "<h3>" . "Welcome" . ' ' . $content->firstName . ' ' . $content->lastName . '!' . "<h3>";

?>'

The goal would be to get back the array and then post certain parts of it to different jquery mobile pages.

Answer by Starx

You can send JSON data back to AJAX request.

Change your arrays to JSON like this:

echo json_encode($yourData);

To read this, you have to setup your script to accept JSON data

        $.ajax({
          type: "POST",
          url: "callajaxdemo.php",
          data: ({name: theName}),
          cache: false,
          dataType: "json", // <--- Here
          success: onSuccess
        });

Then you can access the properties as JavaScript Object.

    function onSuccess(data)
    {
        // access using data.item1
        //           or data.item2 how you prepare your array
    }
February 27, 2013

How to update the data in one region through ajax?

Question by user2046638

i want to upload the data in one region of four links, when I clicked the link1 it will load the data in specific region, and when I clicked the link 2 it will load the page on the same region where first link open, how can I do that?

    <div class="container">
    <div class="span-5">
        <ul>
            <li><?php echo $this->Manager->link('Ecommerce',array('controller'=>'associations','action'=>"view_report"),array('id'=> 'home','class'=>'nav'));?></li>
            <li><a href="#" id="home" class="nav">Home</a></li>
            <li><a href="#" id="about" class="nav">About</a></li>
            <li><a href="#" id="contact" class="nav">Contact Us</a></li>
        </ul>
    </div>
</div>

the data which I want to open from ecommerce link is int the newfile.ctp like that

 <?php v_start($this);?>

<h1><?php echo __l('View Report');?></h1>

<div class="firsttable">
    <table width="100%" border="0" cellspacing="0" cellpadding="2">
        <thead>
          <tr class="heading">
            <td><?php  echo __l('Financials');?></td>
            <td><?php  echo __l('Payment Methods');?></td>
            <td><?php  echo __l('By Credit Card');?></td>
          </tr>
        </thead>
        <tbody>  

          <tr>
            <td>
                <?php 
                    echo __l("YTD t ");
                    $ytd_total=0;
                    foreach ($YTD as $yearData)
                    {

                        $ytd_total +=$yearData['AssocPaymentDetail']['membership_fee'] - $yearData['AssociationDiscount']['amount'];

                    }
                    echo  $ytd_total."<br />";

                ?>
                <?php

                echo __l("Last 5days ");
                 $fda_total= 0;
                 foreach ($fiveDays as $fiveDaysData)
                    {

                        $fda_total += $fiveDaysData['AssocPaymentDetail']['membership_fee'] - $fiveDaysData['AssociationDiscount']['amount'];

                    }
                    echo $fda_total ."<br />";
                 ?> 
            </td>
            <td><?php  echo __l('creditcard');?>  <?php echo __l($ccSum) ?> </td>
            <td>
                <?php
        //       debug($paymentRecord);
        //      debug($ccIndex);
                    foreach($paymentRecord as $data =>$key){
                        foreach($ccIndex as $index){
                            if($data== $index)
                            {
                                echo "$data ttt";
                                if(is_array($key))
                                    echo array_sum($key);
                                else 
                                    echo "tt $key";


                            }

                            echo "<br/>";
                        }   

                    }

                ?>
            </td>
          </tr>
        </tbody>  
    </table>
</div>

Please help me to do this, thanks in advance

Answer by Starx

You can attach a single request handler to all links with nav as class name and then load the output to a container

$(".nav").on('click', function() {
    $("#loadingdiv").load("linktoload.php"); // or other 

});
November 7, 2012

Jquery val() not working in ie for dynamically added option

Question by rahul

i am generating options for my dropdown by jquery ajax method, filling it by db.

$.ajax({
        type: "POST",
        url: pageUrl + '/FillAssignee',
        data: {},
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
                        for (var i = 0; i < response.d.length; i++) {
                            $('#SelectAssignee').append($("<option></option>").val(response.d[i]['Value']).html(response.d[i]['Text']));
                        }
                  }            
      });

it’s works fine. only problem is that first value not got selected by default on ie. so for that i used many options

1. $('#SelectAssignee").val();
2. $('#SelectAssignee option:first').attr('selected','selected');
3. $('#SelectAssignee option:first').prop('selected',true);

how to get it work please help me out.

Thanks in advance.

Answer by Starx

Try setting as attributes rather than properties.

$('#SelectAssignee').append($("<option />", { value: response.d[i]['Value'], html: response.d[i]['Text'] }));
September 18, 2012

Multiple Input fields with same id

Question by fahad

I am rendering data from php code with a input field but when i retrieve data from database the input field is replicated and i have assigned one id and one class value to it now i am facing that if i use id it only show me the 1st value only.if i use class it start iterating it and complete till each field and show empty where input fields are empty

Jquery Code is this

    $('.submit-button').on('click',function(){
       $('.datecontrol').each(function(){
       alert($(this).val());
   });

and my whole html is provided here

Answer by Starx

First, as per the title, it is not a good idea to use multiple fields with same id. It will create problems is CSS, Scripting, etc.

Next, if selecting certain numbers of field only is your problem, then assign a different class to the fields to represent a particular group.

$.ajax() function working in IE but not in Chrome and FF

Question by icr

I guess this question is not asked in this forum before, tried searching alot but none matched or worked for me. Below is the JSFiddle link of code:

JSFiddle

Everything is working well in IE8 and IE9 but not in any other browsers. I tried looking for the problem in Chrome from which I got

XMLHttpRequest cannot load http://v3.actisku.com/GetUserPostData?pid=Test-37&surv=1170. Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers

I tried searching for necessary solution i.e CORS but couldn’t figure out the solution. I am side by side looking for the same.

EDIT:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<html><head>

    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp = new XMLHttpRequest();
            }
            var contents = $.ajax({
                url: 'http://v3.actisku.com/GetUserPostData?pid=Test-37',
                cache: false,
                crossDomain: true,
                dataType: 'html',
                data: { surv: '1170'},
                async: false
            }).responseText;

            var test = contents;
            alert(test);
            test = test.replace(/t/g, ';');
            alert(test);
            test = test.replace(/n/g, 'break');
            alert(test);
            $('#contentArea').attr('value', test);
        });
    </script>
</head>

<body>
<textarea id="contentArea" rows="10" cols="50"></textarea>
</body>
</html>​

Can we manually add headers so that the server feels like it is getting request from IE itself.

Regards,
icr

Answer by Starx

There is nothing in your code, to create Browser incompatibility. In fact they ware working fine in Firefox, and chrome. However, This seems unnecessary.

if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
}

As mentioned by Mahan, this looks to be like Server Configuration problem.

July 20, 2012

detect cross domain redirects on ajax request

Question by Sush

We have our authentication delegated to another domain (Window Identify framework, federated authentication setup). Now, if the the session timed out before an ajax request , server redirects the request to authentication server. Since it becomes a cross domain call, ajax request is cancelled by the browser. Is there a way i can detect this in jquery/javascript ?

I inspected the status property of the xhr object which set to 0 in such case, but is it a good indicator for cancelled requests? (I am using jquery $.ajax to make ajax requests)

Answer by Starx

Actually, there isn’t any definite way to detect this, unless you define it manually.

For example: Store you domain name in a var

var domain = "http://www.domain.com";

Next, whenever you have a URL you need to check, if it belongs to same domain, you can check like this:

var url = "http://www.domain.com/page.html";
if(url.indexOf(domain) >0) {
   //Yes it belongs to same domain
}

Note: This is rather a very simple example to give you an idea

...

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