Best jquery questions in January 2012

When to declare a new (anonymous)function in javascript?

12 votes

I'm a bit confused in how functions operate in javascript. I understand that they're all objects but how does that change how I would use them as arguments?

For instance, if I'm trying to use a callback function where the 2nd argument is evaluated after 1000ms...

$(this).fadeIn(1000,function(){alert('done fading in');});

Why can't I achieve the same effect with:

$(this).fadeIn(1000,alert('done fading in'));

If I do, it evaluates both at the same time. That is, (this) element fades in and the alert pops up at the same time.

When I'm calling alert(arg), aren't I creating a new object which gets passed into fadeIn()?

How exactly does this work?

In this

 $(this).fadeIn(1000,alert('done fading in'));

what does fadeIn() see as its second argument? It's the result of calling

 alert('done fading in')

we are making the call to alert() before calling fadeIn().

In this case

$(this).fadeIn(1000,function(){alert('done fading in');});

we have an object

 function(){alert('done fading in');}

which fadeIn() calls at the right time.

How can jQuery behave like an object and a function?

12 votes

jQuery or $ seems to be a function:

typeof $; // "function"

And it acts like one:

$('div').removeClass(); // $ constructs a new object with some methods like removeClass

But when I drop the function parentheses it behaves like an object:

$.each(/* parameters */); // $ is an object with some methods like each

I'd like to know how this is possible and how I can implement this behaviour to my own functions.

Functions are also objects, so $.each can be defined in a similar way as an Object.

JavaScript is a prototypical language. For jQuery, this means that every instance of $ inherits methods from jQuery.prototype.See Notes

A very rough demo, to achieve the similar behaviour:

(function() { // Closure to not leak local variables to the global scope
    function f(a, b) {
        //Do something
    }
    // Prototype. All properties of f.prototype are inherited by instances of f.
    // An instance of f can be obtained by:    new f, new f(), Object.create(f)
    f.prototype.removeClass = function(a) {
        return a;
    };
    function $(a, b) {     return new f(a, b);   } // <--- "new f" !
    $.each = function(a) { alert(a);             }
    window.$ = $; // Publish public methods
})();

//Tests (these do not represent jQuery methods):
$.each("Foo");                   //Alerts "Foo" (alert defined at $.each)
alert($().removeClass('Blabla'));//Alerts "Blabla"

Notes

jQuery's root method is defined as follows (only relevants parts are shown):

(function(win) {
    var jQuery = function (selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery);
    }
    //$.fn = jQuery.fn is a shorthand for defining "jQuery plugins".
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function(){ .... sets default properties...}
        ....other methods, such as size, get, etc...
        .... other properties, such as selector, length, etc...
    }
    jQuery.fn.removeClass = ...
    ...lots of stuff, including definitions of removeClass, etc..


    win.$ = win.jQuery = jQuery; //Pulish method
})(window);

The advantage of the prototype method is that it's very easy to chain methods and properties. For example:

$("body").find("div:first").addClass("foo");

A method to implement this feature could be:

$.fn.find = function(selector) {
    ...
    return $(...);
}

Smooth scrolling of image tiles on large grid?

12 votes

Long time listener, first time caller here.

Ok, I apologize for the length of this post, but I want to be very clear on what I'm trying to do and what I've tried to hopefully guide your answers.

The Goal: I am trying to create a grid of tiles (images) 100 x 100 and I will display only part of the grid at a time because the images are 240 x 120. By clicking buttons (note: no need for mouse scrolling, zooming, etc.), the user will scroll around horizontally and vertically.

As an analogy, take a checkers board that is set up to play and you are looking down on it. It would be quite simple to display, requiring only a few base images and putting them on a grid. Now, consider that you only wanted to show the bottom 1/3 of the board. Then when a user clicks up, they move their view to the middle and another click takes them to the top 1/3 of the board. This is a simple example of what I'm trying to accomplish except on a much larger grid with a smaller view / move.

What I've tried:

  1. First I wrote the code in PHP to draw the full 100x100 grid and everything looked great
  2. Then I altered the code to actually write files for each square, saving them as X-Y.png
  3. I got sucked into a world of map tools and zoomify type tools
  4. I had some partial success writing my own solution

Map tools / Zoomify Fail:

After getting the full map and tiles, I tried to figure out how the heck to scroll part of this window only. A light bulb went off: "what about something like how google maps does things!" That's when trouble started and I got sucked down the rabbit hole a bit researching all these map tools that really got me nowhere because, quite simply, they seem to be made only for displaying geographic maps.

I did, however, get led to Zoomify at one point or another and I thought it could really be an option. The first problem was I couldn't seem to get it to take my own tiles without one shot of the full image, so I tried every screen capture program under the sun to try getting a full shot of my browser with the full grid to let zoomify make them. Let's just say, that didn't work, but i tried with reduced size. It sort of worked, but lost a lot of quality and I realized that zoomify doesn't even really accomplish what I need because 1. the scroll is not that smooth; and 2. these images will eventually contain some links connected with their X-Y coords, which means I need control over how much is scrolled each time the up, down, left, right arrows will be clicked.

My Not so failed attempt to do it myself

Ok, then I got back to the basics and I threw the grid in a DIV with overflow:hidden on the CSS. Great, now I had a window. I didn't want to load all of these images at once, though, so I drew only part of the grid in absolutely positioned DIVs with unique ID's (e.g. Tile_1_1). This was all looking great, but now I needed to make it appear that you are scrolling around the grid as you click the arrow buttons, so I threw it up to a javascript function for this. I had the javascript calculate the new X and new Y and swap the Image source of all the tiles since they are all named after their X/Y coordinates on the grid. Actually, this totally worked and now the map is scrolling. The problem is, it's a bit choppy to just change the image sources. There is no illusion that we are moving around this grid as much as the content is just instantly changing. and THIS my friends is where I need our help.

Where did I go wrong? Was I on the right track with this latest attempt? Do I need to totally rethink this or is there some simple fix for moving the tiles a little more elegantly than swapping the source?

Please keep in mind that I've gotten quite good with php, css, etc., but I never really invested much time in javascript, so you might need to do a little more explaining in that area.

P.S. this was the closest thing I could find on these boards, but it never really got to a clear answer: Tile scrolling / preloading (Google Maps style) of HTML layers with Ajax

Update: Solution Used

