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

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.

Related

Function hide() , prev() , show() are assembled to get required result but unable to understand its working?

I have got a script which works fine. The script is :
var minimized_elements = $('.innovision-msg');
var minimize_character_count = 100;
minimized_elements.each(function(){
var t = $(this).text();
if(t.length < minimize_character_count ) return;
$(this).html(
t.slice(0,minimize_character_count)+
'<span>...</span>'+'Read more'+
'<span style="display:none;">'+ t.slice(minimize_character_count ,t.length)+ '<span>...</span>' +
'Read less</span>'
);
});
$('a.read_more', minimized_elements).click(function(event){
event.preventDefault();
$(this).hide().prev().hide();
$(this).next().show();
});
$('a.read_less', minimized_elements).click(function(event){
event.preventDefault();
$(this).parent().hide().prev().show().prev().show();
});
Here in this script i can not understand the meaning and use of code:
$(this).parent().hide().prev().show().prev().show();
Can any one explains what this line of code means ?
Moreover when it set var minimize_character_count = 250; Script does not works.
$(this).parent().hide().prev().show().prev().show();
This line is hiding the parent element of this element which is clicked (for minimization). After hiding the parent element, it goes to the previous sibling (of the parent element) and make it visible. It again goes to the previous sibling (of the previous sibling of the parent element) and make it visible.
Basically, jquery methods (after doing their job, whether to hide, show or traverse) returns the reference to the current element which allows you to chain the methods in this manner.
This is basically chaining which works on an returned object
$(this).parent().hide().prev().show().prev().show();
$(this) referring to either 'a.read_less', minimized_elements
On click on this element , it will find the parent dom and will hide it.
.prev() is use to select the previous element. So it will select the previous element and will show it. Again using prev() will select previous to previous element and will also show it
Method chaining is one of the nice features of jQuery. Most of the methods will return objects on which it is called, and hence you can call other methods in same chain.
Yet another one of the really cool aspects of jQuery is the fact that
most of the methods returns a jQuery object that you can then use to
call another method. This allows you to do command chaining, where you
can perform multiple methods on the same set of elements, which is
really neat because it saves you and the browser from having to find
the same elements more than once - source

Jquery binding to keyup

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/

Get the id of a the item that is clicked

I have this html code:
<b class = "edit" id = "foo1">FOO</b>
<b class = "edit" id = "foo2">FOO2</b>
<b class = "edit" id = "foo3">FOO3</b>
And I have this code in jQuery:
$('b.edit').click(function(){
//GET THE ID OF THE b.edit: e.g foo1, foo2, foo3
$('.editP').focus();
});
How can I get the id value of the b.edit, as there are multiple instances of b.edit, and I want to get the specific id of the one clicked? How can I do this?
Thanks, Sorry, I am pretty new to javascript.
I'm assuming from your sample code that you're using jQuery? If so you can get the id as follows:
$('b.edit').click(function(){
this.id;
});
EDIT:
The direct reference to the attribute is indeed more efficient if all that is required is simply the id.
Also can be obtained from the jQuery object:
$('b.edit').click(function(){
$(this).attr('id');
});
Sample fiddle: http://jsfiddle.net/5bQQT/
Try with this:
$('b.edit').click(function(e){ //When you use an event is better
//send the event variable to the
//binding function.
var id = e.target.id; //get the id of the clicked element.
/*do your stuff*/
$('.editP').focus();
});
try this. You can use keyword "this" to retrieve the attr ID...
$('b.edit').click(function(){
alert($(this).attr("id"));
});
$('.edit').click(function(){
var theId = $(this).attr('id');
}
This will get you the ID of anything clicked with a class of .edit
$('.edit').live('click', function() {
alert( this.id );
});
Sample
http://jsfiddle.net/ck2Xk/
When passing a click handler in JQuery, you actually have a reference to something called an event object. This event object has a property called target, which is a reference to the element that was clicked.
$('b.edit').click(function(eventObject){
eventObject.target // this is the element that was clicked.
});
Since you have a reference to the target element, you can do whatever you like. In this case, you could just access eventObject.target.id.
Since nobody has shown the simplest method yet that doesn't even need jQuery to get the id:
$('.edit').click(function() {
alert(this.id);
});
I never understand why people use jQuery for getting simple attributes which involves two jQuery function calls (and a bunch of overhead to create a jQuery object) instead of one direct attribute reference.
something like this:
var id = $(this).attr('id');
More clearly:
$('b.edit').live('click', function(){
var id = $(this).attr('id');
// in this scope this.id works too
// var id = this.id;
});
This is called event delegation in Javascript. More info can be found in Zakas blog http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/
The idea in few words is you attache the event to a parent node and then waiting for some event on the child node. In the example below I attach the onclick event to the document itself. Then inside the event handler you will write a switch statement to check the clicked element id, then do what you want to do for that element
document.onclick = function(event){
//IE doesn't pass in the event object
event = event || window.event;
//IE uses srcElement as the target
var target = event.target || event.srcElement;
switch(target.id){
case "foo1":
foo1();
break;
case "foo2":
foo2();
break;
case "foo3":
foo3();
break;
//others?
}
};
//some dummy handlers
var foo1 = function(){
alert("You clicked foo1");
};
var foo2 = function(){
alert("You clicked foo2");
};
var foo3 = function(){
alert("You clicked foo3");
};
For how to implement event delegation in jQuery you can check http://api.jquery.com/on/#direct-and-delegated-events
Even though this is not a real answer to your question. I will try to explain why what your asking is not the way to go. Since you are new especially, since learing bad practices could be hard to unlearn. Allways try to search for an ID before finding an element by its Class. Also try to avoid giving every element the same class (and in this case ID to), just give it an encapsulating parent.
Furthermore, the id of an element is really specific and should preferably used to find / select / bind events to. An id should usually be unique for this to work, so in your case a couple of things could be optimized, lets say like:
<div id="foo">
<b id="1">Foo</b>
<b id="2">Other foo</b>
<b id="3">Some foo</b>
</div>
Now if you want to know which was clicked there are multiple ways to accomplish it, but a nice one is simply binding a parent its children (i.e <div id="foo"> .. </div>). This way you can alter the structure of your pretty fast, without changing all the classes and id's.
With jQuery you can get the attribute id using the .attr() function. However I told you the id was pretty specific and thus has its own rights in javascript world. An id can also be directly targeted ('DOMelement.id', but this would be too much to explain for now)
In two ways the <b> can be targetted:
Example a)
var b_elements = $("#foo").children();
Example b)
var b_elements = $("#foo").find('b');
We can add jQuery (or javascript events) to these found elements. The nice thing about jQuery is that it simplifies alot of work. So in your case if you would like to know an id of a certain clicked <b> field you could use a very verbose way:
b_elements.click(function()
{
var clicked_element = $(this);
alert(clicked_element.attr('id'));
});
Verbose because you can do it much much shorter, but who cares about a few bytes when your learning and this makes remembering functions and events alot easier. Say you wanted to get the class edit by finding the where you knew the id that was clicked:
b_elements.click(function()
{
var clicked_element = $(this);
alert(clicked_element.attr('class'));
});
And to conclude, the id of an element is ment to be unique because it makes searching through big documents alot faster. Also don't forget to look and learn plain javascript, as it helps coding in jQuery alot too, but not the other way around. Your given question would require a for loop in plain javascript since it cannot do a lookup by class nor id nor have they have a common parent.
Good luck with learning :)

