Best jquery questions in June 2012

What's wrong with the jQuery live method?

15 votes

The live() method was deprecated in jQuery 1.7. The jQuery docs now recommend

Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

I understand how on and delegate work, but I don't understand why they are better. live() is simpler and easier to use.

Is there a reason why live was deprecated? How are the other methods better? Will anything bad happen if I continue to use live?

See some of the explanations here:

http://www.ultimatewebtips.com/why-jquery-live-is-a-bad-option-to-use/

quote

  1. You can’t use live for reusable widgets.

  2. stopPropagate() doesn’t work in live

  3. Live is slower

  4. Live isn’t chainable

further beauty of on is that streamlines all events quite well : http://api.jquery.com/on/ D'uh you know about the api link and see how .on works :)

Quote

The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers. For help in converting from older jQuery event methods, see .bind(), .delegate(), and .live(). To remove events bound with .on(), see .off(). To attach an event that runs only once and then removes itself, see .one()

Working with data in jQuery

14 votes

I would like to ask for more an opinion than a question: What would the community recommend to do when you must do a webpage with lots of data, for example, a products listing, that should have some functionality like buy (adds to cart), sorting, etc. if you have to manipulate the data of the current product - price, title, image, link and other attributes? How you do it in your projects?

For example we have a page with dozens of products, each of them has attributes: price, title, description, image(URL), link(URL). How would you store the data to use it on some user interaction? Personally, I've done it by just inserting each of the attribute in tags, something like:

<div class="product" data-product_id="123">
  <div class="pr_title">Title</div>
  <div class="pr_body">Body</div>
  <div class="pr_img"><img src="http://www.www.www/img.png"></div>
  <div class="pr_link"><a href="http://www.stackoverflow.com/">Buy!</a></div>
</div>

This way I have my html structure for presentation and I worked with data in jQuery by something like:

var url = $('.product').find('.pr_link').find('a').attr('href');

But when the project got big and there were 10-15 more attributes added to each element, getting data from current product got pretty complicated and the code became mostly unreadable.

I thought of using same structure, but to keep data in some object like:

var products = {
    1: {
        title: "abc",
        description: "lorem ipsum",
        price: 25.19,
        img: "http://www.www.www/img.png",
        link: "http://www.stackoverflow.com"
    }
}

and keep markup as simple as possible, only using elements and styles needed for design with css:

<div class="product" data-product_id="123">
  <div class="title">Title</div>
  <div>Body</div>
  <img src="http://www.www.www/img.png">
  <a href="http://www.stackoverflow.com/">Buy!</a>
</div>

so onClick I would need to retrieve the id of the product and query it in our object "products":

var url = products[id].title;

While this is the most convenient way to work with it requires a new object.

Another idea was to keep all data in data- attributes of the parent div element like:

<div class="product" data-product_id="123" data-title="abc" data-body="Body">

but for much as I know jQuery doesn't work with data attributes well (natively).

So what are your suggestions? Maybe you have some even better ideas to share.

P.S. I tried to find some information on the subject, but most likely failed to find the way to formulate it well so I found nothing about it. If there are links or even similar questions on stack exchange sites, please feel free to post them. Thank you in advance!

You can use HTML5 data attribute to store products data, as you have several properties of products to associate with each product block, you can JSON encode the object and assign to the top element, and then can access that on user interaction on that element or any child element.

var product = {
    title: "abc",
    description: "lorem ipsum",
    price: 25.19,
    img: "http://www.www.www/img.png",
    link: "http://www.stackoverflow.com"
};
$(selector).data('product',JSON.stringify(product));

then to retrieve the object you can do on any event's callback

$product = $.parseJSON($(elem).data('product'));

In fact both facebook and twitter used data attributes to store associated data with tweets and stories. For example here goes some html of a FB story

<li data-ft='{"qid":"5757245005920960301","mf_story_key":"7164261693049558180"}'
 id="stream_story_4fe5d7d51bc415443080257">

You can see facebook is storing JSON encoded data into the data-ft attribute.

Similarly an example of a Twitter tweet html

<div data-tweet-id="216534496567230464" data-item-id="216534496567230464" 
data-screen-name="onimitch" data-user-id="123682011" data-is-reply-to="">

So twitter is saving associated data for a tweet into different attributes like data-tweet-id, data-user-id.

So As they both handle's a lot amount of data, I think You can also use either of the method to save your data without any performance issue.

