Dynamic elements not created properly in Jquery Plugin - javascript

I wrote a masking jquery that is suppose to add dynamic elements the an existing input element.
var link = $('<a title="show" role="link" href="#" class="masker-value">show</a>');
wrapper: function() {
container = $(container)
.attr('ispartial', this.options.partial)
.attr('readyonly', this.options.readyOnly);
$(this.element).wrap(container);
if (!this.options.hideToggle)
$(this.element).after(link);
}
If I have a single input on a page, the code above works fine, but if I have multiple input, the link is only added to the last input.
Demo

Add the following line to the wrapper function:
link = $('<a title="show" role="link" href="#" class="masker-value">show</a>');
You defined link globally outside the wrapper function so its always refering to the same object, which gets moved in the DOM.
Example: https://jsfiddle.net/nxvdm5hr/5/
Further explanation:
When you use $('<a/>'), jQuery creates an input DOM element.
When you .after() that element, it detaches from the previous position.
You could also modify the var link to just HTML code, which will also fix your problem.

Related

Accessing properties of a tag within a tag

I have an a tag as follows:
<a href="data1.html" class="list-group-item" data-toggle="collapse">
<i class="glyphicon glyphicon-folder-close"></i>Root Folder
</a>
I have a function that gets called when you click on a tag. It is as follows -
$(document).ready(function() {
$("a").hover(function(event) {
console.log(event.target.href);
});
});
I can access the properties of a tag. Example: If i want to access the href of the a onclick, I can get it by event.target.href.
I want to access the properties of the i tag that is inside the a tag (for instance, class of i tag is "glyphicon glyphicon-folder-close").
How do I achieve that?
Also, what changes do I have to make to the function, such that it is called only if a tags of class = "list-group-item" are clicked?
Thanks in advance.
I want to access the properties of the i tag that is inside the a tag
Inside any jQuery event handler, this refers to the element on which the event was triggered: therefore you can use any selector relative to that element. $(this).children('i') for example will find the contained i given your HTML; if the element might be nested more deeply you'd want .find() instead of .children().
what changes do I have to make to the function, such that it is called only if a tags of class = "list-group-item"
Change the selector you're using to attach the handler - $("a.list-group-item") instead of $("a") to limit it to items having that class.
Note also that if you want this to work on click as you describe, rather than on hover as in your sample code, you'll need to return false from the event handler (so that the regular link navigation doesn't occur).
$(document).ready(function(e) {
$("a.list-group-item").click(function() {
var myChild = $(this).children('i')
console.log(myChild.attr("class")); // for example
return false; // prevent regular navigation from occurring on click
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="https://example.com" class="list-group-item">
<i class="glyphicon glyphicon-folder-close"></i> Will fire handler on click
</a>
<br>
<a href="https://example.com">
<i class="glyphicon glyphicon-folder-close"></i> Will navigate normally
</a>
Since you are using jQuery, this will be very easy!
$(document).ready(function() {
$("a.list-group-item").click(function(event) {
$(this).find('i').attr('class');
});
});
To get only certain anchor tags you can use a selector, read more about them here. Then you can use the this object to find children. Use the find method in jQuery. Finally use the attr to retrieve the class.
You can rewrite your function like this:
$(document).ready(function() {
//Only use list-group-item
$("a.list-group-item").hover(function(event) {
var $attrNode = $(this).find("i");
//Now that you have the list group item it is easy to get the attribute
var attributeValue = $attrNode.attr("your-attribute");
//You can also set the attribute
$attrNode.attr("your-attribute", "attribute value");
});
});

jQuery: Using .after() or .before() adds element to last item in selection only

I've been using jQuery for a while but this is a new one. A simplified example:
HTML
<div class='custom'></div>
<div class='custom'></div>
<div class='custom'></div>
jQuery:
var $customElems = $('.custom'),
$spanOuter = $('<span class="outer"/>'),
$spanInner = $('<span class="inner"/>');
$customElems.each( function() {
$(this).wrap($spanOuter).after($spanInner);
});
JSFiddle:
http://jsfiddle.net/a3ZK8/
I would have expected the 'inner' span to be added to all three elements in the selection but it gets always inserted into the last one only (no matter how many). I tried it with .before(), with and without the chaining, same result. What am I missing??
The problem is you are using a reference to a jQuery object.
Hence you keep moving the object reference around within each iteration.
If you have no events attached or no need for the span to be a jQuery object then just pass the parameter as a HTML string literal instead of an object reference
Cloning a jQuery object that doesn't need to be a jQuery object in the first place is just redundant processing and unnecessary overhead.
Change your jQuery object to a string similar to this:
spanInnerString = '<span class="inner"/>';
and your method like this:
$(this).wrap($spanOuter).after(spanInner);
The result is:
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
<span class="outer"><div class="custom"></div><span class="inner"></span></span>
DEMO - Passing parameter as HTML string
Off course, the same goes for the outer span. Don't create jQuery objects unless you have to.
If you must use a jQuery object because you want to attach events to the span or similar, than cloning is the way to go, though make sure you use clone(true, true) then to also clone the attached events.
You need to clone the element. Otherwise, after() will relocate the same element 3 times, which results in it being attached to only the last looped element.
$customElems.each(function () {
$(this).wrap($spanOuter).after($spanInner.clone());
});
Demo: Fiddle
You might ask, "Why would wrap() work?" That's because 'wrap()' internally clones the element.
You're moving the same span from place to place. If you acted on all three divs at once, jquery will instead clone the span.
http://jsfiddle.net/a3ZK8/1/
var $customElems = $('.custom'),
$spanOuter = $('<span class="outer"/>'),
$spanInner = $('<span class="inner"/>');
$customElems.wrap($spanOuter).after($spanInner);
From the documentation for .after:
Important: If there is more than one target element, cloned
copies of the inserted element will be created for each target except
for the last one.
which means the last element will always get the original, while all other selected elements will get a clone. That's why when you acted on one element at a time, it simply moved the same span around.

How correct create dynamiclly select with horizontal orientation?

I want danamically create select element in horizontal block. And have funny result. What is the correct way?
JSFiddle
You need to define where you want to append the new elements. For this, use .after(). And then you need to apply styles on the generated/modified controlgroup.
Demo here: http://jsfiddle.net/Palestinian/rKGtQ/
Code:
// append select menu after Button div
$("#Button_show_filters").after('<select id="sm"><option>Opt 1</option><option>Opt 2</option></select>');
// apply styles on select menu
$("#sm").selectmenu();
// add options to controlgroup
$( "#test" ).controlgroup( "option", "corners", true );
// create controlgroup
$( "#test" ).controlgroup().trigger('create');
controlgroup div ID is #test.
I think the main problem is that every time the "Push me!!" button is pressed, you are appending a select element with an id attribute of sm. Having multiple elements with the same id is invalid HTML and can cause problems with Javascript. See this question.
Namely, the $("#sm") line doesn't know which select you are trying to target.
Maybe you should try something like this:
$("button").click(function () {
$("#div_for_harakteristikinomenklatury_list").append('<select><option>Opt 1</option><option>Opt 2</option></select>');
$("#div_for_harakteristikinomenklatury_list select:last").selectmenu();
});
Also, you should get rid of the onclick attribute for the button. You don't need it. Passing the click handler to the click function should make the function run when the button is clicked.
Instead of using id you should use class and apply selctmenu only on last appended select element. Check this fiddle
$("button").click(function show_filters() {
//alert("Hello");
$("#div_for_harakteristikinomenklatury_list").append('<select class="sm"><option>Opt 1</option><option>Opt 2</option></select>');
$(".sm:last").selectmenu();
})
Updated Fiddle
change the $("#sm").selectmenu(); to $("select").selectmenu();
With above mentioned method no matter what is the id or class of the element you newly pushed, it'll get the styles applied.
Check the live fiddle here http://jsfiddle.net/mayooresan/VMj4U/6/

How to .append() an object

I'm making a simple game in javascript and I would like to .append() a box. To serve as a bullet. But I'm stuck. This is what I have
var existingdiv1 = document.getElementById('bullet');
and
$("#test").click(function() {
$("div").append([existingdiv1]);
});
It wont create additional "divs" when I press the button "#test".
You will have to select the existing div (I guess this is the bullet?). Then append it.
Here's and example:
Working Demo
Javascript:
$("#test").click(function(){
$("#appendToThis").append($('#bullet').html());
});
Html:
<input id="test" type="button" value="click" />
<div id="appendToThis"></div>
<div id="bullet"><div>BANG</div></div>
You will see the word "bang" be appended everytime you click. You can remove it by using the empty() method on the test div.
From the .append documentation:
If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved into the target (not cloned).
It seems like you want to clone [docs] the element first:
$("div").append($(existingdiv1).clone());
// or simpler
$("div").append($('#bullet').clone());
Note though that if you have multiple div elements on your page, $("div") will select all of them and the element you pass to .append will cloned automatically (as stated in the documentation).
You should append the element only to a single div.
I believe you wanted to add a new div to the existing div, so your code has been reversed the append order. and you need wrap the existing div by $('#bullet')
Try this
$('#bullet').append('<div></div>');
You can use .clone()
$("#test").click(function(){
$("#appendToThis").append($('#bullet').clone());
});

jquery hasClass, can it be given the beginning of class name, to get the full class name

I'm trying to do something similar to this question, but it's a bit different, so the solution there isn't working for me.
<span class="a-class another-class test-top-left"></span>
I have an element (this code shows a span but it could be div span or anything). This element has a class beginning with test- (test-top-left, test-top-right etc.) I've triggered a click event on classes starting with test- and saved the clicked object as var object = this;. Simple stuff so far.
What I'm trying to do now is get the full name of that class (test-top-left). I know it starts with test- but what's the full name. The thing is that there are other classes a-class another-class and test-top-left. Can hasClass be used to get the full name of the class? I'd prefer not to use find() or filter() just because there may be additional elements within that also have class="test-"
Edit:
The code I have now is, but it gives me ALL the classes. What I need is the single class beginning with test-.
var object = this;
$(object).attr('class');
So now I for loop through all the classes and test each one separately, which seems like a lot of unnecessary code. I'm hoping jQuery has a clever way to get the exact class that was clicked right away.
Description
You can use jQuerys Attribute Contains Selector, .attr() and .click() method.
Attribute Contains Selector - Selects elements that have the specified attribute with a value containing the a given substring.
.attr() - Get the value of an attribute for the first element in the set of matched elements.
.click() - Bind an event handler to the "click" JavaScript event, or trigger that event on an element.
Sample
html
<span class="anyclass test-hello">Hello World</span>​
jQuery
$("[class*='test']").click(function() {
var object = $(this);
alert(object.attr("class").match(/(test-.*?)(?:\s+|$)/)[1])
;});
Check out the updated jsFiddle
Update
If you dont want to use regex you can do this.
$("[class*='test']").click(function() {
var object = $(this);
alert("test-" + object.attr("class").split("test-")[1].split("-"))
;});
​
More Information
jQuery - Attribute Contains Selector
jQuery - .attr()
jQuery - .click()
jsFiddle Demonstration
This should work for you:
var object = this;
var className = object.className.match(/(test-.*?)(?:\s+|$)/)[1];
Class name is the name of the class you are looking for.
If you don't want to use split or regex, you can try having the class in a separate attribute
<span class="someclass test-something" _rel="test-something">test<span>
or
<span class="someclass" _rel="test-something">test<span>
with the script
$("[_rel*='test-']").click(....
And to retrieve the attribute, use $(this).attr("_rel")

Categories

Resources