jQuery: take existing HTML, modify one node, then reinject - javascript

I have a blob of HTML that I'm retrieving using simple jQuery selectors, something like the following:
<div id="stuff">
<ul>
<li>some</li>
<li class="ninja">stuff</li>
</ul>
</div>
I'm basically doing:
var myblock = $("#stuff").html();
now I want to inject an additional li element to the bottom of that li list with very similar attributes to the li above it, but i want to change the class ninja to class samurai.
What's the best way of going about that with jQuery?

Simply select the <ul> and append the <li> to it
$("#stuff ul").append('<li class="samurai">stuff</li>');
If you actually wanted to copy the last <li> element, change the class then add to the list, then you could do something like this
var ul = $("#stuff ul");
ul.append(ul.find('li:last').clone().removeClass().addClass("samurai"));
pass true into clone() if you also want to copy event handlers too.
The problem with taking a whole chunk of HTML, changing an element and then reinserting is that any event handlers set up on elements that will be replaced when you reinsert the HTML will be lost, so it's more elegant/ and less cumbersome/intrusive to simply manipulate the part of the DOM that you need to.

Related

Need help using the .not() selector with nested elements

I am trying to clone an li element but without the tags.
I am have tried many different ways but I can make it seem to work.
When I take a look at the html of the li element it still selects the span tags.
Below is the code I am using. Any help would be really appreciated. Thanks!
<ul class="todo_list_items" data-category_id="44">
<li class="tasks" data-task_id="30">
<!-- Don't want to select this span class -->
<span class="modify_tasks">
<a href='#' class='delete_task_name'>Delete</a>
<a href='#' class='edit_task_name'>Edit Task</a>
</span>
Test
</li>
</ul>
<script>
$(document).on("click", ".edit_task_name", function () {
var task_id = $(this).data("task_id");
var previous = $(".tasks[data-task_id=30]").not(".tasks[data-task_id=30] > span").clone();
console.log(previous.html());
});
</script>
Just clone it and then empty it:
var previous = $(".tasks[data-task_id=30]").clone().empty();
EDIT: If you only want to remove the span and not other content, then just remove the span from the clone:
var previous = $(".tasks[data-task_id=30]").clone();
previous.children("span").remove();
not() will check against elements in the set, in your case the set consists of only $(".tasks[data-task_id=30]"). not() is testing the span inside it to see if it matches its own parent, so not wont be adjusting your jQuery object for cloning there. An alternative way to achieve what you want might be code similar to this:
var $tasks = $(".tasks[data-task_id=30]"),
$modifyTasks = $tasks.children('span').detach(),
$cloneOfTasks = $tasks.clone();
$modifyTasks.prependTo($tasks);
$cloneOfTasks.appendTo($tasks.parent());
.detach() removes the span without losing events and data so you can put it back in when your done making your clone.
Alternatively this code might be easier to interpret and use:
var $tasks = $(".tasks[data-task_id=30]");
$('ul.todo_list_items').append($tasks.contents().not('span').clone().wrap('<li class="tasks" data-task_id="30">').closest('li'));
This uses .contents() to grab whats inside the task so you can run not against it. The closest('li') part is needed to ensure the li wrapped around the new element is returned for appending to the ul.

How to get div before li using jquery?

My HTML looks like this:
<ul>
<div class="topmsg"></div>
<li>
<div id="message"></div>
....</li>
....</ul>
and this list is repeated several times
I could get the div inside the li like this:
li.children('div#message').hide();
Any ideas on how to get the topmsg using jquery or JS?
Ignoring the problems with your HTML.
As you have an ID on the div you want to select, you should just be able to use the # id selector.
$('#topmsg')...
If you have multiple things with the id of topmsg then you really need to reform your HTML so that you don't.
Id is short for "identifier" and should be unique in a document - it is used to uniquely identify the node.
EDIT after topmsg changed from id to class:
Having changed topmsg to be a class, then once you have the LI that contains the message you're interested in you can traverse it with a parent and then a find.
E.g.
// Get the LI that contains the message DIV
var messageLi = $('#message').parent();
// Hide it
messageLi.hide();
// Get the 'topmsg' relating to that LI
messageLi.parent().find('.topmsg').hide();
Use this code, it will get the div relative from the li.
var topmsg = $(li).parent();

JQUery find and match parent based on a dynamic child class