I liked both Cobby and pseudosavant's answers. Pseudosavant's solution was really right up my ally with letting CSS do most of the hard work, however I went with Cobby's solution. I thought it would give me a little more control and because I'm actually using a diamond grid, I could wrap my head around it better (not saying the other one wouldn't necessarily work also).

Here is what I did. I know the code is a little crude and needs some cleanup, but maybe it can help someone.

First I needed to find the relationship between my X and Y axis, so I drew myself a little diagram.

enter image description here

I quickly noticed that more X meant starting the diamond both farther left and higher to get the right coordinates in the center of the view (user defined start) and then offset by the Y coordinates to take off some of the negative left and lower the starting point.

Then, the PHP to draw the grid looks something like this ($xcoord and $ycoord come from a form):

//draw the grid
//Offset leftStart and topStart by Xcoord
$leftStart = 360 - ($xcoord * 120);
$topStart = 360 - ($xcoord * 60);

//Offset leftStart and topStart by Ycoord
$leftStart += ($ycoord * 120);
$topStart -= ($ycoord * 60);

for($y = 1; $y <= 99; $y++) { //y min to y max
    $left = $leftStart;
    $top = $topStart;
    for($x = 1; $x <= 99; $x++) { //x min to x max
       //I only want to draw part of the square
       if(($x < ($xcoord + 6)  && $x > ($xcoord - 6)) && ($y < ($ycoord + 6)  && $y > ($ycoord - 6))) {
          //Put out the image - this is how i needed mine formated
          echo "\t<div class=\"move\" id=\"T" . $x . "_" . $y . "\" style='position:absolute; left:" . $left . "px; top:" . $top . "px;'>\n";
          echo "\t\t<img src=\"./<path to your image>" . $x . "-" . $y . ".gif\">\n";
          echo "\t</div>\n";
       }
       $left = $left + 120;
       $top = $top + 60;
    }
$leftStart = $leftStart - 120;
$topStart = $topStart + 60;
}

Throw a DIV around that with overflow:hidden and give it an ID (mine is #tileView). OK, now you have a diamond grid drawn inside your view and now we need to start moving it!

This is how my jquery looks. Sorry if it needs improvement, I just learned Jquery and Ajax yesterday.

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $("#top").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "-=120px", "top": "+=60px"}, 500);
        changeImg(x, y, 'up');
        $("#ycoord").val(parseInt( y ) - 1);
    });     
    $("#bottom").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "+=120px", "top": "-=60px"}, 500);
        changeImg(x, y, 'down');
        $("#ycoord").val(parseInt( y ) + 1);
    });     
    $("#left").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "+=120px", "top": "+=60px"}, 500);
        changeImg(x, y, 'left');
        $("#xcoord").val(parseInt( x ) - 1);
    });
     $("#right").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "-=120px", "top": "-=60px"}, 500);
        changeImg(x, y, 'right');
        $("#xcoord").val(parseInt( x ) + 1);
    });

function changeImg(x, y, move){
    $.ajax({
        type: "POST",
        url: "addImage.php",
        data: 'x=' + x + '&y=' + y + '&move=' + move,  
        cache: false,
        success: function(html){
            $(html).appendTo($("#tileView"));
        }
    });
    $.ajax({
        type: "POST",
        url: "removeImage.php",
        data: 'x=' + x + '&y=' + y + '&move=' + move,  
        cache: false,
        success: function(xml){             
            $("removeTile",xml).each(function(id) {    
            removeTile = $("removeTile",xml).get(id);
            removeID = $("tileID",removeTile).text();
            $("#" + removeID).remove();
        });
        }
    });
}
});
</script>

The ajax calls addImage.php to add a new row on the right spot and deleteImage.php to delete the row that's now out of view (i found without deleting those rows that things started running pretty slow).

In add image you just figure out the new position and output 's for the html to add in the page. For example part might look like this (but set the variables depending on move then go through the loop):

if($_REQUEST["move"] == "up") {
    $xmin = $x - 5;
    $xmax = $x + 5;
    $y = $y - 6;

    $left = 360;
    $top = -360;

    for($i = $xmin; $i <= $xmax; $i++) {
        $id = "T" . $i . "_" . $y;
        $newTiles .= "<div class='move' style='position:absolute; left:" . $left . "px; top:" . $top . "px;' id='$id'><img src='./Map/TileGroup1/1-$i-$y.gif'></div>\n";
        $left += 120;
        $top += 60;
    }
}

then just echo $newTiles out for your script to use.

Delete is similar, just putting out in xml the DIV ID's to delete because i couldn't get each() to work otherwise.

if($_REQUEST["move"] == "up") {
    $xmin = $x - 5;
    $xmax = $x + 5;
    $y = $y + 5;

    echo "<?xml version=\"1.0\"?>\n";  
    echo "<response>\n";  
    for($i = $xmin; $i <= $xmax; $i++) {
        echo "\t<removeTile>\n";
        echo "\t\t<tileID>T" . $i . "_" . $y . "</tileID>\n";
        echo "\t</removeTile>\n";
    }
    echo "</response>"; 
}

Hope this helps someone. Thank you all for the ideas and support!

I think you need to go back to the approach of the whole grid being nested in a DIV with overflow:hidden but use JavaScript to figure out which images should be visible and only load those images in as needed, then load in additional relevant images as the user scrolls to that area.

Scrolling of course should just manipulate the left and top CSS properties for your grid to move it with in the containing overflow: hidden DIV. In your case, it would be easiest to being by just changing the positioning CSS properties in increments of your tile size (so you never have portions of tiles showing).

From a programming standpoint this is a bit of a pain to do but it sounds like you've already got a method to calculate which ones are/should be displaying?

With this method, it will have that initial glitch as images are being loaded for the first time, but subsequent moving of the grid won't have to reload the same images. Once you've got this working, you can use jQuery or similar to animate the left and top properties to give a smooth scrolling effect.

Then, if you want, you can build on this further and allow partial scrolling of tiles and click-and-drag scrolling like Google Maps. Also if you want to work on performance, I'd recommending setting up an nginx server that listens on a few sub-domains of your site to serve up the tile images.


I haven't used this before, but maybe something like TileMill could work?

Is it possible to change text color based on background color using css?

10 votes

Is it possible to change text color based on background color using css?

Like in the this image

http://www.erupert.ca/tmp/Clipboard01.png

