I am creating a photography course app in dreamweaver, and want users to be able to tap a button to randomly give them an assignment out of the numerous ones in the app.
All the various assignments are in separate div's, with separate div id's.
I've tried various javascript random link generators, but they don't link to the div ids...they are looking for the whole link (www.noelchenier.ca/#self) instead of the div ID's (#self).
Is there any way to do this?
This seems to be what this guy was asking too, but there is no explaination on where to use it?
How to jump to an anchor / div per random button (jQuery mobile)?
Thanks for any possible help
Noel Chenier
You seem to be saying that you have a long page with lots of divs on it all displayed at once, and you want a button to jump down to a random one of those divs. If so this works:
<script>
$(document).ready(function() {
$("#getAssignment").click(function() {
var $divs = $(".assignment");
if ($divs.length > 0) {
window.location.href = "#" + $divs[ Math.floor(Math.random() * $divs.length) ].id;
}
});
});
</script>
<input id="getAssignment" type="button" value="Get assignment">
<div id="a1" class="assignment">Assigment 1</div>
<div id="a2" class="assignment">Assigment 2</div>
<div id="a3" class="assignment">Assigment 3</div>
<div id="a4" class="assignment">Assigment 4</div>
Essentially it gets a list of all divs with the "assignment" class and then selects one at random to move to by setting the location.href to "#" plus the div id - this means the hash part of the url will change in the address bar so the user can bookmark that particular assignment.
However, selecting a random assignment from a bunch that are all displayed seems a bit strange when the user could just browse through the list themselves. It would make more sense to me to start out by hiding all of the assignments and then just show a random one each time the button is clicked. Using the same html as above:
$(document).ready(function() {
var $assignments = $(".assignment");
$assignments.hide();
$("#getAssignment").click(function() {
$assignments.hide();
if ($assignments.length > 0)
$($assignments[Math.floor(Math.random()*$assignments.length)]).show();
});
});
UPDATE
From your last comment, I wonder if you're trying to use the same id attribute for more than one element? That won't work because each id needs to be unique.
If the idea is to have several container divs with a button in each that is supposed to randomly select a div from within that container, try giving class="getAssignment" in the buttons instead of id=..., then code something like this:
<script>
$(document).ready(function() {
$(".getAssignment").click(function() {
var $divs = $(this).parent().find(".assignment");
if ($divs.length > 0) {
window.location.href = "#" + $divs[ Math.floor(Math.random() * $divs.length) ].id;
}
});
});
</script>
<div>
<input class="getAssignment" type="button" value="Get assignment">
<div id="a1" class="assignment">Assigment 1</div>
<div id="a2" class="assignment">Assigment 2</div>
<div id="a3" class="assignment">Assigment 3</div>
<div id="a4" class="assignment">Assigment 4</div>
</div>
<div>
<input class="getAssignment" type="button" value="Get assignment">
<div id="b1" class="assignment">Assigment 7</div>
<div id="b2" class="assignment">Assigment 8</div>
<div id="b3" class="assignment">Assigment 9</div>
<div id="b4" class="assignment">Assigment 10</div>
</div>
The click handler is assigned to all elements with class of "getAssignment", then the code $(this).parent().find(".assignment") takes the parent div of the clicked button and finds any ".assignment" divs within it.
Since you haven't posted any HTML, there are several possibilities. First one, list all the relevant IDs in a javascript array and pick one randomly:
var items = [
"id1",
"id2",
"id3"
];
var randomItemId = items[Math.floor(Math.random() * items.length)];
Then, access if with jQuery:
$("#" + randomItemId)
Second, if all the relevant divs have the same class name, you can do it like this:
var items = $(".whateverClassName");
var randomItemNum = Math.floor(Math.random() * items.length);
var randomItem = items.eq(randomItemNum);
Related
I'm learning to get data from other pages using jQuery and one of the problems I encountered while doing so is when trying to find multiple elements, getting the text from them and then printing them into multiple lines
The problem is that I didn't find a way to print them into multiple lines without storing each element in its own variable.
Here's an example that clarifies what I'm trying to do:
External HTML:
<div class="element element1">
<div class="irrelevant">irrelevant text 1</div>
<div class="anitem1">text 1</div>
<div class="theitem2">text 2</div>
<div class="irrelevant">irrelevant text 2</div>
<div class="item3">text 3</div>
<div class="theitem4">text 4</div>
<div class="irrelevant">irrelevant text 3</div>
</div>
Internal HTML:
<div class="app"></div>
jQuery:
theUrl = 'https://api.allorigins.ml/get?url=' + encodeURIComponent('
https://www.thisisjustanexampleurl.com/something.html');
$.ajax({
url: theUrl,
type: get,
dataType: "",
success: function(data) {
$(data.contents).find('.element').each(function(i, obj){
var getText = $(obj).find('.anitem1, .theitem2, item3, .theitem4').text();
$('.app').append(getText) // output: text 1text 2text 3text 4
})
}
})
The text is on the same line, but what I'm looking for is to print it on multiple lines.
Expected Output:
text 1
text 2
text 3
text 4
You may iterate again through the objects in .find() result:
var newText;
var getText = $(obj).find('.anitem1, .theitem2, item3, .theitem4').each(function(){
newText=$(this).text() + '<br>'; // or \n
$('.app').append(newText);
});
You can use children function and get text using text and append a new line \n
let vars = '';
$('.element').children().each((i, v) => {
vars += $(v).text() + '\n'
})
console.log(vars)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="element element1">
<div class="anitem1">text 1</div>
<div class="theitem2">text 2</div>
<div class="item3">text 3</div>
<div class="theitem4">text 4</div>
</div>
.innerText
Handling text nodes was never one of jQuery's strong points. .innerText property extracts the text of selected elements plus that of all of it's descendants as well -- line breaks included. It's a plain JavaScript property so if you use it on a jQuery Object you need to dereference it to a DOM object. There are two ways to dereference:
$(selector)[0]
or
$(selector).get(0)
All it takes is one line. Just pick an ancestor element and let her rip.
$('.app')[0].innerText = $('.app')[0].innerText;
Solution
Filter the .irrelevant tags out:
$('.element').find(':parent').not('.irrelevant')...
Clone and append it to .app
.....clone(true, true).appendTo('.app');
Overwrite everything in .app with .innerText.
$('.app')[0].innerText = $('.app')[0].innerText;
The result is just text nodes and <br>. No repetition it's straight copy, paste, and format programmatically.
Demo
The text in the red outlined box (i.e. .app) is the result.
.app {
outline: 1px dashed red
}
<!DOCTYPE html>
<html>
<head></head>
<body>
<header class='app'></header>
<div class="element element1">
<div class="irrelevant">irrelevant text 1</div>
<div class="anitem1">text 1</div>
<div class="theitem2">text 2</div>
<div class="irrelevant">irrelevant text 2</div>
<div class="item3">text 3</div>
<div class="theitem4">text 4</div>
<div class="irrelevant">irrelevant text 3</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$('.element').find(':parent').not('.irrelevant').clone(true, true).appendTo('.app');
$('.app')[0].innerText = $('.app')[0].innerText;
</script>
</body>
</html>
I resolved this easily by creating an array for the elements I want to include and then I mapped over each element and added a </br> to the end.
Here's the code:
// Array for the elements I want to select
var classes = ['.anitem1', '.theitem2', '.item3', '.theitem4'];
// Declaring the variable which will include the elements of the list
var lists;
/* Mapping over each element in classes array,
finding it and getting a text from it + adding br tag to it*/
classes.map(function(x) {lists += $(obj).find(x).text() + '</br>'})
// Appending lists to app
$('.app').append('<ol><li>' + lists + '</li></ol>');
I selected zer00ne's answer as the best solution because it resolves the problem in only one line.
But for my code, I'm using the above because it resolves other problems that I'm unable to share all of them here and If I do I will end up writing a very long code. One of them is that I have many elements containing items with the same class. Using the former approach will push all of the items to the first ordered list, while what I want is pushing the items of the first element to the first <ol>, and those of the second to the second <ol> and so on.
I'm using Javascript and I'm having problems trying to remove several elements.
Each div has a specific ID, like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
<div id='4'></div>
Each div has a button that fires the remove() function
document.getElementById(count).remove()
Count is a variable that is increased whenever I create a new div
The remove() function works, but it creates a gap. IF i remove the div with id=2, then:
<div id='1'></div>
<div id='3'></div>
<div id='4'></div>
But I would like that the remaining IDs could downshift like this:
<div id='1'></div>
<div id='2'></div>
<div id='3'></div>
I guess I need a for loop but I can't understand how to make it
Use a class on each element, like this:
<div class="a" id='1'></div>
<div class="a" id='2'></div>
<div class="a" id='3'></div>
<div class="a" id='4'></div>
And call the following function after each removal:
function resetId(){
const list = document.getElementsByClassName("a")
for(let i = 0; i < list.length; i++){
list[i].id = i + 1
}
}
However, it might be better to just not use IDs in this case. By applying the same class to all your elements, there's no need to readjust the numbering, and you can select (or remove) the nth element using:
document.getElementsByClassName("a")[n]
This would probably be best achieved using jquery.
Here is the working code below:
$("div").each(function(i) {
$(this).attr('id', ++i);
});
$("#remove").click(function() {
$("#2").remove();
$("div").each(function(i) {
$(this).attr('id', ++i);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
<div id=""><span>0</span></div>
remove
How it works
First $(this).attr('id', ++i); this line here is used to add a number to div id. Ive repeated it in the remove function [("#remove").click(function()] This is because once a div has been removed the will be a number change.
This in affect is a loop. Without all the lines of code. Which is why i like jquery :)
The div id name is found here after they have been written $("#2").remove(); #2 refers to the <div id="2"> As you would in css.
If you notice, with an inspection the numbers down shift as 1 is removes as per your request.
In order to use jquery you have to link the library. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
A Pure Javascript Version
function resetId(){
var div=document.getElementsByClassName("div")
for(i in div){
div[i].id=i++
}
}
function clicked() {
var elem = document.getElementById("1");
elem.parentNode.removeChild(elem);
resetId();
}
<div class="div" id="0">div</div>
<div class="div" id="1">div</div>
<div class="div" id="2">div</div>
<div class="div" id="3">div</div>
Remove
How it Works
This section here is your loop:
for(i in div){
div[i].id=i++
}
This section quite simply rewrites the numbers 0 - 4 after one has been removed.
The reason it starts from 0, is because in programming we start counting from 0. Hay 0 is a number too guys :).
The i++ Is a basically a mini int [ish] that is increased as the loop counts through how many divs there are.
This var elem = document.getElementById("1"); & this elem.parentNode.removeChild(elem); Is why I find jquery more acceptable in this situation. Its a bit less faf.
Finally resetId(); We have to call the function otherwise it doesn't that anything has changed, because computers are silly and need to be told.
Furter Reading
https://api.jquery.com/
http://www.lucemorker.com/blog/javascript-vs-jquery-quick-overview-and-comparison
Sounds like you should be using classes and referencing elements by index instead. IDs should remain persistent for clarity.
document.getElementsByClassName('my-class')[2].remove();
<div class="my-class" id="thing1">One</div>
<div class="my-class" id="thing2">Two</div>
<div class="my-class" id="thing3">Three</div>
<div class="my-class" id="thing4">Four</div>
I've done quite a bit of research for this but can't get my mind around it.
There is a parent div .container. Which has numerous child divs having different text inside them. There are two buttons outside the .container. One is used to dynamically create and append a child element having particular text. Other is to remove a child div having particular text.
The first time the page is loaded everything works but when a new child div is added (lets say having text xyz) and then use enters xyz in textarea and presses remove button (which is coded to remove child div having text xyz in them) it doesn't work.
Sample HTML markup (there may be infinite number of child divs)
<div class="container>
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
<div class="child4"></div>
</div>
<button class="AppendWithSomeText"></button>
<button class="RemoveDivWithSomeMatchedText"></button>
<textarea></textarea>
jquery for adding the div
var newdiv = = document.createElement('div');
newdiv.className = 'child';
$(".container").append(newdiv);
$(".container").find(".child").html(textfromtextarea);
// here text from text area is a string stored from user input in textarea
jQuery for remove button
$('.container>div:contains("'+textfromtextarea+'")').remove();
//works only first time
http://codepen.io/dustinpoissant/pen/VYXGwB
HTML
<input type='text' id='input' />
<button onclick='addItem()'>Add</button>
<button onclick='removeItem()'>Remove</button>
<br><br>
<div id='box'></div>
JavaScript
function addItem(){
$("#box").append("<span>"+$("#input").val();+"</span>");
}
function removeItem(){
var text = $("#input").val();
$("#box span").each(function(i, el){
if($(el).text()==text) $(el).remove();
});
}
Inorder to keep the uniformity of structure I have added class of type child-number.
I hope this is what you expected.
$(document).ready(function() {
$(".AppendWithSomeText").on("click", function() {
$(".container").append("<div class=child" + ($("[class^='child']").length + 1) + ">" + $(".content").val() + "</div>")
})
$(".RemoveDivWithSomeMatchedText").on("click", function() {
$('.container>div:contains("' + $(".content").val() + '")').remove();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div class="child1">somecontent</div>
<div class="child2">somecontent</div>
<div class="child3">somecontent</div>
<div class="child4">somecontent</div>
</div>
<button class="AppendWithSomeText">add</button>
<button class="RemoveDivWithSomeMatchedText">remove</button>
<textarea class="content"></textarea>
Lets say I have struckture like this:
<div id="stuff">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
The divs will be dynamically added, meaning I cant say how much there will be.
When I rearrange the divs with jquery, is there a way to acces one of them even after they are moved?
Is there some dynamically way to add an id to them and/or is there another way to achieve this?
Give id to each div based on its sequence position like below:
<div>
<div id='pos1'>1</div>
<div id='pos2'>2</div>
<div id='pos3'>3</div>
</div>
Then you can easily follow it using its position class irrespective its changed position.
alternatively you can use classes but they behaves slowly.
Just added a code snippet!
http://jsfiddle.net/q4273/
html:
<input class="btn teach_edit_header_buttons" style="font-family:Helvetica" type="submit" value="Add Div">
<div id='parent'></div>
js:
$(function () {
$("input[type=submit]").click(function () {
// get the available children
var len = $('#parent').children('div').length;
//determine the id = length+1
var id = "item" + (len + 1);
// append the child
$("<div id='" + id + "'/>").html(id).appendTo("#parent");
})
});
You must give and id to your div when you dynamically creat them. Maybe with JQuery :
.attr("id","myid");
I was wondering how you could "relate" two HTML elements.
For example, let's say a user clicks on a selection item and I want the element "related" to that element disappear.
<div id="game1Selection">I pick team1</div>
<div id="game2Selection">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
What I would want to happen is that when a user selects "game1Selection" that the div "game1" will disappear and the same thing for game2, game3, etc. I know how to do this the long way:
$('#game1Selection').click( function() {
$('#game1').toggleClass('selected');
}); //selected has the attribute display:none
How could I make two of them related so I don't have to write it the long way and just use this
jsBin demo
$('div[id$=Selection]').click(function(){
var myID = this.id.split('Selection')[0];
$('#'+myID).toggleClass('selected');
});
use the ends with selector $ and retrieve the first part of the ID name by splitting the original ID and getting the first ([0]) part of the name (gameN)
a better idea demo
But a far better example would be using this HTML:
<div>
<div class="selection">I pick team1</div>
<div class="selection">I pick team2</div>
</div>
<div class="game">This is game 1</div>
<div class="game">This is game 2</div>
and retrieve the clicked element index() and find the matching element using .eq() :
$('.selection').click(function(){
var i = $(this).index();
$('.game').removeClass('selected').eq(i).addClass('selected');
});
This will allow you to remove the already selected classes and assign it to the index-matching element.
Use classes for like behavior, and grab the number from the id.
<div id="game1Selection" class="selection">I pick team1</div>
<div id="game2Selection" class="selection">I pick team2</div>
<div id="game1" class="game">This is game 1</div>
<div id="game2" class="game">This is game 2</div>
$('.selection').click( function() {
$("#" + this.id.replace("Selection", "")).toggleClass('selected');
$('.game').not(this).removeClass('selected');
});
I prefer to use HTML5's data-* properties to make the association more explicit:
<div class="selector" data-fadetarget="game1">I pick team1</div>
<div class="selector" data-fadetarget="game2">I pick team2</div>
<div id="game1">This is game 1</div>
<div id="game2">This is game 2</div>
JavaScript:
$('.selector').click( function() {
var target = '#' + $(this).data('fadetarget');
$(target).toggleClass('selected');
});
Using this method, the associations are explicit in the markup and won't fail if things are rearranged.