I have a question, I have created ng-repeat which i print out li with the names.
then after catching the li element The dndDragging class is added(to li).
And now I have a question how to check if this class has been added, after after pick up item?
Could someone tell me how to do it?
<ul dnd-horizontal-list="true"
dnd-list="board.lists"
dnd-allowed-types="['item']" >
<li ng-repeat="item in board.lists"
dnd-draggable="item"
dnd-type="'item'"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
ng-class="{'selected': models.selected === item}"
dnd-moved="removeList($index)" >
{{item.list}}
</li>
</ul>
It all depends what are you trying to do but I wouldn't go for any class checking and DOM manipulation - that's jQuery way.
What you most likely need is to put your logic in dnd-moved - here you would splice your array and move item out of array and put it somewhere else - there in that function (removeList) you can make all necessary logic.
If that's not enough you can use this to check when element started dragging:
dnd-dragstart
or this to check when drag ended:
dnd-dragend
you even have this to check if element is dragged over another element:
dnd-dragover
and just add callback functions where you can place your logic, so there's litteraly no need for class checking. I'm not 100% sure what are you trying to do but first consider reading all documentation before you start implementing solutions: https://github.com/marceljuenemann/angular-drag-and-drop-lists
Related
This is the first time I’ve thought about moving my events outside of the normal HTML onClick=”” event but I cant seem to find any references as to how I would do this with a li list.
Basically I’m trying to get the number associated with the scrollToArtical(#) in to myElement.onclick. How would you rewrite this so that the event is in the .js file.
I’ve tried variations of to get at the element but these don’t work:
var objScrollToNav = document.getElementById("id_ScrollToNav").children;
var objScrollToNav = document.querySelector("#id_ScrollToNav a");
Any help would be greatly appreciated – CES
My old code is:
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff"><a onclick="scrollToArticle(0)" role="link">•</a></li>
<li class="sectionNavOn"><a onclick="scrollToArticle(1)" role="link">•</a></li>
<li class="sectionNavOff"><a onclick="scrollToArticle(2)" role="link">•</a></li>
</ul>
Use document.querySelectorAll to get an array-like list, then loop over them. To keep a reference to the index, make sure you also pass the index into a new closure (the addEvent function below creates a new closure).
function scrollToArticle(index) { console.log("Scrolling to:", index); }
// Select all the elements.
var links = document.querySelectorAll("#id_ScrollToNav a");
// This function adds event listener, and holds a reference to the index.
function addEvent(el, index) {
el.addEventListener("click", function() {
scrollToArticle(index);
});
}
// Loop over the elements.
for (var i = 0; i < links.length; i++) {
addEvent(links[i], i);
}
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff"><a role="link">•</a></li>
<li class="sectionNavOn"><a role="link">•</a></li>
<li class="sectionNavOff"><a role="link">•</a></li>
</ul>
Since your li elements can be gathered up into an array and arrays have indexes, you really don't need to pass a hard-coded number to your function. You can just pass the index of the li that is being clicked to the function.
Also, don't use <a> elements when they are not directly navigating you anywhere. This can cause problems for people who use screen readers. Instead, set up the click event directly on the li elements and eliminate the a elements completely.
Lastly, don't use inline HTML event attributes (onclick). That is how we did event handlers 20 years ago and, unfortunately, this technique just won't die. There are many reasons not to use them. Instead, follow modern standards and separate your JavaScript from your HTML.
// Get all the li elements into an array
var items = Array.prototype.slice.call(document.querySelectorAll("#id_ScrollToNav > li"));
// Loop over the list items
items.forEach(function(item, index){
// Assign each item a click event handler that uses the index of the current item
item.addEventListener("click", function(){ scrollToArticle(index) });
});
// Just for testing
function scrollToArticle(articleNumber){
console.log(articleNumber);
}
#id_ScrollToNav > li {
cursor:pointer;
}
<ul id="id_ScrollToNav" role="list">
<li class="sectionNavOff" role="link">•</li>
<li class="sectionNavOn" role="link">•</li>
<li class="sectionNavOff" role="link">•</li>
</ul>
To add to the above, use data- attributes to separate css styles from javascript (meaning, html class tags should be used for html/css things only).
<li data-element="sectionNavOff">
<li data-element="sectionNavOn">
There are some minor downsides to using data- tags, mainly speed, but many enterprise applications and frameworks (e.g. Bootstrap) tend to believe the upside to separating styles from javascript completely outweighs the downsides. If I knew whether or not you use jQuery I could give you a detailed usage example.
I would like to know if there is an easier way to check if an element has an ancestor with a particular class.
Consider the following HTML code:
<ul id="uniqueID" class="parentClass">
<li class="subclassA">
<div class="subclassB">
<nobr>
MyText
</nobr>
</div>
</li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
</ul>
<div>other elements in this page which I want to select</div>
Right now, I can select the element MyText by using a jQuery selector checking the href for a particular format. What I can then do is do .parent() a known number of times (4) and then check the class attribute of that particular element that I've now moved to. While this is working just fine, I am curious if there is a better way to do it, perhaps one that lets me be a bit more dynamic?
PS. There are a lot of elements that I'm selecting that'll fit this $('[href *= index.php]') format, so I want to keep those but remove the ones that fall under the categorization where they are a descendant of a member of class listclass. Currently I'm just selecting all of the elements with the selector above, then using an if statement to check through and see if it fits this condition. Again, if there is a more efficient way to do this (perhaps select these certain elements in the first place?) I would love to hear about it.
Current code:
$('[href *= "index.php"]').each(function(){
if ($(this).parent().parent().parent().parent().attr('class') != 'parentClass'){
//do things
}
});
To generalise you can use
.closest(".parentClass")
You can use closest and is:
$('[href*="index.php"]').each(function(){
if ($(this).closest('ul').is('.parentClass')) {
//do things''
}
});
if($(this).parents("ul.parentClass").length == 0){
//do something
}
I am having very specific case where I needed to split the data into two different lists in html. Like this:
<ul id="first_list">
<li ref="1">The quick brown</li>
<li ref="2">My father works</li>
</ul>
And the second list is like:
<ul id="second_list">
<li ref="1">jumps over the lazy dog</li>
<li ref="2">at the Ministry of Defense</li>
</ul>
So as you can see I from the "ref" attribute I know which <li> element from the second list is a continuation of which <li> element from the fist list.
Now I need to enable the jQuery UI sortable() to those lists but when I reorder the first I need the second reordered too. I tried using handle but it doesn't works because it looks like the handle element needs to be inside the element which is moved but these two are at a different places in the page.
I do believe that you should have shared some of your code (what you've tried), and I'm assuming you are familiar with Sortable plugin that you are using. You should run the below code on success event of Sortable so as soon as you sort any LI, the other list will be sorted too. Anyways,
Try this:
//This line stored the LIs in a temp variable and remove it
var $cachedList = $('<div />').html($('#second_list').html());
$('#second_list > li').remove();
//This line loads up the first UL's LIs and replaces the content for each LI
//using $cachedList.
$('#second_list').html($('#first_list').html()).find('li').each(function () {
$(this).html($cachedList.find('li[ref="'+$(this).attr('ref')+'"]').html());
});
Demo: http://jsfiddle.net/AR8px/
Given an ordered HTML list, is there any way, given the list element, of determining it's number in JavaScript, besides looking at its location in the list?
For example, suppose I have a list
<ol start="4" type="i">
<li>First</li>
<li>Second</li>
</ol>
which is rendered as
iv. First
v. Second
What is the best way using JavaScript (including jQuery) that, given on of the LI, to find out it's number?
The naive way is to look at the item's index, add the start value, and translate the type. But I am wondering if there's a better way.
an example is to add an index property to the list item:
lets say your list has an id='ordered'
var ol = document.getElementById('ordered');
// select the list items
var lists = ol.getElementsByTagName('li');
// now loop through the items and set a custom property 'index'
var l = lists.length; // total items
for (var i=1;i<=l;i++){
list[i].index = i;
}
now your list item will have an index property that you can access through javascript to determine its position.
<ol id='ordered'>
<li index='1'>First</li>
<li index='2'>Second</li>
</ol>
Looking at http://www.w3.org/TR/html-markup/li.html I'd say using the value member.
note: this is in HTML5. in HTML4.01 both ol.start and li.value were deprecated. This means that this solution will probably work reliably only on browsers with HTML5 support.
The MDC documentation for the <li> element mentions the value attribute, which is supposed to do just that. It was deprecated in HTML 4 but has been reintroduced in HTML 5. If your browser supports it, you should be able to write:
$("li").prop("value"); // jQuery 1.6 and higher
$("li").attr("value"); // jQuery 1.5 and lower
I was, however, unable to use that attribute in Firefox 3.6 (it always returns -1). I created a fiddle if you want to test your browser's support for that feature.
Nice questions :)
I would say, better to inject data into each li elements, you could put some HTML attributes inside the li but I am afraid when you do HTML validation, it will reject it.
So this is the code,
var lis = $("ol li").each(function(i, el)
{
$(this).data("index", i);
});
and when you render your lovely number, do this:
$(this).data("index");
:)
Assume that I have such menu
<ul id="leftMenu">
<li class="selected">Foo1</li>
<li>Foo2</li>
<li>Foo3</li>
<li>Foo4</li>
<li>Foo5</li>
<li>Foo6</li>
</ul>
Now via javascript, I want to change the highlighted one thus remove the "selected" from the current one and add to the next one
What I need is, first remove the class from the currently selected one, than add to the next.
How can this be achieved?
EDIT: I use this for an embedded system WITHOUT mouse or jquery but remote control and plain javascript so up and down are my only options, no hover allowed :S
Using javascript for this would be an overkill in this day and age.
Since you tagged this css, may I suggest the following CSS-only method, also known as the :hover pseudo-class:
ul#leftMenu li:hover {
color: red;
}
If it were me, and I knew the menus weren't monstrously huge, I'd remove the class from all the <li> elements and then add it to the one I wanted.
var lis = document.getElementById('leftMenu').getElementsByTagName('li');
for (var i = 0; i < lis.length; ++i)
lis[i].className = lis[i].className.replace(/\bselected\b/g, '');
Now, as to how to put the class back, well that depends on how you've found your new favorite <li>. If it's in an event handler, then the event object will refer to it as the "target". You'd thus just append "selected" to the class name.