As the text crosses over from one div (white-space:nowrap) is it possible to change the text color using css or jquery/javascript?

Thanks

Here is my solution (thinking it through a different way):

Use a DIV with overflow: hidden; for the navy 'bar' that shows the rating scale. You then write out two sets of TEXT:

  1. Inside the DIV bar (overflow: hidden;), it would be white (on top)
  2. In the underlying DIV container, it would be black. (container)

The result would be an overlap of the two colored text divs:

 ________________________________
|          1          |    2     |
|_(dark blue w white)_|__________|

Here is my jsFiddle

It works great because it will 'cut through' letters if the bar is at that width. Check it out, I think its what you are looking for.

var x = x || "default val" not getting set properly if x is defined above it

10 votes

HTML:

<script type="text/javascript">
  var x = "overriden";
</script>
<script src="myjs.js"></script>

myjs.js:

$(document).ready(function(){
  var x = x || "default val";
  alert(x); // this alerts "default val" and not "overriden"
});

For some reason, x is ending up as "default val" and not "overriden", even tho initially I'm setting it to "overriden" before I even include the script reference to myjs.js.

Any idea as to why this is happening? I'm trying to enable the hosting page to set an override for a variable that's used in an included js file, otherwise use the default val.

What you have after variable declaration hoisting is applied:

var x;
x = 5;

$(document).ready(function(){
    var x;
    x = x || "default";
});

It looks at the closest x and sees it's value is undefined which is a falsy value, so x gets set to "default".


You would be fine if they were in the same scope, because the declarations are always hoisted above assignments so:

var x = 5;

var x = x || "default";

Is actually just

var x;

x = 5;
x = x || "default";

This was suggested which is completely pointless:

$(document).ready(function(){
    x = x || "default";
});

It will throw a ReferenceError if x is not defined.


So either do the check in the same scope or do something like:

$(document).ready(function(){
    var x = window.x || "default";
});

Invalid property reads don't cause a ReferenceError but just return undefined instead.

fullcalendar several issues

10 votes

Hello,
I am using fullcalendar v1.5.2 (only month view ) for property booking website , its a great plugin but i stuck in few problems, I have seen similar issues on google code , but there is nothing clear really. :( . please help me to solve these problems

Here is working demo and JS Code

What i have done so far

  • Fetched events data from two different json files below

    • json_events.php : this holds booking detail which is booked from front end by user; admin can not change any details of these type of events.

    • new_charges.php : this holds special charges events detail ,admin add/update delete the new charges for any future date(s) .

  • admin can view the details of any event when he click on an event

  • admin can add/edit and delete new events on calendar for future dates or range of dates, that will stored on new_charges.php

Now here is my problems.

a) I want that only one event is allowed for a date(s).

b) Currently if user click on a day on which any booking event or special charges event is there, then it alerts that day is booked, but after that it will show a prompt box to enter event title,

this is occured because I have used both dayClick and select methods

How do i stops further propagation if a day already have an event ?

c) suppose a day 15 january (wrapped by fc-day17 div) is booked ( I have applied a class booked for events ) and now when I go to next month and click on fc-day17 div, it also alert that day is booked whereas there is no booking by examining the code i found that it still have the class booked for another months for the same divs

I think there is something missing during eventRender methods?

does `eventRender()`  method is called only once when initialize the calendar 
or each time when we go `prev` or `next` month?

d) I have changed background-color for special charges events during rendering events via json file, but when I delte that events, it does not change back the normal background and still say that day is booked.

how do I make default background of a date if I delete the events of that day??

e) how to hide all events related to previous months?

// a) and b)
// We dont need dayClick event, only select
// I think you created calender something like this 
// var calendar = $('#calendar').fullCalendar({ ... })

select: function(start, end, allDay) {
    //debugger;
    var events = calendar.fullCalendar( 'clientEvents' );
    for (var i = 0; events.length > i ; i++){
        //If we have 1 day event
        if((events[i].end == null && (events[i].start.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime())) ||
        // If we have many days event 
        (events[i].end != null && ((events[i].start.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime()) || 
            (events[i].end.getTime() >= start.getTime() && events[i].start.getTime() <= end.getTime()) || 
            (events[i].start.getTime() <= start.getTime() && events[i].end.getTime() >= end.getTime())) 
        )){
            alert("Realy busy!!!");
            return;
        }
    }
    // If this time is not busy, for example, we promt to enter Event Title
    var title = prompt('Event Title:');
    if (title) {
       //............Adding event into calendar
    }
    calendar.fullCalendar('unselect');
},
// c) and d)
// This is invoked when we navigate throw the month callender 
eventAfterRender: function(event, element, view ){
    $(".booked").removeClass(".booked"); // Remove all booked class from element
    var elements = $(".fc-widget-content:not(.fc-other-month)").filter(function(){
        //We try to find day number witch corresponds to the event date
        return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
            || (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
            &&  $(this).find(".fc-day-number").text() <= event.end.getDate())
    });
    elements.addClass("booked");

    // e)
    // Hide all events related to previous and next months
    // If we event ends in previous month or starts in next we dont show it!
    if(
        (event.end == null && (view.start.getMonth() != event.start.getMonth())) //If we have 1 day event
        || (event.end != null && (view.start.getMonth() > event.end.getMonth() // If we have many day event
        || view.start.getMonth() < event.start.getMonth())) 

    ){
        $(element).hide();
    }
}

EDIT This construction

var elements = $(".fc-widget-content:not(.fc-other-month)").filter(function(){
    //We try to find day number witch corresponds to the event date
    return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
        || (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
        &&  $(this).find(".fc-day-number").text() <= event.end.getDate())
});

meansthat we select days of current month (:not(.fc-other-month)) which satisfy the filter conditions (return true) : The days of month equal the days of events

About your code as I said you must remove dayClick event, and your select event is:

select: function (startDate, endDate, allDay, jsEvent) {
    // This is my addition //
        var events = calendar.fullCalendar( 'clientEvents' );
        for (var i = 0; events.length > i ; i++){
            //If we have 1 day event
            if((events[i].endDate == null && (events[i].start.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime())) ||
            // If we have many days event 
            (events[i].endDate != null && ((events[i].start.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime()) || 
                (events[i].end.getTime() >= startDate.getTime() && events[i].start.getTime() <= endDate.getTime()) || 
                (events[i].start.getTime() <= startDate.getTime() && events[i].end.getTime() >= endDate.getTime())) 
            )){
                alert('Sorry this date is already taken');
                return;
            }
        }

        // /This is my addition //      
    console.dir(jsEvent);
    if (liveDate > startDate) {
        alert('This date has been passed');
        return false;
    } else {
        var title = prompt('New Charges:');
        if (title) {
            calendar.fullCalendar('renderEvent', {
                        title: title,
                        start: startDate,
                        end: endDate,
                        allDay: allDay
                    }, false // make the event "unstick"
                    );
                    var startDateString = $.fullCalendar.formatDate(startDate, 'yyyy-MM-dd');
                    var endDateString = $.fullCalendar.formatDate(endDate, 'yyyy-MM-dd');
                    $.ajax({
                        type: 'POST',
                        url: './new_event.php?action=add',
                        data: {
                            startDate: startDateString,
                            endDate: endDateString,
                            eventTitle: title,
                            propID: propID
                        },
                        dateType: 'json',
                        success: function (resp) {
                            calendar.fullCalendar('refetchEvents');
                        }
                    });
                } // end of inner if
            } // end of else
            calendar.fullCalendar('unselect');
},

About viewDisplay. Its is fired every time when we go to previous or next month, and it fired after eventAfterRender. If we use eventAfterRender and go to month without events we have no effect. The free cells stay booked. I offer analyse events of current month inviewDisplay:

function viewCalDisplay(view) {

//...................
// Your code

            $(".booked").removeClass("booked"); // Remove all booked class from element
            var events = view.calendar.clientEvents(function(event){  
                //we need only events of current month
                return event.start.getMonth() == view.start.getMonth(); 

            } );

            for(i = 0; events.length > i; i++){
                var event = events[i];
                // We need only days of current month. We select <td> of calender table (by class .ui-widget-content)
                var elements = $(".ui-widget-content:not(.fc-other-month)").filter(function(){
                    //We try to find day number witch corresponds to the event date
                    return (event.end == null && $(this).find(".fc-day-number").text() == event.start.getDate()) //If we have 1 day event
                        || (event.end != null && $(this).find(".fc-day-number").text() >= event.start.getDate() // If we have many day event
                        &&  $(this).find(".fc-day-number").text() <= event.end.getDate())
                });

                elements.addClass("booked"); //Only for this <td> 
            }
}

How does jQuerys $.each() work?

10 votes

Maybe a bad title, but this is my problem: I'm building a framework to learn more about javascript. And I want to use ""jQuery"" style.

How can I make a function where the () is optional?

$("p").fadeOut(); //() is there
$.each(arr, function(k, v) {...}); //Dropped the (), but HOW?

This is what I have come up with, but it don't work:

$2DC = function(selector)
{
    return new function() {
        return {
            circle : function()
            {
                //...
            }
        }
    }
}


$2DC("#id1"); //Work
$2DC("#id2").circle(); //Work
$2DC.circle(); //DONT WORK

$ is really just an alias for the jQuery function. You can call the function with:

jQuery("p"); or $("p");

but remember, in JavaScript you can attach "stuff" directly to functions.

function foo(){
}
foo.blah = "hi";
foo.func = function() { alert("hi"); };

foo.func(); //alerts "hi"

This is how (conceptually) jQuery's each function is defined.

jQuery.each = function(someArr, callback) { ...

And so now jQuery.each is a function that can be called like this:

jQuery.each([1, 2, 3], function(i, val) {
});

or the more familiar

$.each([1, 2, 3], function(i, val) {
});

So for your particular case, to support:

$2DC.circle(); 

You'd have to add the circle function directly to $2DC:

$2DC.circle = function(){
   // code
};

jQuery checkbox: select all/none except one

9 votes

I have a checkbox select all issue. I have multiple checkbox that can be triggered by a master one.

If the master one is check then you can select any checkbox (which this works). Now my problem is when i check "none" all of them are gone even the master

What I need is not to unchecked the master. I can have as many as checkbox as I want.

Is there a solution to do this without putting an ID on each or automatically uncheck all checkbox and not the master one?

here is my code:

 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">

  $(document).ready(function() {
  $('#checkAll').click(function() {
    if(!$('#master').is(':checked')) {  return;
    } $('input[type="checkbox"]').attr('checked', true);
  });

  $('#checkNone').click(function() {
    $('input[type="checkbox"]').attr('checked', false); });

  $('#master').click(function() { if($('#master').is(':checked')) {
        return; } $('input[type="checkbox"]').attr('checked', false);
  });
  $('input[type="checkbox"]').click(function() {
    if(!$('#master').is(':checked')) { $(this).attr('checked', false);
    }
  });
  });

  </script>
  </head>

  <input type="checkbox" value="master" id="master">master
  <span id="checkAll">All</span>
  <span id="checkNone">None</span>

  <input type="checkbox" value="1" id="c1">1
  <input type="checkbox" value="2" id="c2">2
  <input type="checkbox" value="3" id="c3">3
  <input type="checkbox" value="4" id="c4">4
  <input type="checkbox" value="5" id="c5">5

Based on your code, I would add a wrapper around the check-box you want to select all/none and then give the wrapper id and inputs to select all or none.

$('#list input[type="checkbox"]').attr('checked', false);

or

$('#list input[type="checkbox"]').attr('checked', false);

This way, you can control all your checkboxes without affecting the "master" one.

Here's the code:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {
$('#checkAll').click(function() {
  if(!$('#master').is(':checked')) {
      return;
  }
  $('#list input[type="checkbox"]').attr('checked', true);
});

$('#checkNone').click(function() {
  $('#list input[type="checkbox"]').attr('checked', false);
});

$('#master').click(function() {
  if($('#master').is(':checked')) {
      return;
  }
  $('#list input[type="checkbox"]').attr('checked', false);
});
$('#list input[type="checkbox"]').click(function() {
  if(!$('#master').is(':checked')) {
      $(this).attr('checked', false);
  }
});
});

</script>
</head>

<input type="checkbox" value="master" id="master">master
<span id="checkAll">All</span>
<span id="checkNone">None</span>

<div id="list">
 <input type="checkbox" value="1">1
 <input type="checkbox" value="2">2
 <input type="checkbox" value="3">3
 <input type="checkbox" value="4">4
 <input type="checkbox" value="5">5