If you store data with individual keys then be aware of the automatic data conversion that .data() does as @nnnnnn has already mentioned in comment.

Demo With .data() : http://jsfiddle.net/joycse06/vcFYj/

Demo With .attr() : http://jsfiddle.net/joycse06/vcFYj/1/

Understanding "this" keyword

14 votes

In this commit there is a change I cannot explain

deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );

becomes

deferred.done( arguments ).fail( arguments );

AFAIK, when you invoke a function as a member of some object like obj.func(), inside the function this is bound to obj, so there would be no use invoking a function through apply() just to bound this to obj. Instead, according to the comments, this was required because of some preceding $.Callbacks.add implementation.

My doubt is not about jQuery, but about the Javascript language itself: when you invoke a function like obj.func(), how can it be that inside func() the this keyword is not bound to obj?

My doubt is not about jQuery, but about the Javascript language itself: when you invoke a function like obj.func(), how can it be that inside func() the this keyword is not bound to obj?

Well, the only way this is possible is if obj.func references a bound function, then it doesn't matter how you call it. In that case it doesn't matter how you call the function, whether you do obj.func(), func(), func.call({}), func.apply({}) doesn't matter at all. I'm not sure how the commit is related to this, however.

To clarify, I am answering the quoted question interpreted as:

Given a call signature like: obj.func(), how is it possible that this is not obj inside the called function for the call?

jQuery: Why does $.ajax() not wait for request to complete before returning?

13 votes

I've just spent 3 hours debugging a bit of code only to find it was caused by me assuming that the execution order of the following code was linear:-

$.ajax( {ajax options} );
console.log('I was assuming this would execute once the ajax request was complete');

This isn't the first time that this has caused me problems and I was just wondering what the reason for this behavior was?

Is it so that any ajax requests don't hold up other script execution that may be unrelated to the ajax request?

Most of the other answers are answering how to deal with this. I'd like to look, very briefly, at why asynchronous is good in this case.

In fact, most in-browser Javascript is asynchronous. Take, for example, this code:

document.getElementById('foo').onclick = function() {
    alert('foo clicked');
};
document.getElementById('bar').onclick = function() {
    alert('bar clicked');
};

Which will run first? You don't know, because of the asynchronicity inherent to the browser model (or in fact most event-driven code). You run code when an event occurs. You set up the document, then wait for the event to happen, and your code could be executed in all kinds of different orders, depending on what events happen first. Javascript code needs to be executed during the whole lifetime of the page, not just when it's first created.

So in general Javascript programming (or at least, Javascript programming beyond the simplest level) is often going to be asynchronous. Furthermore, it makes a great deal of sense for HTTP requests to be asynchronous as well.

First, as you imply in your question, making the code synchronous would block execution. That is to say, you probably don't want to make an animation wait two seconds to start because you're making an HTTP request two lines further up. Server response times can be (a) irregular and (b) slow, so it makes no sense for the design of your application to depend on the speed of your server's response.

Second, and more importantly, your user isn't going to stop using the page because your script is making an AJAX call. Your user doesn't care. Your user probably will care that your normal onscroll behaviour isn't working because your script is currently tied up with an unrelated AJAX request. To tie in with the asynchronous nature of the whole of browser Javascript programming, the vast majority of HTTP calls should be non-blocking, asynchronous.

how does the browser tell the difference between user click and programmatic click?

13 votes

If I initiate a click with jquery which does window.open(), it is blocked by pop up blocker, If I do the click manually the window is not blocked. How does the browser differ between the two?

The Firefox implementation of this is discussed at length on this bug, and this other bug has some further interesting background, including what lengths sites will go through in order to foist an unwanted popup window on unsuspecting users (in this case: calling window.open() from within an image load event). If you search around Bugzilla you'll find that the Mozilla people took a number of years to get this all working correctly, for example here's a bug from 2001.

The way it works currently is this: When Firefox receives a click event from the operating system, for a certain amount of time window.open() is enabled in JavaScript (look for dom.disable_open_click_delay in about:config). If you call the click() event from code without a user click occurring then the first step, the enabling of window.open() never occurs, though the call to window.open() will itself succeed to stop sites detecting that you have popup blocking enabled.

I'm not sure how other browsers implement this stuff but it would be surprising to me if it was much different.

How do you detect if an html element can append child nodes?

12 votes

