how to pass $(this) object from one function to another? - javascript

I think its very basic Object oriented javaScript related question. But I'm still very confused about it. I would like to pass $(this) object from 1 function to another. So that I can get the href attr of the link clicked.
Here my sample code
HTML
TEST
TEST
JS
$(document).on("click", ".test", function () {
var $this = $(this);
var rel = $this.attr("rel");
if (rel == "image") {
e.preventDefault();
openImage($this);
} else if (rel == "video") {
openVideo($this);
}
});
function openImage($this) {
var href = $this.attr("href");
alert(href);
}

Check out the examples in the jQuery documentation page. You'll find that the on method applies to the selected elements, in the case of your code, it's the document object. To get the attribute that you want, jQuery is not necessary to wrap the element. Here's a JSBin example. One more thing, try reemplace == with === to get type checking also. Hope it helps

My question had 1 small syntax error please (check 1st comment on question)
Following is the code I ended up using.
$(document).on("click", ".test", function (e) {
var anchor = $(this);
var rel = anchor.attr("rel");
if (rel == "image") {
e.preventDefault();
openImage(anchor);
} else if (rel == "video") {
openVideo(anchor);
}
});
function openImage(anchor) {
var href = anchor.attr("href");
alert(href);
}
Thank you!

Related

My jQuery wrap method doesn't work