</div>

Google chrome frame overlay works only once

9 votes

I have a page that prompts for a Google Chrome Frame installation if the user uses an outdated browser.

It works great if the user chooses to install the plugin. But, if he/she choose not to install it and closed the layer; It's impossible to open the layer again using the same button. (Basically it works only once.)

Is there any way I can force Google Chrome Frame to open every time I click on install?
(I've tried forcing a cookie, but doesn't seem to work.)

update [#1]:

Test page here.

<!doctype html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <!--[if IE]>
            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js"></script>
        <![endif]-->
    </head>
    <body>
        <a href="#" class="dngcf">Prompt</a>
        <script>
            $(function(){
                if( $.browser.msie && $.browser.version < 9 ){
                    if( navigator.userAgent.indexOf('chromeframe') < 0 ){
                        $('.dngcf').bind('click', function(){
                            //document.cookie = 'disableGCFCheck=0;path=/;';
                            CFInstall.check({
                                url: 'http://www.google.com/chromeframe/eula.html?user=true',
                                mode: "overlay",
                                destination: "http://mywebsite.com"
                            });
                        });
                    }else{
                        alert('GCF is already installed');
                    }
                }else{
                    alert('You need IE 6, 7 or 8 in order to see the "bug".');
                }
            });
        </script>
    </body>
</html>

update [#2]:

This seem to be a session-related problem.
When i restart the browser, the link works again once. But doesn't however when i only refresh the page.

[conclusion]

This behavior is by design. It allows an admin to check() for GCF on every single page, without annoying the user with a prompt every time.

The accepted answer allows you to circumvent this behavior.

You're right about the cookie, but it annoyingly also sets a private variable when it shows the popup, so without hacking the cfinstall script we're looking at overriding existing methods.

This is the best I can get. There's a problem where pressing "cancel" and then "close" means that the popup is still on the 2nd page when you pop it back up again, but you can install from there so I don't think it's that big an issue. (The pedant in me doesn't like it though!)

<!doctype html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <!--[if IE]>
            <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js"></script>
        <![endif]-->
    </head>
    <body>
        <a href="#" class="dngcf">Prompt</a>
        <script>
            $(function(){
                if ($.browser.msie && $.browser.version < 9){
                    if (navigator.userAgent.indexOf("chromeframe") < 0){
                        $(".dngcf").on("click", function(){
                            if ($(".chromeFrameOverlayContent").length > 0) {
                                $(".chromeFrameOverlayContent, .chromeFrameOverlayUnderlay").show();
                            } else {
                                CFInstall.check({
                                    url: "http://www.google.com/chromeframe/eula.html?user=true",
                                    mode: "overlay",
                                    destination: "http://mywebsite.com"
                                });
                                $("#chromeFrameCloseButton").off("click").on("click", function() {
                                    $(".chromeFrameOverlayContent, .chromeFrameOverlayUnderlay").css({ display: "none" });
                                });
                            }
                        });
                    } else {
                        alert('GCF is already installed');
                    }
                } else {
                    alert('You need IE 6, 7 or 8 in order to see the "bug".');
                }
            });
        </script>
    </body>
</html>

jqeury error submit form validation

8 votes

i need to validate input using javascript and jqeury when someone submit my newsletter form

for some reason it does not work. it submit the form without alerting any errors

heres what i have so far:

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
  <script type="text/javascript">

  $(document).ready(function(){
  function go() {
      if($('#name').val() == '') {
          alert('error: name is required');
      }
      $('form').submit();
  }
  });


  </script>
  </head>

  <form method="post" action="">
    Name *<input type="text" name="name" id="name"/>
    E-Mail *<input type="text" name="email" id="email"/>

    <input class="submit" type="submit" value="Submit" name="submit" id="submit" onclick="go();">
  </form>

why i dont see the alert when i dont put anything in the name and then submit the form?

Rather than using onclick on the submit button, use onsubmit="return go(); on the form element. Or, use jQuery $('form').submit(function(){ ... });

And, once you encounter an error, you need to return false from the function to prevent it from executing any further.

How To Detect Right Mouse Click + Delete Using Jquery/Javascript

8 votes

I want to track Right Mouse Click + Delete event on a html text input. I Succeed in mapping Right Mouse Click + Paste/Cut/Copy as below

          $("#evalname").bind('paste/cut/copy', function(e)
          {
             do something

          });

Here 'evalname' is the id of my html text input. I tried like

          $("#evalname").bind('delete', function(e)
          {
             do something

          });

but not working. Is there any way to map Right Mouse Click + Delete event in Jquery/Javascript ?

As already answered, it isn't possible to pick up on the browsers contextmenu delete being used, in fact, using .bind('copy', func....) will not only listen to the contextmenu's copy, but also CTRL+c as it's actually binding to the clipboard.

I have put together a plugin, which to be honest is a bit of a hack, but it will allow you to catch:

  • Context COPY, CUT, PASTE, DELETE - ONLY
  • Context COPY, CUT, PASTE, DELETE - AND - CTRL+c, CTRL+x, CTRL+v
  • Or just one, two, three or four item(s) in either of the above ways. Of course one problem was IE, it doesn't trigger jQuerys .bind('input', func.... to listen for changes, so I needed to trigger it for IE, hence there could be a vary small delay (milliseconds).

    The plugin:

    (function($) {
        $.fn.contextDelete = function(options) {
            var set = {
                'obj': $(this),
                'menu': false,
                'paste': false,
                'cut': false,
                'copy': false,
                'set': '',
                'ie': null,
            };
            var opts = $.extend({
                'contextDelete': function() {},
                'paste': function() {},
                'cut': function() {},
                'copy': function() {},
                'contextOnly': false,
            }, options);
    
            $(window).bind({
                click: function() {
                    set.menu = false;
                },
                keyup: function() {
                    set.menu = false;
                }
            });
    
            set.obj.bind({
                contextmenu: function() {
                    set.menu = true;
                    set.paste = false;
                    set.cut = false;
                    set.copy = false;
                    set.val = set.obj.val();
    
                    // Hack for IE:
                    if ($.browser.msie) {
                        set.ie = setInterval(function() {
                            set.obj.trigger($.Event('input'));
                            if (!set.menu) {
                                clearInterval(set.ie);
                            }
                        }, 300);
                    }
                    // End IE Hack
                },
                paste: function(e) {
                    set.paste = true;
                    if (opts.contextOnly) {
                        if (set.menu) {
                            opts.paste(e);
                            set.menu = false;
                        }
                    }
                    else {
                        opts.paste(e);
                    }
                },
                cut: function(e) {
                    set.cut = true;
                    if (opts.contextOnly) {
                        if (set.menu) {
                            opts.cut(e);
                            set.menu = false;
                        }
                    }
                    else {
                        opts.cut(e);
                    }
                },
                copy: function(e) {
                    set.copy = true;
                    if (opts.contextOnly) {
                        if (set.menu) {
                            opts.copy(e);
                            set.menu = false;
                        }
                    }
                    else {
                        opts.copy(e);
                    }
                },
                input: function(e) {
                    if (set.menu && (!set.paste) && (!set.cut) && (!set.copy)) {
                        if (set.obj.val().length < set.val.length) {
                            opts.contextDelete(e);
                            set.menu = false;
                        }
                    }
                }
            });
        };
    })(jQuery);
    

    One example usage, contextmenu delete + context copy ONLY:

    $('#evalname').contextDelete({
        contextDelete: function(e) {
            alert('You just deleted something!');
        },
        copy: function(e) {
            alert('You just copied something!');
        },
        contextOnly: true,
    });
    

    Click Here for a DEMO

    Is there a particular reason why jQuery's addClass() is not right-trimming?

    8 votes
    <div id="myDiv" class=" blueberry mango "></div>
    

    If we use the .addClass()

    $("#myDiv").addClass("carrot");
    

    The class for myDiv is now "(no-space)blueberry mango(double-space)carrot"

    There is a left-trim, but there are double spaces between mango and carrot because there were no right-trim

    • Is there a particular reason why jQuery's addClass() is not right-trimming?
    • Or the left-trim was not even intended?

    Seems like jQuery is doing the trim after adding the class. See jquery addclass code below,

    addClass: function( value ) {
        var classNames, i, l, elem,
            setClass, c, cl;
    
        if ( jQuery.isFunction( value ) ) {
            return this.each(function( j ) {
                jQuery( this ).addClass( value.call(this, j, this.className) );
            });
        }
    
        if ( value && typeof value === "string" ) {
            classNames = value.split( rspace );
    
            for ( i = 0, l = this.length; i < l; i++ ) {
                elem = this[ i ];
    
                if ( elem.nodeType === 1 ) {
                    if ( !elem.className && classNames.length === 1 ) {
                        elem.className = value;
    
                    } else {
                   //HERE IS APPENDS ALL CLASS IT NEEDS TO ADD
                        setClass = " " + elem.className + " ";
    
                        for ( c = 0, cl = classNames.length; c < cl; c++ ) {
                            if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
                                setClass += classNames[ c ] + " ";
                            }
                        }
                        elem.className = jQuery.trim( setClass );
                    }
                }
            }
        }
    
        return this;
    }
    

    So it's like below,

    jQuery.trim(" blueberry mango " + " " + "carrot")

    Parent(), faster alternative?

    8 votes

    I am working with a dashboard of divs and each div it has a tree of which the buttons are. Every time I have to know which the id of that div is so I am using parent() alot.

    Mostly I am doing $(this).parent().parent().parent() to find the ID of div so I can set variables to it. The app is based on the id's of each div.

    Is it consider slow to use parent() up to 3 times but pretty much on every function?

    Is there any other alternative?

    I am looking for something like benchmarks-style which shows what's faster.

    Here is an example of the tree:

    <div id="6179827893" class="dashdiv">
       <div class="buttons">
         <li><a href="#" class="btn1">Button 1</a></li>
         <li><a href="#" class="btn2">Button 2</a></li>
         <li><a href="#" class="btn3">Button 3</a></li>
         <li><a href="#" class="btn4">Button 4</a></li>
         <li><a href="#" class="btn5">Button 5</a></li>
         <li><a href="#" class="btn6">Button 6</a></li>
       </div>
       <div class="dashcontent">
    
        ....
    
       </div>
    </div>
    

    You've got a few options to achieve the same effect.

    Benchmark: http://jsperf.com/parents-method. According to this benchmark, my method is roughly 100x faster than your method.

    Method (see below) : Operations per second (higher is better)
    parentNode3x       : 4447k
    $(parentNode3x)    :  204K
    $().closest        :   35k
    $().parents        :    9k
    $().parent()3x     :   44k
    
    // Likely the fastest way, because no overhead of jQuery is involved.
    var id = this.parentNode.parentNode.parentNode.id;
    
    // Alternative methods to select the 3rd parent:
    $(this.parentNode.parentNode.parentNode) // Native DOM, wrapped in jQuery
    
    // Slowpokes
    $(this).closest('.dashdiv')              // Hmm.
    $(this).parents('.dashdiv:first')        // Hmm...
    

    Hiding _groups_ of series in Highcharts and jQuery: how to get acceptable performance?

    8 votes

    I'm using Highcharts to represent groups of time series. So, data points collected from the same individual are connected by lines, and data points from individuals that belong to the same group share the same color. The Highcharts legend displays each individual time series instead of groups, and I have over a hundred time series, to it's ugly and impractical to hide and show data that way.

    Instead I made buttons and used jQuery to associate them with functions that would search for matching colors among the time series and toggle the visibility of each matching series.

    Here is an example with a small dataset: http://jsfiddle.net/bokov/VYkmg/6/

    Here is the series-hiding function from that example:

    $("#button").click(function() {
        if ($(this).hasClass("hideseries")) {
            hs = true;
        } else {
            hs = false;
        }
        $(chart.series).each(function(idx, item) {
            if (item.color == 'green') {
                if (hs) {
                    item.show();
                } else {
                    item.hide();
                }
            }
        });
        $(this).toggleClass("hideseries");
    });
    

    The above works. The problem is, my real data can have over a hundred individual time series and it looks like checking the color of each series is really slow. So, can anybody suggest a more efficient way to solve this problem? Are there some built-in Highcharts methods that already do this? Or, can I give jQuery a more specific selector?

    I tried digging into the <svg> element created by Highcharts but I can't figure out which child elements correspond to the series in the chart.

    Thanks.

    The issue here is that Highcharts is redrawing the chart after every series change. I checked the API to see if there was a param you could pass to defer that, but that doesn't appear to be the case.

    Instead, you can stub out the redraw method until you are ready, like so:

    var _redraw = chart.redraw;
    chart.redraw = function(){};
    
    //do work
    
    chart.redraw = _redraw;
    chart.redraw();
    

    Check out the full example here. For me, it was about 10 times faster to do it this way.

    Automatically Invokes a jQuery Plugin on a Dynamically-Created Element

    7 votes

    I need to apply a jQuery plugin to an HTML element that will be created upon a user's input. For example:

    <!-- Upon click, this link creates a new div with an id of 'target'. -->
    <a id="trigger-a" href="javascript:void(0);">Create a new div</a>
    
    /* This will not work because div#target isn't available yet upon page load. */
    $(function() {
      $("div#target").aJQueryPlugin( ... );
    });
    

    In the simplest form, I can call the plugin inside the <a>'s click handler, after the div is created.

    $(function() {
      $("#trigger-a").click(function() {
        // Create div#target.
    
        // I can call the plugin here but is there a different, maybe better, way?
        $("div#target").aJQueryPlugin( ... );
      });
    });
    

    However, if possible, I am looking for something that is more "automatic"; maybe using .on() that automatically invokes the plugin once the element becomes available?

    Paraphrasing the question: In jQuery, is there a way to "monitor" when a certain element becomes available (i.e. after it's being created)? If there is, I'd then call the plugin or other functions as a callback.

    Maybe something like this? http://jsfiddle.net/Q2UYC/

    Triggering custom event let you bind event handler later.

    Replace selected content in the ckEditor with new content using javascript

    6 votes

    I am using CKEditor ver.3.6 in my MVC Application.

    My requirement is to update the selected text with new text in the ckEditor. I could find out the method editor.getSelection().getSelectedText(); for getting selected text from the editor. I need to add some tag with the selected text when a toolbar button is pressed and update the selected content using javascript.

    For Example :

    Content in the ckEditor is

     <span>Edit content in the editor</span>
    

    and I have selected the word “editor” from ckEditor. I have to update the selected word “editor” with “ckEditor” using javascript code.

    Please suggest a proper solution.

    It looks to me from the docs as the following would work (untested):

    editor.insertText("ckEditor");
    

    Graceful Javascript Degradation - external source files

    6 votes

    Easy question for a coder well-versed in JS.

    I'm building a Wordpress site that uses jQuery AJAX methods, reloading either my entire content area when a top nav link is clicked or my main content area when a sidebar nav link is clicked. I want to be sure that the AJAX call is only issued if the user's browser supports JavaScript. I found some reference material here and on other sites that said by referencing my script externally, a browser unequipped with JavaScript would simply ignore all JS files. Is this accurate? I considered using php:

    $my_arr = get_browser(null,true);if $my_arr['javascript'] == 1 {
      echo '<script type="text/javascript" src="path/to/script"';
    }
    

    The UX I'm going for is if JS is enabled, then fire AJAX calls; if JS is disabled, just send the user to the page they've requested.

    e.g.

        <?php
        /**
         * The template for displaying all pages.
         *
         $ajxy = $_GET['ajxy'];
         if(!is_null($ajxy)) {
           $ajax_code = $ajxy; 
         }
    
         if(!$ajxy) {
           get_header(); 
         }
         ?>
    
        <?php if(!$ajax_code) { ?>
                <div id="primary">
                  <div id="content" role="main">
                     <div class="container_12" id="contentWrapper">
        <?php } ?>
    
                       <div id="contentContainer" <?php if($ajax_code) { echo 'class="ajxn"'; } ?>>
    
        <?php while ( have_posts() ) : the_post(); ?>
    
                        <div class="grid_8" id="contentGrid">
                            <?php 
                                get_template_part( 'content', 'page' ); 
                            ?>
                        </div>
                            <?php get_sidebar(); ?>
    
                        <?php endwhile; // end of the loop. ?>
                        </div>
    
                    <?php if(!$ajax_code) { ?>
                    </div>
                    </div><!-- #content -->
                </div><!-- #primary -->
                <?php } ?>
    
        <!---My Ajax Loading Script -->
        <script type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/js/ajxy.js"></script><!---My Ajax Loading Script -->
    
        <?php 
        if(!$ajxy) {
            get_footer(); 
        }
        ?>
    

    and the script:

        function ajxnOff(list, ajxnCode, wrapper, container) {
            jQuery(list).click(function(e) {
                e.preventDefault();
    
                var $lnkGoz = jQuery(this).attr("href");
    
                var $lnkGozAjx = $lnkGoz + '?ajxy=' + ajxnCode;
                var $ajxyContainer = wrapper;
                var $ajxyCurThing = container;
    
                $ajxyCurThing.fadeOut(400, function() {
                        $ajxyContainer.html('<div id="loaderA"></div>');
                        jQuery("div#loaderA").fadeIn(400);
                        jQuery.ajax({
                            url: $lnkGozAjx,
                            success: function(data) {
                                    jQuery("div#loaderA").delay(2000).fadeOut(400, function() {
                                        $ajxyContainer.html(data);
                                        jQuery("div.ajxn").fadeIn(400);
                                        jQuery.remove("div#loaderA");
                                    });
                            }
                        });
    
                });
            });
        }
    
        jQuery(document).ready(function() {
            ajxnOff(jQuery("ul#topNavList a"), 1, jQuery("div#contentWrapper"), jQuery("div#contentContainer"));
            ajxnOff(jQuery("ul#sidebarNavList a"), 2, jQuery("div#contentGrid"), jQuery("div#contentPageContainer"))
        }); 
    

    I've been learning to code on my own for about 6 months and don't have any books on the subject, so any help from the experts around here is greatly appreciated.

    Yes, if the user's browser either doesn't support JS or has JS disabled, script tags are essentially ignored. It doesn't hurt to include them no matter what, you just have to plan your site for what happens when they're not utilized.

    As far as AJAX versus page reload goes, you simply code your site as if there were no AJAX, i.e. all links should have appropriate href attributes point to where they should go. If JS is enabled, you attach your AJAX to the links via its onclick handler and prevent the default action by returning false from whatever function handles the click event.

    What happens if a user exits browser or change page before AJAX request is over

    6 votes

    I am calling a php script over ajax to do some database maintenance. If the user closes the page, hits back or clicks a link, will the php script be fully executed? Is there a way to do it? Maybe if the php script called the exec() method or something similar, which would in turn call a script via the console as such: $ php /var/www/httpdocs/maintenance.php ?

    Looked on the internet but did not know how to ask to get a good answer, so I didn't find the answer.

    As long as the user agent (browser, etc.) has fully sent the request, the server has all it needs and will complete the request and try to send back a response.

    In fact, this sort of "pinging" behavior is often used for "heartbeat"-like processes that keep a service warm or perform periodic maintenance.

    Confused about jQuery $.get and $.load

    5 votes

    On my site, I would like to implement AJAX page loading, as seen on Facebook, Twitter, and the comparatively smaller site Kotaku Gaming.

    Basically, this is what I want to do: have a header that remains static throughout all pages on the domain, and only load content into a specific container, using AJAX and jQuery.

    jQuery's $.load() is almost perfect— but only almost. This is basically the code I'd use:

    $("#content").load("site.html");
    

    However, when another page is "loaded" with this function, the URL does not change. This will ruin bookmarking as well as linking, and is therefore unacceptable. The URL needs to change.

    The problem with $.get() is that the header does change along with the rest of the page, which of course is not what I'm looking for.

    Can anybody please help me accomplish this? If the sites mentioned above can do it, why can't I?

    The first answer on How can I change the page URL without refreshing the page? should do the trick for you - using pushstate to push the new address. Note this won't work in older browsers, I'd suggest the best theory is to fall back to traditional methods then.

    cross domain issue with Jquery

    5 votes

    I'm trying to access webservice in another domain and it returns nothing. later I figured out it was a issue bcause of cross domain acess.

    I searched online and there are so many articles but none is readable by newbie like me. :(

    Can someone help me out how to access the webservice??

    following is my code.

    //variables for Add Contacts
    var addAccountServiceUrl = 'http://crm.eyepax.net/organization.asmx?op=WriteOrg'; // Preferably write this out from server side
    var OrganizationID=123;
    var ParentID=123    ;
    var AccountManagerID="123";
    var OrganizationName="Testapple";
    var IncorporationNo="23";
    var PostAddress="asdfklj asldfj";
    var CountryID="LK";
    var VisitAddress="asldkf asldkf asldfas dfasdf";
    var VisitCountryID="LK";
    var VisitSwithboard="242344";
    var VisitFax="234234";
    var Www="http://www.eyepax.com";
    var Active=true;
    var RegBy=345345345345;
    var ConfigurationCode="28BC9CC3@BFEBFBFF0001067A";
    var Flag=1;
    var LicenceOrganazationID=1;
    var sErr;
    
    function addContact()
    {
    //this is to be commented soon! 
    alert("function called");
    //update the webservice soapmesg
    
    var soapMessage =
    '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> \
    <soap:Body> \
        <WriteOrg xmlns="http://eyepax.crm.com/Organization"> \
          <OrganizationID>'+OrganizationID+'</OrganizationID> \
          <ParentID>'+ParentID+'</ParentID> \
          <AccountManagerID>'+AccountManagerID+'</AccountManagerID> \
          <OrganizationName>'+OrganizationName+'</OrganizationName> \
          <IncorporationNo>'+IncorporationNo+'</IncorporationNo> \
          <PostAddress>'+PostAddress+'</PostAddress> \
          <CountryID>'+CountryID+'</CountryID> \
          <VisitAddress>'+VisitAddress+'</VisitAddress> \
          <VisitCountryID>'+VisitCountryID+'</VisitCountryID> \
          <VisitSwithboard>'+VisitSwithboard+'</VisitSwithboard> \
          <VisitFax>'+VisitFax+'</VisitFax> \
          <Www>'+Www+'</Www> \
          <Active>'+Active+'</Active> \
          <RegBy>'+RegBy+'</RegBy> \
          <ConfigurationCode>'+ConfigurationCode+'</ConfigurationCode> \
          <Flag>'+Flag+'</Flag> \
          <LicenceOrganazationID>'+LicenceOrganazationID+'</LicenceOrganazationID> \
        </WriteOrg> \
      </soap:Body> \
    </soap:Envelope>';
    
    $.ajax({
    url: addAccountServiceUrl,
    type: "POST",
    dataType: "xml",
    data: soapMessage,
    success: endAddContact,
    error: function(jqXHR, textStatus, errorThrown) {alert("failure"); console.log(textStatus);console.log(errorThrown);},
    contentType: "text/xml; charset=\"utf-8\""
    });
    
    return false;
    }
    
    function endAddContact(xmlHttpRequest, status)
    {
        console.log(xmlHttpRequest);
        console.log(status);
        alert("webservice called!");
     $(xmlHttpRequest.responseXML)
        .find('WriteOrgResponse')
        .each(function()
     {
       var orgres = $(this).find('WriteOrgResult').text();
       var error = $(this).find('vstrError').text();
    
       alert(orgres +' -'+ error);
     });
    
     var a = $(xmlHttpRequest.responseXML).find('WriteOrgResult');
     var b = $(xmlHttpRequest.responseXML).find('vstrError');
     console.log("a"+a.text());
     console.log("b"+b.text());
    }
    

    Browsers do not allow cross-domain AJAX calls. Only cross-domain JSONP requests are allowed.

    To use JSONP requests, you have to change the dataType property to jsonp. This means however you can not request XML, but JSONP only.


    A bit about JSONP:

    The <script> tag bypasses the cross-domain limitations. Which means that you can use that tag to get data from other servers. That tag doesn't support all kinds of languages, hence XML is not supported.

    JSONP is basically JSON, but with a function call around it like this:

    functionname({"property":"value"})

    I can see you wondering: "What is that functionname doing there?"

    That's EXACTLY the difference with JSON. Because the function is wrapped around it, you can use the actual data!

    <script type="text/javascript">
    var functionname = function(json) {
        alert(json.property);
    }
    </script>
    <script type="text/javascript" src="http://www.domain.com/jsonp"></script>
    

    If you replace the second script tag with the response content, it'll all make sense:

    <script type="text/javascript">
    var functionname = function(json) {
        alert(json.property);
    }
    
    functionname({"property":"value"});
    </script>
    

    Believe it or not, but this minor difference actually enables us to make cross-domain requests much safer.

    Another thread about JSONP