Ok it's a little hard to explain in a single title but basically I have a dynamic class added to a child element based on it's parent's dynamic class. Added so:
$('ul').each(function(key){
if ($(this).hasClass('sortable')){
$(this).addClass('parent' + key);
$(this).children().addClass('parent' + key);
};
});
The structure is pretty simple after this:
<ul class="parent0">
<li class="parent0">
<ul class="parent1">
<li class="parent1"></li>
</ul>
</li>
</ul>
Now the UI has the user move these li outside of the parent and placed elsewhere. Later on, I want to check the element and then match it to it's corresponding (original) parent. It can't be $(this) parent because it will be moved out of the parent but the classes still remain.
So the check is looking for .parent(n) and then finding the ul with .parent(n) eventually this code will live inside:
$('sortable li').appendTo($('THIS-IS-THE-DYNAMIC-CLASS'));
So I'm assuming the find will be before this but I don't know how to write that.
I would use a different attribute other than class so it can be wholly unique. Either use $(this).data or $(this).attr. And I would recommend assigning IDs to the parent (or a different attribute) that, again, can be wholly unique. This will keep things cleaner in my opinion.
For example...
Assuming:
$(this).attr('parentClass', '.parent' + key);
then
$('.sortable li').each(function() { $(this).appendTo($(this).attr('parentClass')); });

how to get value of HTML from jquery or javascript

I want to select the following three values from the HTML file either by Jquery or Javascript.
class "class1" href value
class "class1" inner text value (PersonA in the example code)
class "Title" inner text value (Accountant in the example)
How can I select all the data of li node by node as? I am lost :(
<ol id="result-set">
<li id="v-0">
<div class="result-data">
..
<h2>
<a class="class1" href="">PersonA</a>
</h2>
<dl class="basic">
<dt>Title</dt>
<dd class="title">Accountant</dd>
....
</dl>
</div>
</li>
<li id="v-1">
...
</li>
.....
To get "PersonA": $('#v-0 h2 a').html();
To get href of that link: $('#v-0 h2 a').attr('href');
To get "Accountant": $('#v-0 dl dd').html();
You can modify the id ("v-0") at the start of the selector to choose a particular "row" of your data set.
With jQuery, you can do something like this:
$("#result-set li").each(function() {
var $currentLi = $(this),
$class1link = $currentLi.find("a.class1"),
class1href = $classAlink.attr("href"),
class1content = $classAlink.html();
// do something with values
});
The .each() method will process each li element. Within the callback to .each() the variable $currentLi is a jQuery object holding that li (set from $(this) where this is the li element itself). The .find() method is used to find the anchor element within the li and then its href and content are retrieved.
The "Accountant" you asked about is one item in a definition list, so you'd probably want to loop through that list with another .each() statement nested inside the one above.
You don't make it clear how you want to use the values, but this should get you started. For further details about the various jQuery methods I've mentioned check the jQuery API.
document.getElementById(Id).value
returns value of element with specific id. in jquery:
$("#id").val()
by class $(".yourClass").val()
to get attribute value use attr("attributeName") for example $(".class1").attr('href').
if you want to get text from specified element use .text() like $(".title").text() //will return Accountant.
You mean selecting them with a jQuery selector? That would be done like so:
$('.class1').attr('href') //class1 href, i persume you dont mean classA as it doesnt exist in your code
$('.class1').text(); //PersonA text using the same selector
$('.title').text(); //Accountant from the .title dd

Javascript getElementsByTagName

I'm trying to use the getElementsByTagName("a") method to get all the elements under a specific tag.
However, I don't want every anchor tag. How would I narrow it so I only select all the anchor tags under the the ul tag for "someListClass" name?
<ul class="someListClass"> <li><a href... /></li>... </ul>
I know in jQuery you can just select with $(".someListClass a").
How would I do it without using jQuery?
Give your ul an id and then use
<ul id="ulid" class="someListClass"> <li><a href... /></li>... </ul>
document.getElementById ( "ulid" ).getElementsByTagName ( "a" );
element.getElementsByTagName
elements = element.getElementsByTagName(tagName);
elements is a live NodeList of found
elements in the order they appear in
the subtree.
element is the element from where the
search should start. Note that only
the descendants of this element are
included in the search, but not the
element itself.
tagName is the qualified name to look
for. The special string "*" represents
all elements. For compatibility with
XHTML, lower-case should be used.
you can use
element.getElementsByTagName(tagName)
where element is the UL item... so grab the UL item then search against that. something like:
<ul class="someListClass" id="myList"> <li><a href... /></li>... </ul>
var theList = document.getElementById('myList');
var listItems = theList.getElementsByTagName('li');
you want getElementsByClassName http://www.quirksmode.org/blog/archives/2008/05/getelementsbycl.html
links = document.getElementsByClassName("someListClass")[0].getElementsByTagName("a")
Without a framework, I can think of no other way than going though each element manually and to iterate its parents. If one of them has the class "somelistClass", add it to the stack. Otherwise, not.
If you are looking for the children of a single element, phoenix's approach is the way to go.

Categories

Resources