Jquery binding to keyup - javascript

I'm having some problems binding to the keyup event of a textarea control. I'm trying the below
var shortDescInput = $('nobr:contains("Short Description")').closest('tr').find($('textarea[title="Short Description"]'));
// this doesn't work
shortDescInput.bind('keyup', function () {
countShortDescChars();
});
// Nor this
shortDescInput.keyup(function () {
countShortDescChars();
});
Am I missing something here that's really obvious? This is working for other controls, for example binding events to radiobuttons. I've checked and I'm defiantly selecting the right textarea with
var shortDescInput = $('nobr:contains("Short Description")').closest('tr').find($('textarea[title="Short Description"]'));
I just never seem to get the keyup event....

find($('textarea[title="Short Description"]')) is highly inefficient. For your purposes, find should take a selector as it's argument.
When you pass in a jQuery object to find, jQuery first queries the DOM from the top and finds all elements that match that selector. Then, find loops through all of these results until it finds one that matches the specified parents.
You should, instead, use:
find('textarea[title="Short Description"]')
Also, use .on instead of .bind. .bind is set to be deprecated in future releases for it's inefficiency.
shortDescInput.on("keyup", countShortDescChars);
And the revised code:
$(function () {
var shortDescInput = $('nobr:contains("Short Description")').closest('tr').find('textarea[title="Short Description"]');
shortDescInput.on("keyup", countShortDescChars);
});

To verify that a selector is working use .length with a console.log() or old fashioned alert() :
var shortDescInput = $('nobr:contains("Short Description")').closest('tr').find('textarea[title="Short Description"]');
alert(shortDescInput.length);
You can also go step by step to identify the one not returning anything :
alert($('nobr:contains("Short Description")').length);
alert($('nobr:contains("Short Description")').closest('tr').length);
alert($('nobr:contains("Short Description")').closest('tr').find('textarea[title="Short Description"]').length);
Second try. using .on() instead of .bind() :
shortDescInput.on('keyup',function(){countShortDescChars();});

So I played along with your fiddle and...
There IS something wrong with your selector.
First I remove the script tags from the js part.
then remove the script tag in your html cause it broke the fiddle.
Switched to jQuery 1.8.0 cause MooTools is not what we want.
added shortDescInput = $('textarea'); after your giant selector, event is triggered!
Added again shortDescInput = $('textarea'); in your function to make the counter work.
So again, let's now try to figure why your selector is not working :-)
Edit:
Found it!
I replaced your .closest() with .parent().next() because I kind of think .closest() was targeting the parent .
var shortDescInput = $('nobr:contains("Short Description")').parent().next().find('textarea[title="Short Description"]');

The problem is that at least in the fiddle, the <tr> wasn't in a <table>and so it was removed from the DOM by the browser. Wrapping the <tr> in a <table> made the fiddle work.
Demo: http://jsfiddle.net/kNkXE/9/

Related

dynamic add and delete input field jquery 1.10