I created a custom jquery event called 'loading' in my application. I want to append a masking element with a spinner, when this event is triggered. I can figure out that part without problems. However, some elements (images, form inputs, etc..) cannot append child elements. I need to be able to detect if the target of this event can receive child elements. If it cannot, then I will add the spinner & mask to it's parent element.

You have to check the name:

/*global $, jQuery */

function isVoid(el) {
    var tags = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
                 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'],
        i = 0,
        l,
        name;

    if (el instanceof jQuery) {
        el = el[0];
    }

    name = el.nodeName.toLowerCase();

    for (i = 0, l = tags.length; i < l; i += 1) {
        if (tags[i] === name) {
            return true;
        }
    }
    return false;
}

And use it like this:

var el = document.getElementById('el'),
    elj = $('#el');

if (!isVoid(el)) {
    // append
}

jQuery data() returns undefined, attr() returns integer

11 votes

I have the following code:

alert($embellishment.data("embellishmentId"));
alert($embellishment.attr("data-embellishmentId"));

The first alert returns undefined, whereas the second alert returns an integer, 3.

-- SEE DEMO --

I'm using jQuery version 1.7.2 (data was added with version 1.4 I believe)

Why is this? Should I be using data() at all if its not returning the right values?

OK. I found the problem by interpreting jQuery docs.

When you write:

$embellishment.data("embellishmentId");

it is handled by jQuery as compound attribute:

<div data-embellishment-id="3"></div>

So, to solve the problem you can use lower case in the data key otherwise it just addresses the different attribute.

<!-- HTML -->
<div data-embellishmentid="3"></div>

// JavaScript
$embellishment.data("embellishmentid");

jQuery: $(this) vs. this.$()

11 votes

In Ember.js's docs, they have a jQuery code snippet with the following syntax:

this.$().button();

Is this snippet only turning this into a jQuery object so that the jQuery UI .button() function can be called on it?

Would this snippet be identical?

$(this).button();

The source code explains this as follows:

/**
    Returns a jQuery object for this view's element. If you pass in a selector
    string, this method will return a jQuery object, using the current element
    as its buffer.

    For example, calling `view.$('li')` will return a jQuery object containing
    all of the `li` elements inside the DOM element of this view.

    @param {String} [selector] a jQuery-compatible selector string
    @returns {Ember.CoreQuery} the CoreQuery object for the DOM node
  */
  $: function(sel) {
    return this.invokeForState('$', sel);
  },

So to answer your question: no it's not the same as $(this), which would wrap the ember view instance in a jQuery object...

Can you have a javascript hook trigger after a DOM element's style object changes?

9 votes

An element has a javascript style object which contains the different names and values of css styles. I'd like to trigger a function every time this object changes without use of polling. Is there any way to do this in a way that is cross-browser compatible and would work reliably with third party code (because let's say you're providing a drop-in script)? Binding a javascript event like DOMAttrModified or DOMSubtreeModified won't suffice because they don't work in Chrome.

Edit 2:

  1. Fix for propertName in IE7 & IE8

Edit 1:

  1. Handle multiple elements
  2. Ordered the conditions as MutationObserver, DOMAttrModified and onpropertychange for better implementation.
  3. Added modified Attribute Name to the callback.

Thanks to @benvie for his feedback.

DEMO: http://jsfiddle.net/zFVyv/10/ (Tested in FF 12, Chrome 19 and IE 7.)

$(function() {
    (function($) {
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

        function isDOMAttrModifiedSupported() {
            var p = document.createElement('p');
            var flag = false;

            if (p.addEventListener) p.addEventListener('DOMAttrModified', function() {
                flag = true
            }, false);
            else if (p.attachEvent) p.attachEvent('onDOMAttrModified', function() {
                flag = true
            });
            else return false;

            p.setAttribute('id', 'target');

            return flag;
        }

        $.fn.attrchange = function(callback) {
            if (MutationObserver) {
                var options = {
                    subtree: false,
                    attributes: true
                };

                var observer = new MutationObserver(function(mutations) {
                    mutations.forEach(function(e) {
                        callback.call(e.target, e.attributeName);
                    });
                });

                return this.each(function() {
                    observer.observe(this, options);
                });

            } else if (isDOMAttrModifiedSupported()) {
                return this.on('DOMAttrModified', function(e) {
                    callback.call(this, e.attrName);
                });
            } else if ('onpropertychange' in document.body) {
                return this.on('propertychange', function(e) {
                    callback.call(this, window.event.propertyName);
                });
            }
        }
    })(jQuery);

    $('.test').attrchange(function(attrName) {
        alert('Attribute: ' + attrName + ' modified ');
    }).css('height', 100);

});