I'm trying to use jQuery wrap but it doesn't work.
(function ($) {
$.fn.taggify = function () {
create(this);
return this;
};
function create($theElement) {
var $input = $('<input></input>')
.attr('type', 'text')
.attr('autocomplete', 'off')
.css('border', 'none')
.css('outline', 'none')
.wrap('<li></li>');
$input.on('keyup', function (e) {
if (e.keyCode === 13) {
var tagText = $input.val();
var $span = $('<span class="tag-label"></span>');
$span.text(tagText).wrap('<li class="tag-choice"></li>');
$theElement.prepend($span);
}
});
$theElement.append($input);
}
})(jQuery);
The result still doesn't have <li> tag wrapped around the input
Here's the jsfiddle
http://jsfiddle.net/noppanit/sryg5fk7/1/
just move your wrap code after append input element .
DEMO
$theElement.append($input);
$input.wrap('<li />');
$theElement.prepend($span);
$span.text(tagText).wrap('<li class="tag-choice"></li>');
You can wrap it using:
(function ($) {
$.fn.taggify = function () {
var $input = $('<input />')
.addClass('specialInput')
.attr('type', 'text')
.attr('autocomplete', 'off')
.css('border', 'none')
.css('outline', 'none')
.wrap('<li />');
$(this).append($input);
return this;
};
})(jQuery);
$('body').on('keyup','.specialInput',function (e) {
if (e.keyCode === 13) {
$('<li class="tag-choice"><span class="tag-label">'+$(this).val()+'</span></li>').prependTo($(this).parent());
}
});
Looking at the console, the error surrounds trying to use the .on() command on a non DOM element
Not quite sure why, but look like you wanna wrap the element that not exist yet. Unless wrap the element after prepend should work like so :
$theElement.append($input);
$input.wrap('<li></li>');
$theElement.prepend($span);
$span.text(tagText).wrap('<li class="tag-choice"></li>');
See DEMO
p/s : This only an alternative solution for your problem, not sure why the original code did't worked either.
How about using like this?
var $input = $('<li><input></input></li>')//wrap li here
.find('input')//find input and use as you want
.attr('type', 'text')
.attr('autocomplete', 'off')
.css('border', 'none')
.css('outline', 'none');
I also noticed that you're using on method but this wouldn't work as the element is dynamically created. So replace this line:
$input.on('keyup', function (e) {
With this:
$(document).on('keyup', $input, function (e) {
//you may use closest parent element instead of document
your updated fiddle

JavaScript Function Only Working Sometimes With Same Input

I've got the following bit of code (using JQuery) that I've written for a project. The idea is to have a function that you can attach to an element within an "item" div and it will return the id of that div. In this case, the div id would be item-[some item primary key value]. This function works probably 9/10 times, but every once in a while it will get to the else else case and return false. I've verified through the console that the input for selector is the exact same JQuery $() item in both the success and fail cases.
I'm relatively new to JavaScript, so there may be something obvious I'm missing, but this is some really unusual behavior.
var recursionCounter = 0;
function getElementID(selector, recursionDepth, searchString){
console.log(selector);
var elementID = selector.attr("id");
if(elementID === undefined){
elementID = "";
}
if(elementID.indexOf(searchString) !== -1){
elementID = elementID.split("-")[1];
return elementID;
} else {
if(recursionCounter < recursionDepth){
recursionCounter++;
return getElementID(selector.parent(), recursionDepth, searchString);
} else {
recursionCounter = 0;
alert("The element clicked does not have an associated key.");
return false;
}
}
}
Here is an example of code that calls this function, for some context.
$(document).on("click", ".edit-pencil-item", function(event) {
//Use helper function to get the id of the surrounding div then pass it to the function
var itemID = getElementID($(this), 10, "item-");
jsEditItem(itemID);
return false;
});
Thanks in advance for any help!
If you want to get the encapsulating element of your clicked element, and you know it should have an id starting with "item-" you should be able to do something along the lines of
$(this).closest('[id^="item-"]').attr('id')
Which says find this elements closest parent that has an id starting with "item-" and tell me its id.

How can I find the element clicked on inside a jQuery handler?

I'm trying to do a specific action on the clicked element if an argument is passed in the on click method in jQuery. When I try to access this it's referencing the entire window instead of the clicked on element. How would I access the clicked on element in the handler?
Here's the code I'm using:
var myfunction = function(action) {
var content;
var $this = $(this);
if(action === "one") {
$(".output").text("clicked on one");
$this.addClass("one");
}
if(action === "two") {
$(".output").text("clicked on two");
$this.addClass("two");
}
};
$("#button").on("click", function(event) {
myfunction("one");
});
$("#button2").on("click", function(event) {
myfunction("two");
});
I set up an example on jsbin here. Any help would be appreciated.
There are several ways to do this.
JQUERY WAY:
Within your jquery click event handlers you have the event object. It has a property called target which is what you're looking for.
Change this: $this.addClass("one");
To this: $(event.target).addClass("one");
You can also do this: event.target.className = "one"
And do for "two" as well obviously...
VANILLA WAY:
You can just pass in an extra argument representing your clicked element.
var myfunction = function(action, element) {
var content;
if(action === "one") {
$(".output").text("clicked on one");
$(element).addClass("one");
// or event.target.className = "one"
}
if(action === "two") {
$(".output").text("clicked on two");
$(element).addClass("two");
// or event.target.className = "two"
}
};
$("#button").on("click", function(event) {
myfunction("one", this);
});
$("#button2").on("click", function(event) {
myfunction("two", this);
});
You can use Function.prototype.call:
$("#button2").on("click", function(event) {
myfunction.call(this, "two");
});
or store the action as an attribute on your element, bind your handler directly and query the attribute.
var myfunction = function() {
var content;
var $this = $(this);
var action = $this.attr('data-action');
if (action === "one") {
$(".output").text("clicked on one");
$this.addClass("one");
} else if (action === "two") {
$(".output").text("clicked on two");
$this.addClass("two");
}
};
$("#button2").on("click", myfunction);
this refers to the object the function belongs to, in your case the function belongs to the window object or global object, the 'this' keyword behaves differently depending on how you use your function, if you use it as a constructor function for example (with the new keyword) 'this' will be bound to new object being constructed, and when the function is used as an event handler this will be set to the event the element the event fired from.
see :https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this for more information.
you need to change your code and do something like this:
$(".button").on("click",function(){
var $this = $(this) //refers to the event it was fired from (button object)
$(".output").text("You clicked on "+$this.text());
});
i used classes instead of ids to target any button that's clicked
an example in jsfiddle: http://jsfiddle.net/fvacbd9u/

How to match children innerText with user input using jQuery

I have the following structure:
<div id="campaignTags">
<div class="tags">Tag 1</div>
<div class="tags">Tag 2</div>
<div class="tags">Tag 3</div>
</div>
And I'm trying to match user input against the innerText of each children of #campaignTags
This is my latest attempt to match the nodes with user input jQuery code:
var value = "Tag 1";
$('#campaignTags').children().each(function(){
var $this = $(this);
if(value == $(this).context.innerText){
return;
}
The variable value is for demonstration purposes only.
A little bit more of context:
Each div.tags is added dynamically to div#campaignTags but I want to avoid duplicate values. In other words, if a user attempts to insert "Tag 1" once again, the function will exit.
Any help pointing to the right direction will be greatly appreciated!
EDIT
Here's a fiddle that I just created:
http://jsfiddle.net/TBzKf/2/
The lines related to this question are 153 - 155
I tried all the solutions, but the tag is still inserted, I guess it is because the return statement is just returning the latest function and the wrapper function.
Is there any way to work around this?
How about this:
var $taggedChild = $('#campaignTags').children().filter(function() {
return $(this).text() === value;
});
Here's a little demo, illustrating this approach in action:
But perhaps I'd use here an alternative approach, storing the tags within JS itself, and updating this hash when necessary. Something like this:
var $container = $('#campaignTags'),
$template = $('<div class="tags">'),
tagsUsed = {};
$.each($container.children(), function(_, el) {
tagsUsed[el.innerText || el.textContent] = true;
});
$('#tag').keyup(function(e) {
if (e.which === 13) {
var tag = $.trim(this.value);
if (! tagsUsed[tag]) {
$template.clone().text(tag).appendTo($container);
tagsUsed[tag] = true;
}
}
});
I used $.trim here for preprocessing the value, to prevent adding such tags as 'Tag 3 ', ' Tag 3' etc. With direct comparison ( === ) they would pass.
Demo.
I'd suggest:
$('#addTag').keyup(function (e) {
if (e.which === 13) {
var v = this.value,
exists = $('#campaignTags').children().filter(function () {
return $(this).text() === v;
}).length;
if (!exists) {
$('<div />', {
'class': 'tags',
'text': v
}).appendTo('#campaignTags');
}
}
});
JS Fiddle demo.
This is based on a number of assumptions, obviously:
You want to add unique new tags,
You want the user to enter the new tag in an input, and add on pressing enter
References:
appendTo().
filter().
keyup().
var value = "Tag 1";
$('#campaignTags').find('div.tags').each(function(){
if(value == $(this).text()){
alert('Please type something else');
}
});
you can user either .innerHTML or .text()
if(value === this.innerHTML){ // Pure JS
return;
}
OR
if(value === $this.text()){ // jQuery
return;
}
Not sure if it was a typo, but you were missing a close } and ). Use the jquery .text() method instead of innerText perhaps?
var value = "Tag 1";
$('#campaignTags').find(".tags").each(function(){
var content = $(this).text();
if(value === content){
return;
}
})
Here you go try this: Demo http://jsfiddle.net/3haLP/
Since most of the post above comes out with something here is another take on the solution :)
Also from my old answer: jquery - get text for element without children text
Hope it fits the need ':)' and add that justext function in your main customised Jquery lib
Code
jQuery.fn.justtext = function () {
return $(this).clone()
.children()
.remove()
.end()
.text();
};
$(document).ready(function () {
var value = "Tag 1";
$('#campaignTags').children().each(function () {
var $this = $(this);
if (value == $(this).justtext()) {
alert('Yep yo, return');)
return;
}
});
//
});

Why would a jQuery function be only selectively run?

I am trying to debug this (incomplete) script, but it is behaving inconsistently. The main problem is when I click off of an item, sometimes the $(editObj).removeAttr('style'); runs and sometimes not. Through the Chrome inspector I can see that the editObj variable in each case is properly defined, but it isn't always getting its inline style attribute removed. Sometimes, and sometimes not. Cannot determine the reason.
I'm a bit out of my element with this code. Maybe something about it is obvious; Regardless I'd appreciate some ideas on why this sort of unpredictable might be occuring!
var editObj = null;
var inputType = 'text';
var input = '#textEdit';
var formId = '#form_undefined'
$(function() {
$("#textEdit").click(function(event) {
event.stopPropagation();
});
$('body').click(function(event) {
if (editObj){
//textedit contents to editobj and
if (inputType == 'text'){
$(editObj).text($("#textEdit").val());
}
$("#textEdit").removeAttr('style').hide();
$(editObj).removeAttr('style');
var previewId = $(editObj).attr('id');
var formId = previewId.replace('bzm', 'form');
$("#" + formId).val($("#textEdit").val());
//ajax modify database
editObj = null;
}
});
$(".editable").not("video, img, textarea")
.click(function(event) {
event.stopPropagation();
loadEditor($(this));
});
});
function loadEditor(element){
$("#textEdit")
.copyCSS(element)
.offset($(element).offset())
.css("display", "block")
.val($(element).text())
.select();
$(element).css("color", "transparent");
editObj = element;
}
I've had trouble in the past with .removeAttr('style'); not actually removing all the inline styles.
Use
$(editObj).attr('style', '');
instead of
$(editObj).removeAttr('style');
I dint see any code that initializes e editobj variable.. May be Im missing Anthony.. Anyways what are the chances of the edit obj being null.. Just put a log statement in the click function to always log ur editobj and see if it is null smtimes

Categories