Hi I'm having trouble with this fiddle I found somewhere it works perfectly on 1.4 jquery
but I am using 1.10 version of Jquery.
I notice that live method is deprecated in 1.10 so I user on to replace live but still not doing as it supposed to do.
my toubled fiddle is here
I used to code back end so please spare me, could anyone help me with this?
You should use parent selector $("#content") with on() and use prop() to make button disable like,
$("#content").on("click", ".plus",function(){
var parent = $(this).closest(".iteration");// use closest
parent.append('<input type="text" value="Create a task for this iteration" />');
var nbinput = parent.find("input[type='text']").length;
if(nbinput == 5)
parent.find(".plus").prop("disabled",true);// use prop()
if(nbinput > 0)
parent.find(".moins").prop("disabled",false);
});
$("#content").on("click",".moins", function(){
var parent = $(this).closest(".iteration");// use closest
parent.children("input").last().remove();
var nbinput = parent.find("input[type='text']").length;
if(nbinput < 5)
parent.find(".plus").prop("disabled",false);// use prop()
if(nbinput == 0)
parent.find(".moins").prop("disabled",true);
});
Demo
To make on work like you wanted you need to specify an element that won't be changed as the main selector and pass the dynamic element selector as the second parameter:
$("#content").on("click", ".plus", function(){
Also, there was an error with the code that disabled the plus and minus buttons, instead of setting the disabled attribute to empty you want to remove it completely:
parent.find(".moins").removeAttr("disabled");
Finally, changed the .parent().parent().parent('.iteration') to
$(this).closest(".iteration");
As this is much simpler and less likely to be broken by changes to your html.
http://jsfiddle.net/infernalbadger/L3s3w/3/

CSS selector for the next element of an element which fires onclick?

I have an element which listens to the onclick event. It calls a function once it was clicked. After that element is a < dd > which I want to select in a CSS selector. The element which is clicked, is a < select >. How would I do that?
This is the HTML:
<select onclick="myFunction();">...</select>
<dd>...</dd>
function myFunction() {
// What do I have to write for the ??????
$$('?????? dd').toggle();
}
Note: There are many of those select/dd combination, so I really have to get the next dd after the firing element.
The minimal change is: Pass this into your function:
<select onclick="myFunction(this);">...</select>
...and then:
function myFunction(select) {
$(select).next().toggle();
}
$ enhances the element, then you can use next to move to the next element. If you like, you can use .next('dd'), but in your case the dd is the next element.
That still uses onxyz attributes, which is a bit old-hat. You might consider hooking things up via observe instead.
I am guessing you mean this:
this.next("dd");
(specifying dd so when there's an error in the mark up, no other element is selected)
If you are trying CSS selectors only, try the following:
$("select + dd").toggle();
Note: this will toggle all dds that follow a select.
Note 2: apparently this does not work in Prototype but it does work in jQuery.
See T.J.Crowder's comment:
[This doesn't work in Prototype] because $ in Prototype looks up elements by ID. $$ is more like
jQuery's $, but what it returns doesn't do set-based operations like
jQuery does (or rather, not the same set-based operations as the ops
you can do on individual elements; you have to use invoke).
next() works on both jQuery as Prototype.
Use:
$(this).next("dd").toggle(); --> this is Jquery
$(element).next("dd").toggle();
see the link Element.next
<select>...</select>
<dd>...</dd>
$('select').change(function(){
$(this).next("dd").toggle();
});
Better use unobtrusive javascript, so your js is better coupled from html markup.
HTML:
<select><option value="test">Test</option></select>
<dd>Test</dd>
JS:
//Event.observe(window, "load", function() {
document.observe('dom:loaded', function() {
$$('select')[0].observe('click', function(event) {
var next = event.element().next();
next.toggle();
});
});
JSFiddle

Jquery setting $(this) to another element while dragging it

I am trying to set the $(this) -while dragging the- element to a new one, but I cant seem to get it to work without getting an error in my Firebug:
invalid assignment left-hand side
$(this) = $("#external-events.temp-class-for-detection:last");
//Gives the same result.
$(this) = $("#external-events.temp-class-for-detection:last")[0];
The above examples acctualy do work in my case, but I still get the error so I assume its not the right way to do it. I have also tried other ways to do it (that dont work at all):
//Does not work at all.
$(this)[0] = $("#external-events.temp-class-for-detection:last")[0];
//Does not work at all.
$(this)[0] = $("#external-events.temp-class-for-detection:last");
//Does not work at all.
$(this).html("#external-events.temp-class-for-detection:last");
Here is a bigger picture of what I am doing:
$(this).html("<div class='external-event'>");
$(this).data('eventObject', { title: event.title, id :event.id });
$(this).text(event.title);
$(this).addClass("temp-class-for-detection");
$(this).addClass("external-event");
$(this).appendTo( "#external-events" );
$(this) = $("#external-events.temp-class-for-detection:last");
This may look like a terrible way to do it, but I need to move the $(this) element out of its parent div, add it to whatever div and then set $(this) back to itself. Just that now it is refrenced to another parent div.
EDIT: I want to specify that this all is trying to be done while the element itself is being dragged. Also, I get the result I want in Firefox but with an error in my Firebug. In IE the element wont stick at all.
I think your a little mixed up with what $(this) is. reference to this is whatever the current scope is. $(this) for example is the jquery selector for the current scope.
instead of doing:
$(this) = $("#external-events.temp-class-for-detection:last");
just do this:
var _this = $("#external-events.temp-class-for-detection:last");
And now whenever you want to reference the #external-events selector simple _this.css
Hmm, I'm not sure why you have to do this (no pun intended), but if you must, why not use an alternate variable? You can use a dollar sign, if that makes you happy:
$this = $("#external-events.temp-class-for-detection:last");
Actually, if I'm understanding you correctly, can't you just use a .each() statement? It's a bit hacky, but lets you use $(this):
$(this).html("<div class='external-event'>");
$(this).data('eventObject', { title: event.title, id :event.id });
$(this).text(event.title);
$(this).addClass("temp-class-for-detection");
$(this).addClass("external-event");
$(this).appendTo( "#external-events" );
$("#external-events.temp-class-for-detection:last").each(function() {
$(this).css('foo', 'bar'); // Now $(this) points to the thing above
});
I think what you really want to do it this:
var that = $(this).clone();
.. do all your stuff to that
that.appendTo( "#external-events" );
$(this).replaceWith($("#external-events.temp-class-for-detection:last"));
You need to clone it because otherwise all your work will just be replaced (and in the new location you appended it to). It sounds like you want to do a bunch of stuff and then replace its original incarnation with that select. This should do that.
You don't need to do anything.
The $(this).appendTo( "#external-events" ); will change the parent. $(this) will continue to to point to the moved element.

Not adding event in jquery

Not tuch events on input if i use filter "not".
In task i need event blur add to all elements except input in
div with id ending on "cont".
this not work
$("input[id$=inp]").not($("div[id$=cont]").children()).live("blur",someFoo);
and this dot work too
$("input[id$=inp]").not("div[id$=cont]:children").live("blur",someFoo);
Any idea why it hapan ?
How solve this problem ?
Update: live Has to be called directly on the result set.. This works:
$("input[id$='inp']:not(div[id$='cont'] input)").live(...)
DEMO
The children call looks wrong here. Try:
$("input[id$='inp']")
.not("div[id$='cont'] input")
.live("blur",someFoo);
If you are not adding these elements dynamically, then there is no need to use .live:
$("input[id$='inp']")
.not("div[id$='cont'] input")
.blur(someFoo);

jQuery toggle();

I am loading data dynamically by AJAX into a cluetip (http://plugins.learningjquery.com/cluetip/#).
I want to toggle the results from a link like so:
$(document).ready(function() {
$("#calendarLink").live("click",( function() {
$("#result").toggle();
}));
});
For some reason the above will not work. Can you suggest an alternative?
Couple of questions/points
Do you really need to use .live() You're using an ID selector, so there should only ever be one of these.
Also, you have an extra set of brakets. Probably not a problem, but you could remove them:
$(document).ready(function() {
$("#calendarLink").click( function() {
$("#result").toggle();
});
});
Perhaps the toggle() function isn't be used properly?
See here http://api.jquery.com/toggle/
I'm not sure if this is new functionality only for jQuery 1.4 but it appears the toggle function requires parameters.
The following code is correct (demo online - http://jsbin.com/ehate/edit):
$("#calendarLink").live("click", function(e){
$("#result").toggle();
});
You use $.live() only if #calendarLink will be added dynamically later. If it isn't, use a regular click:
$("#calendarLink").click(function(e){
$("#result").toggle();
});
If this is not working for you, be sure to check your #calendarLink and #result elements in your HTML. Make sure the ID values are correct. Mainly, be sure your casing is correct.
Two elements in the same page can't have the same id.
u used
$("#result").toggle();
'I want to toggle the results from a link ...'
So the result elements should have the same class , not id.
The code should be :
$(".result").toggle();
'#' changed into '.'

Categories