Ref:

  1. Detect if DOMAttrModified supported
  2. DOMAttrModified for chrome
  3. Mutation Observer
  4. Why should we avoid using Mutation events?
  5. onPropertyChange IE

Mutation Observers is the proposed replacement for mutation events in DOM4. They are expected to be included in Firefox 14 and Chrome 18

Browser Support:

onpropertychange - is supported in IE (tested in IE 7)

DOMAttrModified - is supported in IE 9, FF and Opera

MutationObservers - is very new and it worked fine in Chrome 18. Not sure how far it is supported and yet to be tested in Safari.

Thanks @benvie on adding info about WebkitMutationObserver

I need a new way to detect if there has been a change to an elements HTML

9 votes

Right now im trying to find a way to detect when an elements HTML has changed.

I'm currently trying:

var a, b;
setInterval(function() {
    a = $('#chat').text();
}, 150);
setInterval(function() {
    b = $('#chat').text();
    if (a !== b) {
        alert("There has been a new message.");
    }
}, 200);​

What I do is every 150 milliseconds I check for the HTML of #chat and then every 200 seconds I check the HTML again and then check if variable a does not equal to variable b them in the future I will so something with that but for right now I just alert something.

You can see it live here: http://jsfiddle.net/MT47W/

Obviously this way is not working and is not very accurate at all. Is there a better/different to do/achieve this?

Thanks for any help, I've been trying to figure out how to do this a better for about a week now but I just can't find a fix for this and i'm hoping I posted this problem at the right place, and at the right time.

Use a var to store the element's current text then check against it in a setInverval and update the var to store the current text after checking:

var a = $('#chat').text();
setInterval(function() {
    if (a !== $('#chat').text()) { //checks the stored text against the current
        alert("There has been a new message."); //do your stuff
    }
    a = $('#chat').text(); //updates the global var to store the current text
}, 150); //define your interval time, every 0.15 seconds in this case

Fiddle

You may as well store the value in the .data() of the element to avoid using globals.

Example using .data():

$('#chat').data('curr_text', $('#chat').text());
setInterval(function() {
    if ($('#chat').data('curr_text') !== $('#chat').text()) {
        alert("There has been a new message.");
    }
     $('#chat').data('curr_text', $('#chat').text());
}, 150);

Fiddle

Another approach, to save client's memory, you can just store the number of child divs your #chat element has:

$('#chat').data('n_msgs', $('#chat').children().length);
setInterval(function() {
    if ($('#chat').data('n_msgs') !== $('#chat').children().length) {
        alert("There has been a new message.");
    }
     $('#chat').data('n_msgs', $('#chat').children().length);
}, 150);

Fiddle


EDIT: Here's my very final addition, with a DOM mutation event listener:

$('#chat').on('DOMNodeInserted', function() {
    alert("There has been a new message.");
});

Fiddle (not tested in IE < 8)

Note: As noted in the comments, even though mutation events are still supported they're classed as deprecated by W3C due to the performance loss and some incompatibilities across different browsers, therefore it's suggested to use one of the solutions above and only use DOM Mutation events when there's no other way around.

jquery ui selectable and sortable combined

9 votes

