Edit HTML list entry with javascript - javascript

Note: i searched a half hour. I need a special solution for this:
I have the folowing code already (node some Variables have german Names i hope that's ok)
function generateList () {
document.getElementById("liste").innerHTML =""
var listEasy = vorNameListe[i] + " " + nachNameListe[i] + " " + alterListe[i]
for (var i=0; i < vorNameListe.length; i++) {
document.getElementById("liste").innerHTML += "<li>" + listEasy + "</li>"
};
Now i need a javascript (pls no jquery) solution so the user can change every List entry by himself. How do i do that?
further explanation: The code i have is one to bring a "li" in a existing "ul" with every loop.
But then i want to give every "li entry" the ability to be changed by the user.

Are you trying to change text of every li of #liste ul?
function generateList() {
var liItems = document.querySelectorAll('#liste > li');
for (i = 0; i === liItems, i++) {
liItems[i].innerHTML = 'content';
}
}

i refined my edit function with jquery fdurther and further i will edit this entry for every step:
I have a Special Idea about an Edit function
https://stackoverflow.com/questions/28695711/edit-and-delete-selected-list-entrys

Related

Adding clickable buttons or links for side bar

I'm having trouble adding links or buttons to my side bar dynamically. I'm trying to use JavaScript to add the appropriate amount of elements or buttons(I don't know what is better). In essence this is used to make a JS quiz website where each of the buttons in the sidebar will jump you to the question(to make it more clear: Question 4 takes you to 4th question and so on)
This is my side bar:
<div id="mySidenav" class="sidenav">
×
Question
</div>
My JS trying to make the elements but failing to do so:
//add question numbers to the side bar
function questionNav(){
for(var i = 0; i < numberOfQuestions; i++){
document.getElementById("mySidenav").innerHTML = "Question " + (i+1) + "<br/>";
//var newSideBarElm = "Question " + (i+1) + "<br/>";
//document.getElementById("mySidenav").insertAdjacentHTML = ('beforeend',newSideBarElm);
}
}
I've been trying numerous different methods but I can't get it to work and would greatly appreciate if someone was able to help me.
Here is the full code of the site in case you would like to see how I'm doing everything else: https://pastebin.com/hrSADLQy
So assuming that I understand your question correctly, what you are currently doing is targeting the div with the id 'mySideNav' and overwriting its content by assigning a new value to its innerHTML attribute. What you should be doing instead is
Create a new anchor element
Use the innerHTML attribute to insert your desired value (i.e "Question N")
Append your newly created element to your 'mySideNav' div element.
I wrote a small demo for you to see my answer in action, but will post my code below this answer for you to see as well.
// Grab and Store Element to append questions to
var mySideNav = document.getElementById('mySidenav');
// Designate number of questions
var numberOfQuestions = 10;
// Loop as many times as there are questions
for (let i = 0; i < numberOfQuestions; i++) {
// Step 1: Create a new anchor element
let newQuestion = document.createElement('a');
// Assign href to whatever you want
newQuestion.href = '#';
// Step 2: Use the innerHTML attribute to insert your desired value
newQuestion.innerHTML = 'Question ' + i + '<br>';
// Step 3: Append your newly created element to your 'mySideNav' div element.
mySideNav.appendChild(newQuestion);
}
I hope this helps!
According to your question and the code you provided i think you need to define a div with an onclick() property to make the corresponding question visible. That could be something like this (assuming you can access the number of questions inside this function):
function questionNav(){
for(var i = 0; i < numberOfQuestions; i++){
document.getElementById("mySidenav").innerHTML += "<div style='cursor:pointer' onclick=navigateToQuestion(" + (i+1) + ")/> Question " + (i+1) + "</div>";
}
}
And then define a the onclick function "navigateToQuestion" to show the question that is passed as parameter, maybe could be somethink like this:
function navigateToQuestion(question){
document.getElementById("question_" + currentQuestionInView).style.display = "none";
currentQuestionInView = question;
document.getElementById("question_" + question).style.display = "block";
}
Haven't tested the code but i think it should work.
Hope you get your problem solved :)

How do I populate a SELECT tag with many options without delays?

So I'm attempting to populate a select tag like so, using jquery, the range I'm choosing is actually pulled from a database but this simplifies things for you:
var select_tag = $("select");
for(var i = 0; i < 10000; i++)
{
$("<option value='" + i + "'>" + i + "</option>").appendTo(select_tag);
}
When I do this, the code take quite awhile to run and populate the select tag. So much so that a user might start to think that their browser closed and start clicking everywhere. Is there anyways I can speed the process up/optimize it so that it doesn't take this long?
Please note that the select tag itself is added to the page based on a click event, and is not loaded with the webpage right away. In this example a user is on one page, then the user clicks the 'Next' button, this triggers various functions one of which adds and populates the select element to the DOM. I just need a way to speed-up or optimize the process.
This is a solution.
var options = "";
for(var i = 0; i < 10000; i++)
{
options += "<option value='" + i + "'>" + i + "</option>";
}
$("select").append(options);
You could remove the element from the document and add all the elements, then insert it back into the document.
var select_tag = $("select").detach();
for(var i = 0; i < 10000; i++)
{
$("<option value='" + i + "'>" + i + "</option>").appendTo(select_tag);
}
$('#orignal-location').append(select_tag);
With Huge data there is always delay . So I recommend you to use another approach, like server filtering service with a client side control such as select2 or chosen jquery plugins to handle user input
Take a look at at these 2 they have remote data loading feature .
I hope this can help.
Unfortunately, I don't think there are many "macro" optimizations you can make.
There are a few smaller optimizations you can make, though.
Avoid parsing HTML -- create elements using document.createElement('option').
See Advantages of createElement over innerHTML?
Use a DocumentFragment to batch-insert all options at once.
See http://jsperf.com/document-fragment-vs-innerhtml-vs-looped-appendchild
Here's some sample code that does this:
var select_tag = $("select");
var docFrag = document.createDocumentFragment();
for(var i = 0; i < 10000; i++)
{
docFrag.appendChild(createOption(i, i));
}
select_tag.append(docFrag);
function createOption(text, value) {
// Avoid parsing HTML using jQuery; use native methods instead:
var option = document.createElement('option');
option.textContent = text;
option.setAttribute('value', value);
return option;
}

Removing elements from a document in Javascript [duplicate]

This question already has answers here:
JavaScript DOM remove element
(4 answers)
Closed 8 years ago.
Working on building this to-do list app to learn JS better.
I am able to insert text into box and have it add a new div element to the page with the relevant text residing within the div. The code that adds the div to the page automatically applies the class .newItem then adds an incrementing id i0, i1, i2, etc each time it's clicked. Everything works without an issue. Now, I have been fiddling around with the code to be able to click a single div element and have it remove itself from the page, but can't seem to get it to work.
var iDN = 0;
//Function that adds a new div with a custom incrementing id number
document.getElementById('add_button').onclick = function () {
var taskName = document.getElementById('add_task').value; // Store the value in the textbox into a variable
document.querySelector('.shit_to_do').innerHTML += '<div class = "newItem" id = "i' + iDN + '"' + 'onclick = removeEl()' + '>' + taskName + '</div>';
iDN += 1;
};
document.getElementById('testing').onclick = function () {
var parentNode = document.querySelector('.shit_to_do');
parentNode.removeChild(parentNode.children[0]);
}
function removeEl() {
for (i = 0; i < iDN; i++) {
if (document.getElementById('i' + i).onclick) {
document.getElementById('i' + i).display.style = 'none';
}
alert(i);
}
}
The for loop was really some random option I was trying to figure out how things were working onclick for each div, but didn't get to far with that one.
tl;dr:
I want to add click events to the new divs added onto the page in a single, universal function.
The value of document.getElementById('i' + i).onclick will be null if you've not set a handler to this attribute/property, otherwise it will be a function. null is always falsy, a function is always truthy.
To remove your element, you'll either have to look at this or e.target where e is the click event, and then call the DOM method node.removeChild(child).
The "quick and dirty" solution is to pass this into removeEl and remove it that way,
// ...
document.querySelector('.shit_to_do').innerHTML += '<div class="newItem" id="i' + iDN + '" onclick="removeEl(this)">' + taskName + '</div>';
// ...
function removeEl(elm) {
elm.parentNode.removeChild(elm);
}
I also removed the strange spacing between attribute names and values in your HTML
A perhaps "cleaner" solution is to create your nodes and attach listeners all by using DOM methods
function createDiv(index, taskname) {
var d = document.createElement('div');
d.setAttribute('id', 'i' + index);
d.textContent = taskname;
return d;
}
function removeElm() {
this.parentNode.removeChild(this);
}
var iDN = 0;
document.getElementById('add_button').addEventListener('click', function () {
var taskName = document.getElementById('add_task').value,
list = querySelector('.shit_to_do'),
div = createDiv(iDN, taskName);
div.addEventListener('click', removeElm);
list.appendChild(div);
iDN += 1;
});
This way means the browser does not re-parse any HTML as it not use element.innerHTML, which is a dangerous property may destroy references etc (along with usually being a bit slower)
Helpful links
node.addEventListener
document.createElement
node.appendChild

Content disappears after user finishes entering groceries

Happy new year, everyone! I'm celebrating by working on learning jquery. I added some jQuery to my code below and managed to add some content and change some css with it. The getGroceries function is working fine and is doing what it's supposed to do. When the user finishes entering the groceries, the program (printGroceries) is supposed to print the list that the user entered. That portion is also working.... HOWEVER, when that happens, the program removes the header (My grocery list) and removes all styling.
What am I doing wrong?
EDITED CODE: Deleted full code and added the portion that I changed (commented the old).
function printGroceries(groceryItems) {
if (groceryItems.length > 1) {
$('grocery-list').html('<ol class="items" id="list-items">');
//document.write("<ol>");
for(x=0; x < groceryItems.length;x++){
groceryItems;
$('#list-items').prepend('<li>' + groceryItems[x] + '</li>');
//document.write("<li>" + groceryItems[x] + '</li>');
}
$('#grocery-list').append('</ol>');
//document.write("</ol>");
} else {
$('#grocery-list').prepend('<p>Sorry, your list is empty.</p>');
//document.write('<p>Sorry, your list is empty.</p>');
}
}
Problem: fiddle
Try this
function printGroceries(groceryItems) {
if (groceryItems.length > 0) {
$('#grocery-list').html('<ol class="items" id="list-items">');
//document.write("<ol>");
for(x=0; x < groceryItems.length;x++){
groceryItems;
$('#list-items').prepend('<li>' + groceryItems[x] + '</li>');
//document.write("<li>" + groceryItems[x] + '</li>');
}
$('#grocery-list').append('</ol>');
//document.write("</ol>");
} else {
$('#grocery-list').prepend('<p>Sorry, your list is empty.</p>');
//document.write('<p>Sorry, your list is empty.</p>');
}
}
You have missed few things as I suggested in the comments
1. The if condition should check groceryItems.length > 0
2. $('grocery-list') should be $('#grocery-list'), you are missing the id selector here
Solution: fiddle
Since you're using jQuery; here's a version that takes advantage of $.each(). Also, it's best to build out your string and append only once rather that append each item over and over.
function printGroceries(groceryItems) {
var listItems = '';
if (groceryItems.length > 0) {
$.each(groceryItems, function (i, item) {
listItems += '<li>' + item + '</li>';
});
$('#grocery-list').append('<ol class="items" id="list-items">'+listItems+'</ol>');
} else {
$('#grocery-list').prepend('<p>Sorry, your list is empty.</p>');
}
}

Filtering the list of friends extracted by Facebook graph api ( more of a JavaScript/Jquery question than Facebook API question)

Hello there JavaScript and Jquery gurus, I am getting and then displaying list of a facebook user's friend list by using the following code:
<script>
function getFriends(){
var theword = '/me/friends';
FB.api(theword, function(response) {
var divInfo = document.getElementById("divInfo");
var friends = response.data;
divInfo.innerHTML += '<h1 id="header">Friends/h1><ul id="list">';
for (var i = 0; i < friends.length; i++) {
divInfo.innerHTML += '<li>'+friends[i].name +'</li>';
}
divInfo.innerHTML += '</ul></div>';
});
}
</script>
graph friends
<div id = divInfo></div>
Now, in my Facebook integrated website, I would eventually like my users to choose their friends and send them gifts/facebook-punch them..or whatever. Therefore, I am trying to implement a simple Jquery filter using this piece of code that manipulates with the DOM
<script>
(function ($) {
// custom css expression for a case-insensitive contains()
jQuery.expr[':'].Contains = function(a,i,m){
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
};
function listFilter(header, list) { // header is any element, list is an unordered list
// create and add the filter form to the header
var form = $("<form>").attr({"class":"filterform","action":"#"}),
input = $("<input>").attr({"class":"filterinput","type":"text"});
$(form).append(input).appendTo(header);
$(input)
.change( function () {
var filter = $(this).val();
if(filter) {
// this finds all links in a list that contain the input,
// and hide the ones not containing the input while showing the ones that do
$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
$(list).find("a:Contains(" + filter + ")").parent().slideDown();
} else {
$(list).find("li").slideDown();
}
return false;
})
.keyup( function () {
// fire the above change event after every letter
$(this).change();
});
}
//ondomready
$(function () {
listFilter($("#header"), $("#list"));
});
}(jQuery));
</script>
Now, This piece of code works on normal unordered list, but when the list is rendered by JavaScript, it does not. I have a hunch that it has to do something with the innerHTML method. Also, I have tried putting the JQuery filter code within and also right before tag. Neither seemed to work.
If anyone knows how to resolve this issue, please help me out. Also, is there a better way to display the friends list from which users can choose from?
The problem is here:
$(list).find("a:not(:Contains(" + filter + "))").parent().slideUp();
$(list).find("a:Contains(" + filter + ")").parent().slideDown();
Since you're rendering this:
divInfo.innerHTML += '<li>'+friends[i].name +'</li>';
There is no anchor wrapper, the text is directly in the <li> so change the first two lines to look in those elements accordingly, like this:
$(list).find("li:not(:Contains(" + filter + "))").slideUp();
$(list).find("li:Contains(" + filter + ")").slideDown();
You could also make that whole section a bit faster by running your Contains() code only once, making a big pact for long lists, like this:
$(input).bind("change keyup", function () {
var filter = $(this).val();
if(filter) {
var matches = $(list).find("li:Contains(" + filter + ")").slideDown();
$(list).find("li").not(matches).slideUp();
} else {
$(list).find("li").slideDown();
}
});
And to resolve those potential (likely really) innerHTML issues, build your structure by using the DOM, like this:
function getFriends(){
var theword = '/me/friends';
FB.api(theword, function(response) {
var divInfo = $("#divInfo"), friends = response.data;
divInfo.append('<h1 id="header">Friends/h1>');
var list = $('<ul id="list" />');
for (var i = 0; i < friends.length; i++) {
$('<li />', { text: friends[i].name }).appendTo(list);
}
divInfo.append(list);
});
}
By doing it this way you're building your content all at once, the <ul> being a document fragment, then one insertion....this is also better for performance for 2 reasons. 1) You're currently adding invalid HTML with the .innerHTML calls...you should never have an unclosed element at any point, and 2) you're doing 2 DOM manipulations (1 for the header, 1 for the list) after the much faster document fragment creation, not repeated .innerHTML changes.

Categories

Resources