I want to check if `id` has no content

I want check between id that get in var span, if empty was between it put css for input but it not work. how can fix it?
var span = '#'+$('.valid').closest('.auto_box').find('span').attr('id');
if ($(span+':empty').length != 0) {
//alert('ok')
(this).closest('.auto_box').find('input').css('background-color','#000');
}
See here my full code: http://jsfiddle.net/Pjqv2/2/
You are using (this) instead of $('.valid') or whatever you meant with it. Also, you are doing this the wrong way; .find('span') returns the jQuery objects set for that span.
You don't need to get it's ID and then check on that ID again. More importantly, your code seems the need to run on multiple instances of .auto_box. For that, you need to iterate on the set found by (".valid").closest(".auto_box"), which you can do with the jQuery .each() (.each() in jQuery docs) like this:
var autoBoxes = $(".valid").closest(".auto_box");
autoBoxes.each(function(){
if ($(this).find("span").is(":empty")) {
$(this).find("input").css("background-color", "#000");
}
});
Your updated jsfiddle with this script: http://jsfiddle.net/dvir_azulay/Pjqv2/4/
Change (this) to $(span). I updated your fiddle to reflect this change.

jQuery: if hovering over an element injects something into the DOM, can I still reference it?

If hovering over an element injects something into the DOM, can I still reference it?
Or do I have to use the live plugin?
I'm using jQuery 1.3.2
i.e. can I do
$("#someItem").attr("src", "htt...")
on it?
I am trying to do it, but I think its not working b/c its a newly added item to the DOM.
Yes, an element that has been added to the DOM can be selected and referenced.
Or, if you already had a reference to it that you used when you added it to the DOM, you can continue to use that reference after it has been added as well.
Using this example, you can see that you can both use a current reference to a newly created element, as well as make a new reference to it.
http://jsfiddle.net/Czuvx/
HTML:
<div id='button'>hover me</div>
jQuery:
$('#button').hover(function() {
$('#newElement').remove();
var $myNewElement = $('<div id="newElement">new Element</div>');
$('body').append($myNewElement);
$myNewElement.css({color:'red'});
},
function() {
// This function has completely different namespace
// from the one that created and inserted #newElement
// and I can get a reference to it just like any other element
var $newReferenceToElement = $('#newElement');
$newReferenceToElement.css({color:'blue'});
});
Showing a bit more of your code would be helpful, but I think I get the general idea.
If you're just looking to add events or something to that item, you can do it before you append the item.
(function($){
$(function(){
$("#link").hover(
function(){
var $div = $("<div class='inserted_div'></div>").bind("click",function(){ ... });
$("body").append($div);
}),
function(){
});
});
})(jQuery);
So just bind the events or attributes at the time of creation, before you append it.

Categories