This is what I got:
http://jsfiddle.net/hashie5/vk6rZ/
(don't mind the layout)

The first table is a combination of the second and third table, and it's this one that needs to be finished.

The seconds table has sortable (with the arrows).

The third table has selectable (dont click the arrows).

The goal is: when you select multiple items, you should be able to sort them all at the same time.

If it's to hard because of the tables, an example with lists would be great too.

In the helper function I tried cloning all selected (ui-selected class) items, but that was too buggy

EDIT:
I created a new fiddle: http://jsfiddle.net/hashie5/AZr9Z/
This works nice, but it's not 100% complete yet

UPDATED

the main code look like below.

sort : function(event, ui) {
    var $helper = $('.ui-sortable-helper'), hTop = $helper.offset().top, hStyle = $helper.attr('style'), hId = $helper.attr('id');
    if (first_rows.length > 1) {
        $.each(first_rows, function(i, item) {
            if (hId != item.id) {
                var _top = hTop + (26 * i);
                $('#' + item.id).addClass('ui-sortable-helper').attr('style', hStyle).css('top', _top);
            }
        });
    }
},
start : function(event, ui) {
    if (ui.item.hasClass('ui-selected') && $('.ui-selected').length > 1) {
        first_rows = $('.ui-selected').map(function(i, e) {
            var $tr = $(e);
            return {
                tr : $tr.clone(true),
                id : $tr.attr('id')
            };
        }).get();
        $('.ui-selected').addClass('cloned');
    }
    ui.placeholder.html('<td colspan="99">&nbsp;</td>');
},
stop : function(event, ui) {
    if (first_rows.length > 1) {
        $.each(first_rows, function(i, item) {
            $(item.tr).removeAttr('style').insertBefore(ui.item);
        });
        $('.cloned').remove();
        first_rows = {};
    }
    $("#uber tr:even").removeClass("odd even").addClass("even");
    $("#uber tr:odd").removeClass("odd even").addClass("odd");
}

​ i'm not sure i understood what you want, anyway what the code actually do is:

  1. from the 1st table, select multiple items;
  2. by holding hover one of the selected items;
  3. you are able to move those selected where ever you want in the list;
  4. mantaining the sort order of all selected items;

hope this is what you are looking for.

Match all combinations of any classes in jQuery

9 votes

I have two comma-separated selectors;

.class, .foo, .bar

.lorem, .ipsum, .potato

I'd like to be able to select any possible combination between these two groups. So it would select elements matching

.class.lorem
.class.ipsum
.class.potato
.foo.lorem
.foo.ipsum
.foo.potato
.bar.lorem
.bar.ipsum
.bar.potato

How can I achieve this effectively?

Select all elements with any class from the first set, and then filter out the elements which don't have a class from the other set:

$('.class, .foo, .bar').filter('.lorem, .ipsum, .potato')

Jquery | Get div elements in defined area

9 votes

is there a simple way to get the div elements fitting completely in a defined area?

Example:

http://i.imgur.com/oIw6i.png

<div id="redbox"> RESIZE DIV </div>

<div id="grid">
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="box3"></div>
  <div id="box4"></div>
</div>

I got 4 Boxes (grey) and I am able to resize a div (red on top of all boxes). After resize I want to know which of the div elements are fitting completely in this area.

Does anyone knows how to do this? Is there a method or function in JQUERY?

It looks to me like the withinBox plugin might help you solve this (jquery.fn.withinBox). You could use the code like this:

var area = $('#redbox'),
    offset = area.offset(),
    selected = $('#grid div').withinBox(offset.left,
                                        offset.top,
                                        area.width(),
                                        area.height()
                                        );

asp.net asmx web service returning xml instead of json

8 votes

Why does this simple web service refuse to return JSON to the client?

Here is my client code:

        var params = { };
        $.ajax({
            url: "/Services/SessionServices.asmx/HelloWorld",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            timeout: 10000,
            data: JSON.stringify(params),
            success: function (response) {
                console.log(response);
            }
        });

And the service:

namespace myproject.frontend.Services
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [ScriptService]
    public class SessionServices : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public string HelloWorld()
        {
            return "Hello World";
        }
    }
}

web.config:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
</configuration>

And the response:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

No matter what I do, the response always comes back as XML. How do I get the web service to return Json?

EDIT:

Here is the Fiddler HTTP trace:

REQUEST
-------
POST http://myproject.local/Services/SessionServices.asmx/HelloWorld HTTP/1.1
Host: myproject.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myproject.local/Pages/Test.aspx
Content-Length: 2
Cookie: ASP.NET_SessionId=5tvpx1ph1uiie2o1c5wzx0bz
Pragma: no-cache
Cache-Control: no-cache

{}

RESPONSE
-------
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 19 Jun 2012 16:33:40 GMT
Content-Length: 96

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

I have lost count of how many articles I have read now trying to fix this. The instructions are either incomplete or do not solve my issue for some reason. Some of the more relevant ones include (all without success):

ASP.NET web service erroneously returns XML instead of JSON

asmx web service returning xml instead of json in .net 4.0

http://williamsportwebdeveloper.com/cgi/wp/?p=494

http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/

http://forums.asp.net/t/1054378.aspx

http://jqueryplugins.info/2012/02/asp-net-web-service-returning-xml-instead-of-json/

Plus several other general articles.

Any help greatly appreciated.

Finally figured it out.

The app code is correct as posted. The problem is with the configuration. The correct web.config is:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.webServer>
        <handlers>
            <add name="ScriptHandlerFactory"
                 verb="*" path="*.asmx"
                 type="type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 resourceType="Unspecified" />
        </handlers>
    </system.webServer>
