How do I read this function? - javascript

function showTweet(username) {
$( "<ul/>", {
"class": "my-user-list",
html: usertweets[username].join( "<li/>" )
}).appendTo( $("#tweets") );
}
So I see that the selector is targeting an unordered list, but what comes after the comma and why is it in curly brackets?
I understand the .append portion. I do not understand what "class": "my-user-list" and html: usertweets[username].join( "<li/>") do. Note that usertweets is an array.
Any insight would be greatly appreciated!

The selector is not targeting a ul - it is creating one. The second parameter is an object that contains the properties to set on the new ul element. It is then added to the DOM by appending it to the #tweets element.
To show the difference:
// to create a ul element in memory
$('<ul></ul>'); // or...
$('<ul />');
// select all ul elements currently in the DOM
$('ul');

The curly brackets are for PlainObject which is plain JavaScript object. From that I would read
Please create me a <ul> with class my-user-list with html of lists of usertweets joined with <li/> and append that to <ul> and append the ul to an element with id tweets
Here's the example
http://jsfiddle.net/xz6a0yqy/

It's not targeting ul, it first creates a <ul> element, and set the <ul>'s class to "my-user-list", then set its the html inside it to usertweets[username].join("<li/>"), which should creates some <li>, and finally append the newly created <ul> and the <li>s inside it to $("#tweets").
You can see more from jQuery#.jQuery().

Related

Using jQuery .remove() to take <li> elements out of an <ol> but the DOM still thinks that the <li> elements are there?

