So I have a list of elements in an array. I'd like to add a jQuery toggle event to each element and pass in two functions as parameters. This is what I have so far, though it's giving me errors, saying that e (the Event Object) is undefined inside moveToSelected and moveToUnselected.
// Getting my array
var selected = document.getElementsByClassName("selected_style");
// The two functions to toggle between:
function moveToSelected(e) {
style = e.target;
style.className = "selected_style";
$('#selected-style').append(e.target);
}
function moveToUnselected(e) {
style = e.target
style.className = "unselected_style";
$('#unselected-style').append(e.target);
}
// Going through the array and adding a toggle event to each element.
for(var i = 0; i < selected.length; i++) {
var element = $(unselected[i]);
element.toggle(moveToSelected, moveToUnselected);
}
HTML, as requested:
<ul id="selected-style">
<li>
Some Style
</li>
<li class="selected_style">
Style
</li>
<li class="selected_style">
Style
</li>
<li class="selected_style">
Style
</li>
</ul>
Thanks for the help!
Uhm, why aren't you using jQuery, this is already built in ?
$('.selected_style').on('click', function() {
$(this).toggleClass('selected_style unselected_style');
if ( $(this).hasClass('selected_style') ) {
$('#selected-style').append(this);
} else {
$('#unselected-style').append(this);
}
});
FIDDLE
The vanilla javascript solution for future viewers. No jQuery required. This is effectively the same script as the accepted answer, without all the overhead of jQuery.
(Demo)
(function () {
"use strict";
var selected = document.getElementById('selected-style');
var unselected = document.getElementById('unselected-style');
var items = document.querySelectorAll('.selected_style'), item;
for (var i = 0; item = items[i]; i++) {
item.onclick = function(){
if(this.className.indexOf('unselected_style') >= 0) {
this.className = this.className.replace(' unselected_style','');
this.className += ' selected_style';
selected.appendChild(this);
} else {
this.className = this.className.replace(' selected_style','');
this.className += ' unselected_style';
unselected.appendChild(this);
}
};
}
})();
Related
I am populating an unordered list item with javascript as follows:
for(var i = 0; i < ourData.length; i++){
$('#searchTeamResultView').append(`<li> <Button class="ui-btn" value=${ourData[i]}> ${ourData[i]["team_long_name"]} </Button> </li>`)
}
The ourData is an array of json objects. I want to get log the value of whatever the button user clicks. I am detecting the click using the following code
$("#searchTeamResultView").on("click", "li", function(){
console.log("FML"); // I don't understand what to put inside the log
})
I am unsure on how to log the value of list item on which the user clicks. It would be great if someone could assist me with it. Sorry if this is a noob question. I was unable to figure it out on my own.
If you attach the event handler to the button element instead of the li, which makes more sense semantically, then you can simply use this.value within the event handler. Try this:
let ourData = ['lorem', 'ipsum', 'dolor'];
for (var i = 0; i < ourData.length; i++) {
$('#searchTeamResultView').append(`<li><button class="ui-btn" value="${ourData[i]}">${ourData[i]}</button></li>`);
}
$("#searchTeamResultView").on("click", "button", function() {
console.log(this.value);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="searchTeamResultView"></ul>
Once added onclick event, you can get exact element by "this" value.
For example.
$( document ).ready(function() {
let $elementsDiv = $('.elements');
for(let i = 0; i < 5; i++) {
//Creating new div with on click handler and adding attr subIndex
let $newOnclickElement = $('<div></div>')
.on('click', function() {
handleOnClick(this);
})
.attr('subIndex', i)
.html('element ' + i);
$elementsDiv.append($newOnclickElement);
}
});
function handleOnClick(subElement) {
console.log(subElement);
//To get its attr for example some new index we gonna add;
let $subElemenet = $(subElement);
//Console log subIndex
console.log($subElemenet.attr('subIndex'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='elements'>
</div>
Someone beat me to it :(
Here is how I populate my list:
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
Here is my html file:
<ul id="myList"></ul>
I want to add a click event for every item of list (without having separate ids):
$(function() {
$('#myList').click(function() {
var listItem = this.find('a').text();
console.log(listItem); // never logged
});
});
However, when I click at a list item, click event doesn't fire.
What am I doing wrong?
I can only assume there's a js error in your console.
I've created a working sample for you. We can use event delegation and then retrieve the DOM node that was clicked. You need to ensure you call the bingNetworksList [assume typo in here and meant binD ;)] function when the DOM ready event has fired.
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
$(function() {
var list = ["foo", "bar"]
bingNetworksList(list);
$('#myList').click(function(evt) {
var listItem = $(evt.target).text();
console.log(listItem); // never logged
});
});
You need to wrap this inside $ as like this:
$(function() {
$('#myList').click(function() {
var listItem = $(this).find('a').text();
console.log(listItem); // will always be logged
});
});
Add multiple items to text-area with duplicate items.
I have one text-area which store data after clicked add data link.
How can i prevent add duplicate items to text-area?
JavaScript call DOM event:
var Dom = {
get: function(el) {
if (typeof el === 'string') {
return document.getElementById(el);
} else {
return el;
}
},
add: function(el, dest) {
var el = this.get(el);
var dest = this.get(dest);
dest.appendChild(el);
},
remove: function(el) {
var el = this.get(el);
el.parentNode.removeChild(el);
}
};
var Event = {
add: function() {
if (window.addEventListener) {
return function(el, type, fn) {
Dom.get(el).addEventListener(type, fn, false);
};
} else if (window.attachEvent) {
return function(el, type, fn) {
var f = function() {
fn.call(Dom.get(el), window.event);
};
Dom.get(el).attachEvent('on' + type, f);
};
}
}()
};
JQuery add data to textarea:
$("#lkaddlanguage").click(function(){
var totalstring;
var checkconstring = $("#contentlng").text();
var strLen = checkconstring.length;
myStr = checkconstring.slice(0,strLen-1);
//alert(myStr);
var checkedItemsArray = myStr.split(";");
var j = 0;
var checkdup=0;
totalstring=escape($("#textval").val()) ;
var i = 0;
var el = document.createElement('b');
el.innerHTML = totalstring +";";
Dom.add(el, 'txtdisplayval');
Event.add(el, 'click', function(e) {
Dom.remove(this);
});
});
HTML Display data
<input type="textbox" id="textval">
<a href="#lnk" id="lkaddlanguage" >Add Data</a>
<textarea readonly id="txtdisplayval" ></textarea>
This seems a very straightforward requirement to me, so I'm not quite clear where you're getting stuck. I have not tried too hard to figure out your existing code given that you are referencing elements not shown in your html ("contentlng"). Also, mixing your own DOM code with jQuery seems a bit pointless. You don't need jQuery at all, but having chosen to include it why then deliberate not use it?
Anyway, the following short function will keep a list of current items (using a JS object) and check each new item against that list. Double-clicking an item will remove it. I've put this in a document ready, but you can manage that as you see fit:
<script>
$(document).ready(function() {
var items = {};
$("#lkaddlanguage").click(function(){
var currentItem = $("#textval").val();
if (currentItem === "") {
alert("Please enter a value.");
} else if (items[currentItem]) {
alert("Value already exists.");
} else {
items[currentItem] = true;
$("#txtdisplayval").append("<span>" + currentItem + "; </span>");
}
// optionally set up for entry of next value:
$("#textval").val("").focus();
return false;
});
$("#txtdisplayval").on("dblclick", "span", function() {
delete items[this.innerHTML.split(";")[0]];
$(this).remove();
});
});
</script>
<input type="textbox" id="textval">
<a href="#lnk" id="lkaddlanguage" >Add Data</a><br>
<div id="txtdisplayval" ></div>
<style>
#txtdisplayval {
margin-top: 5px;
width : 200px;
height : 100px;
overflow-y : auto;
border : 1px solid black;
}
</style>
Note I'm using a div (styled to have a border and allow vertical scrolling) instead of a textarea.
As you can see I've coded it to display an alert for duplicate or empty items, but obviously you could remove that and just ignore duplicates (or substitute your own error handling). Also I thought it might be handy to clear the entry field and set focus back to it ready for entry of the next value, but of course you can remove that too.
Working demo: http://jsfiddle.net/LTsBR/1/
I'm confused.
The only variable that might have duplicates comes from:
var checkedItemsArray = myStr.split(";");
However, checkedItemsArray is not used for anything.
Incidentally, the escape method is deprecated in favour of encodeURIComopnent.
When setting the value of the textarea, do just that: assign to its value property, not to its innerHTML (it can't have markup inside it or any elements, only text nodes).
If you want to check that the members of checkedItemsArray are unique, and you don't mind if they are sorted, you can use a simple function like:
function unique(arr) {
arr.sort();
var i = arr.length;
while (i--) {
if (arr[i] == arr[i - 1]) {
arr.splice(i, 1);
}
}
return arr;
}
Orignal order can be maintained, but it's a bit more code.
For my website navigation I need to add the class 'active' to the li element depending on if it matches the current URL.
Nav HTML:
<ul id="nav">
<div id="wrapper">
<li>Home</li>
<li>Reviews</li>
<li>First Looks</li>
<li>Commentaries</li>
<li>Walkthroughs</li>
<li>Achievements</li>
</div>
</ul>
If you want to use "pure" ("vanilla") JavaScript, use the following code(assuming that <ul id="nav"> exists):
window.onload = function() {
var all_links = document.getElementById("nav").getElementsByTagName("a"),
i=0, len=all_links.length,
full_path = location.href.split('#')[0]; //Ignore hashes?
// Loop through each link.
for(; i<len; i++) {
if(all_links[i].href.split("#")[0] == full_path) {
all_links[i].className += " active";
}
}
}
Using jQuery:
$(document).ready(function(){
var full_path = location.href.split("#")[0];
$("#nav a").each(function(){
var $this = $(this);
if($this.prop("href").split("#")[0] == full_path) {
$this.addClass("active");
}
});
});
I think, in this case, is better change in server side.
Using javascript you can do:
var target = 0;
switch( window.location.pathname )
{
case "/tagged/Review":
target = 1;
break;
case "/tagged/First_Look":
target = 2;
break;
/* add other cases */
}
document.getElementById("nav").getElementByTagName("li")[target].classList.add("active");
Put the code after loaded DOM.
If jquery, you can use:
var target = 0;
switch( window.location.pathname )
{
case "/tagged/Review":
target = 1;
break;
case "/tagged/First_Look":
target = 2;
break;
/* add other cases */
}
$($("#nav li")[target]).addClass("active");
EDIT
window.onload or $.ready is the way to know if the document is loaded.
I have these links:
<a class="active" href="#section1">Link 1</a>
Link 2
When a link 2 is clicked I would like it to receive the active class and remove the class from link 1 itself so it would effectively become:
Link 1
<a class="active" href="#section2">Link 2</a>
This should work both ways. Ie. whatever link is clicked gets the class and removes it from the other.
How can this be done with JavaScript/Prototype?
Try this:
// initialization
var links = document.links;
for (var i=0; i<links.length; ++i) {
links[i].onclick = function() {
setActive(links, this);
};
}
function setActive(links, activeLink) {
for (var i=0; i<links.length; ++i) {
var currentLink = links[i];
if (currentLink === activeLink) {
currentLink.className += " active";
} else {
currentLink.className = currentLink.className.split(/\s+/).map(function(val) {
return val === "active" ? "" : val;
}).join(" ");
}
}
}
You could write a little helper function with prototype support that removes the class from all active elements and adds it to the one that was clicked on:
function active(e) {
$$('.active').each(function(i) {
i.removeClassName('active');
});
e.addClassName('active');
};
You can than call this function from your onclick events:
a
b
c
If it were jQuery, I would do it like
$(document).ready(
function(){
$("a").click(function(){
$("a").toggleClass("active");
});
}
)