</configuration>

According to the docs, registering the handler should be unnecessary from .NET 4 upwards as it has been moved to the machine.config. For whatever reason, this isn't working for me. But adding the registration to the web.config for my app resolved the problem.

A lot of the articles on this problem instruct to add the handler to the <system.web> section. This does NOT work and causes a whole load of other problems. I tried adding the handler to both sections and this generates a set of other migration errors which completely misdirected my troubleshooting.

In case it helps anyone else, if I had ther same problem again, here is the checklist I would review:

  1. Did you specify type: "POST" in the ajax request?
  2. Did you specify contentType: "application/json; charset=utf-8" in the ajax request?
  3. Did you specify dataType: "json"in the ajax request?
  4. Does your .asmx web service include the [ScriptService]` attribute?
  5. Does your web method include the [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute? (My code works even without this attribute, but a lot of articles say that it is required)
  6. Have you added the ScriptHandlerFactory to the web.config file in <system.webServer><handlers>?
  7. Have you removed all handlers from the the web.config file in in <system.web><httpHandlers>?

Hope this helps anyone with the same problem. and thanks to posters for suggestions.

What is the cleanest way to disable css transition effects temporarily?

8 votes

I have a DOM element with some/all of the following effects applied:

#elem {
  -webkit-transition: height 0.4s ease;
  -moz-transition: height 0.4s ease;
  -o-transition: height 0.4s ease;
  -ms-transition: height 0.4s ease;
  transition: height 0.4s ease;
}

I am writing a jQuery plugin that is resizing this element, I need to disable these effects temporarily so I can resize it smoothly.

What is the most elegant way of disabling these effects temporarily (and then re-enabling them), given they may be applied from parents or may not be applied at all.

Add an additional CSS class that blocks the transition, and then remove it to return to the previous state. This make both CSS and JQuery code short, simple and well understandable.

CSS:

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

!important was added to be sure that this rule will have more "weight", because ID is normally more specific than class.

JQuery:

$('#elem').addClass('notransition'); // to remove transition
$('#elem').removeClass('notransition'); // to return to previouse transition

Reference for learning web socket

7 votes

I want to write a web socket client in javascript and web socket server in ruby.

Where shall I start? are there any existing libraries to reduces my work?

I'm lost and confused googling. Please provide any links where to start, given that has knowledge on ruby, javascript, basic networking in ruby.

i currently using em-websocket

EventMachine.run {

    EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
        ws.onopen {
          puts "WebSocket connection open"

          # publish message to the client
          ws.send "Hello Client"
        }

        ws.onclose { puts "Connection closed" }
        ws.onmessage { |msg|
          puts "Recieved message: #{msg}"
          ws.send "Pong: #{msg}"
        }
    end
}

for more info see another thread about ruby & websocket:

jquery getting values inside a ul li tag, but don't want a certain tag

6 votes

I'm trying to get text value inside an li tag, but it has another tag that I don't want

example:

<ul>
<li><a class="close">x</a>text</li>
<li><a class="close">x</a>more text</li>
<li><a class="close">x</a>wohoooo more text</li>
</ul>

I can get tag like so

$("ul li").text();

but it also captures x from a. How do I remove the a tag? There's gotta be a simple solution that I'm not familiar with,

Thanks!

$("ul li").contents(':not(.close)').text()

children() does not return text nodes; to get all children including text and comment nodes, use .contents() http://api.jquery.com/children/

MVC 3.0 JQUERY Partial page update

6 votes

I've a JQuery UI Date Picker. Upon selection of the date, the data on graph changes.

The issue is that when I select the date on the date picker, whole page refreshes and data gets populated.

Is there anyway, I can just update the graph which is on tag? Note, upon selection of the date, jquery posts to server and gets the new data for selected date.

I'm using $.ajax({ }); to make a call to the server. I would have thought this will do a trick but it is not the case.

Any help will be much appreciated.

Try this

$('#datepickerid').datepicker({
   onSelect: function(dateText, inst) { 
     $.ajax({ ... } );
     return false;
   }
});

Number of Ajax Requests increases with live jQuery

6 votes

I have the code below which I use clone() and live(). The code is being load in a jQuery UI dialog with a link. Whenever I click the link it goes to server and fill the dialog with the code below. The first time page is being loaded it works fine, but if I close the dialog and click the link again to get the dialog the number of Ajax requests which is being send increases.

The first time I send trigger the change I send only one request, I close the dialog and load it again and then trigger the change, it send two Ajax request at same time, the third time three request at same time and so on.

Where do you think my problem is?

<input id="TaskId" name="TaskId" type="hidden" value="18" />
<div id="MainDiv">
    <div id="toClone">
        <div style="display: inline;">
            <select id="Tasksess">
                <option value="">لطفاً کار را انتخاب کنيد</option>
                <optgroup label="کار های جديد">
                        <option value="16"style="">q3fe</option>
                        <option value="18"style="">fjhv j</option>
                        <option value="19"style="">wref</option>
                        <option value="25"style="">ff</option>
                </optgroup>
                <optgroup label="کار های در دست اقدام">
                        <option value="13"style="">rr</option>
                        <option value="15"style="">yy</option>
                </optgroup>
                <optgroup label="کار های تمام شده">
                        <option value="14"style="">tt</option>
                        <option value="18"style="">fjhv j</option>
                </optgroup>
            </select>
        </div>
        <div style="display: inline;">
            <select id="Statusess" name="Statusess"><option value="">لطفاً وابستگی را انتخاب کنيد</option>
<option value="1">پيشنياز</option>
<option value="2">همنياز</option>
</select>
        </div>
        <div style="display: none;" id="Ok">
            ok
        </div>
        <div style="display: none;" id="noOk">
            تکراری
        </div>
        <div id="loadingGif" style="display: none;">
            <img src="/Content/Images/ajax-loader/253L.gif" alt=""/>
        </div>
    </div>
</div>
<script type="text/javascript">
    $(document).ready(function () {

        var Maindiv = $("#MainDiv");
        var toClone = $("#toClone");

        //$("#Statusess").each(function () {
            $("#Statusess").live('change', function () {
                if ($(this).find(":selected").val() != "") {                    
                    if ($(this).parent().prev().find(":selected").val() != "") {
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
                        $.ajax({
                            url: '/ProjectAdmin/Project/AddTaskDependency?MainTaskId=' + $("#TaskId").val() + '&DependentTaskId=' + $(this).parent().prev().find(":selected").val() + '&Status=' + $(this).find(":selected").val(),
                            type: 'GET',
                            success: function (data, status) {
                                if (data != "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                                }
                                else if (data == "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                                }
                                var div = $('div:eq(0)', Maindiv).clone();
                                Maindiv.append(div);
                            }
                        });
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

                    }
                }
            });
        //});

    });
</script>

as stated above you should use .delegate() instead of .live().

In order to use delegate all you need to do is specify a parent in which you will be listening to and a selector on which it's going to act.

Try this:

<script>
$(function(){
var Maindiv = $("#MainDiv");
var toClone = $("#toClone");

$("#MainDiv").delegate('#Statusess','change', function () {
    if ($(this).find(":selected").val() != "") {                    
      if ($(this).parent().prev().find(":selected").val() != "") {
        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
        $.ajax({
            url: '/echo/html/',
            type: 'POST',
            success: function (data, status) {
                data = "1";
                if (data != "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                }
                else if (data == "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                }
                var div = $('div:eq(0)', Maindiv).clone();
                Maindiv.append(div);
            }
        });
        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

    }
  }
});
});
</script>

Here you a have a working jsfiddle, also here is a link for reference to .delegate() function.

JavaScript/jQuery clearInterval being set in .each

5 votes

So I have an interval I create for each of my posts, the issue is that I load new posts and remove the old ones, so obviously I'd like to stop the interval for the previous posts. However I can't seem to figure out how to do this. Could someone explain to me how to properly go about doing this? I'm completely lost.

$(".post").each(function(){
    myInterval = setInterval("postStats('"+$(this).attr('id')+"')", 500);
});

function postStats(pid) {
    //do some stuff
}

$(".button").click(function(){
    clearInterval(myInterval);
});

You can store the interval ID in a data attribute:

$(".post").each(function () {
    var that = this;
    var myInterval = setInterval(function () {
        postStats(that.id);
    }, 500);
    $(this).data("i", myInterval);
});

and clear the interval specific to each .post like so:

$(".button").click(function () {

    // assuming the button is inside a post
    clearInterval($(this).closest(".post").data("i"));
});

and like SiGanteng said, you should pass a function object to setInterval rather than a string, which only gets eval'd.