I have a function that removes li elements from an ol when you click on an icon. When the ol is totally emptied, I would like to replace the li with a bit off filler material so that the user can still drag and drop new li elements into the list. (It's kind of a shopping cart setup.)
The problem that I'm running into is that when I use jQuery .remove() the li is removed from the DOM BUT jQuery doesn't it as being gone. So, for example, calling .has(".li") returns true even when all the li's are gone, and calling childNodes.length returns the total number of li that have ever existed in the ol. Code follows:
function onClick(element)
var parent = $(element).parent().attr('id');
$(element).remove();
var container = document.getElementById(parent);
console.log(container.childNodes.length); //always logs the total number that have ever existed
if(container.childNodes.length < 1){
parent.append("<li class='placeholder'>Drag and Drop Components Here</li>");
I'm pretty sure that this isn't the problem because I've been careful to grab the parent container only after the element was removed from the DOM.
Any ideas?
EDIT: The requested ul and li structure:
<h4>Components</h4>
<ol id="components" class="droppable">
<li class="placeholder">Drag and Drop Components Here</li>
</ol>
Users drag and drop the following code into the list, which is retrieved via $.get from some php scripts.
<li id="$id"><table style="color:white"><tr><td>$this->longname</td>
<td>Delete image</div></td></tr></table></li>
The click handler is the code above.
Assuming you have misplaced the function name onClick instead of destrComp, there are multiple problems.
To the click handler you are passing the clicked anchor element not the li element as you as assuming, so when you say $(element).parent() or $(element).remove() it is not dealing with the elements you think it is dealing.
Try
function destrComp(element) {
var $parent = $(element).closest('ul');
$(element).closest('li').remove();
if ($parent.children().length < 1) {
$parent.append("<li class='placeholder'>Drag and Drop Components Here</li>");
}
}
According to your code you seem to be removing the "a" tag, but not the parent.
$(element).remove(); //This removes the a tag
$(element).parents('li').remove(); //This removes the parent li element

Hide all LI`s except the selected

I want to hide all other LI's in a certain UL except the LI that I select.
<ul>
<li><div></div></li>
<li><div></div></li>
</ul>
<ul>
<li><div></div></li> -- HIDE
<li><div></div></li> -- SELECT
<li><div></div></li> -- HIDE
</ul>
<ul>
<li><div></div></li>
<li><div></div></li>
</ul>
How can I solve this the best way?
I've tried using indexes, but having some problems getting it to work, and selecting the correct UL. As you may see, I've got no class on the UL's or LI's so I think the only option is LI's.
What I really do, is selecting a div inside the LI so, I get the selected LI's index by:
var li_index = $(this).parent().index();
You traverse the DOM up from the div that was clicked then hide the other elements with .not($(this).parent()).toggle() -> Not the li that surrounds this div
$('div').click(function () {
$(this).closest('ul').find('li').not($(this).parent()).toggle();
});
.toggle() can be replaced with .hide() if you don't want the User to be able to reverse their decision.
JS Fiddle: http://jsfiddle.net/tDmy3/2/
Tried something like this?
$(this).closest('ul').find('li').not(this).hide();
Or
$('li', $(this).closest('ul')).not(this).hide();
Get a jQuery element set with all relevant <li> elements, then remove the selected element. For example:
$('ul#mylist li').not(selector).hide();
From the JQuery documentation:
Given a jQuery object that represents a set of DOM elements, the .not() method constructs a new jQuery object from a subset of the matching elements. The supplied selector is tested against each element; the elements that don't match the selector will be included in the result.
Instead of a selector, you can also give the element object itself if you have a reference to it.
This should work:
$( 'ul li' ).click( function( e ) {
// by default, hide all li's
$( 'ul li' ).hide();
// show only the selected li
$( this ).show();
});
http://jsfiddle.net/BqKun/
Hope this helps.

Explanation of two arguments for jQuery .each() method

In the following jQuery, the .each() method takes two arguments: 'ul li a' and menu. What do these two arguments mean?
var menu = $('.menu');
$('ul li a', menu).each(function() {
$(this).append('<span />');
});
HTML:
<div class="menu">
<ul>
<li>Edit Profile</li>
<li>Account Settings</li>
<li>Appear Offline</li>
<li>Logout</li>
</ul>
</div>
The second parameter to the jQuery function is the context. This tells jQuery to only search for elements that are in that context
So for your example:
$('ul li a', menu).each(function() {
$(this).append('<span />');
});
This will only search for anchors within li's within a ul, that are also located inside of menu.
This can be a very useful optimization since it can significantly cut down the amount of space jQuery has to search.
EDIT
To possibly make this a bit clearer (as jfriend00 points out), your particular example, $('ul li a', menu), is equivalent to $('.menu ul li a')
The context parameter is explained here in the docs
Hello Brother Assalamu Alaikkum,
The explanation is as follows,
The first parameter is 'ul li a' It means that it searches for the anchor tag within the list item tag which in turn present inside the unordered list tag. This first argument is the sub context.
The second parameter menu which is the main context. That is jquery searches for the elements with the class name as "menu".
Finally jquery searches the sub context within the main context. So the jquery searches for the main context "menu" first and then it searches the sub context within the main context. The keyword "each" denotes all the sub elements to be searched within the main element.
hope this helps you.

jquery $.each is non-blocking?

$("<ol>").appendTo(some_div);
$.each(map, function(i,example){
$("<li>" + example + "</li>").appendTo(some_div)
});
$("</ol>").appendTo(some_div);
expected:
<ol><li>example1</li><li>example2</li></ol>
actual:
<ol></ol><li>example1</li><li>example2</li>
Any idea why this happens?
You are doing DOM operations and not string operations. And $("<ol>") does already create an OL element and not just a string containing <ol>.
You need to append the LI elements to the newly created OL element:
var ol = $("<ol>").appendTo(some_div);
$.each(map, function(i,example){
$("<li>" + example + "</li>").appendTo(ol);
});
You should append your <li> entries to your <ol>. Otherwise you can't know how browser is going to handle your code. Additionally, you should append <ol></ol> instead of separate <ol> and </ol>. jQuery's .append and .appendTo are not string operations, those are modifying page DOM tree.
$("<ol></ol>").appendTo(some_div);
olelement = $(some_div).find("<ol>")
$.each(map, function(i,example){
$("<li>" + example + "</li>").appendTo(olelement);
});
This line
$("<ol>").appendTo(some_div);
isn't simply adding an open tag as you think it is. jQuery is building an ordered list element and adding it to some_div. Likewise, your $.each is appending list item elements to some_div, so they're ending up as siblings of the list. You need to append the list items to the list element.
I believe $("<ol>").appendTo creates the full <ol></ol> tag. Either append the li items to the OL you've created, or create a long string and then do one append. Append is an expensive operation, if you're going to have 10s or more list items you should do the latter.

Jquery get attribute of few ul to create another attribute

I have the following HTML:
<ul actualpage=0>
<li/>
<li/>
....
</ul>
<ul actualpage=0>
<li/>
<li/>
....
</ul>
Im trying to get the value of actualpage of each ul and create a new attribute. Its easy but not in one jquery sentence... Its possible? Until now i have the following line (between ## simbols the missing part that i need.
/*
select all uls with attribute actualpage and create a new attribute on each with the current actualpage value
*/
$('ul[actualpage]').attr('newactualpage',##Current value of actualpage attr of UL##);
Well maybe this isn't as nice as you'd like, but
$('ul[actualpage]').each(function(_, ul) { $(ul).attr('newactualpage', $(ul).attr('actualpage')); });
One might think that
$('ul[actualpage]').attr('newactualpage',$(this).attr('actualpage'))
is the answer.
However, this is evaluated before the call to attr, so it's going to equal whatever this equals in the calling context.
You could use:
$('ul[actualpage]').attr('newactualpage',function(){
return $(this).attr('actualpage');
});
or this:
$('ul[actualpage]').each(function()
{
$(this).attr('newactualpage',$(this).attr('actualpage'));
};
In both, this refers to the element that your selector matched.
You can use function as second argument for .attr(), eliminating the need of .each():
$('ul[actualpage]').attr('newactualpage', function() { return $(this).attr('actualpage') });

Categories