Add anchor point to headers? - javascript

I have a really big html-document consisting of a number of <h4> headers accompanied by a short <p> 'body'.
I need to add an anchor point (is it the correct term, btw?) to each of the headers.
I'm iterating over the headers, and adding them to a menu-ul:
headz = document.getElementsByTagName("h4");
arrayOfHeaders=[];
x = 0;
y = headz.length;
$("#menu").html("<ul>")
while (x<y){
arrayOfHeaders[x] = "<li><a href='#" + x +"'>" + headz[x].innerText + "</a></li>";
$("#menu").append(arrayOfHeaders[x])
x++;
}
$("#menu").append("</ul>")
I need a way to attach the anchor points to the headers.
Edit: To clarify - what i need is the add a name-tag to each of the -elements.
The first header should be edited from '<h4>' header'</h4>' to '<h4 name="0">'...
Without editing the html, of course.

Set ids to the if they do not have one.
headz = document.getElementsByTagName("h4");
arrayOfHeaders=[];
x = 0;
y = headz.length;
var str = "<ul>";
while (x<y){
var elem = headz[x];
var id = elem.id || "heading_" + x;
elem.id = id;
str += "<li><a href='#" + id +"'>" + elem.innerText + "</a></li>";
x++;
}
$("#menu").append( str + "</ul>");
and FYI innerText is not cross browser friendly.
jQuery solution
var str = "<ul>";
$("h4").each(
function(i){
var id = this.id || "header_" + i;
this.id=id;
str += '<li>' + this.innerHTML + '</li>';
}
);
str += "</ul>";
$("#menu").append(str);

Since you used jquery already, thought id write it all in it:
var html = '<ul>';
$('h4').each(function (index, header) {
html += '<li>' + header.html() + '</li>';
});
html += '</ul>';
$('#menu').append(html);

This might solve your problem
headz = document.getElementsByTagName("h4");
arrayOfHeaders=[];
x = 0;
y = headz.length;
var html = "<ul>";
while (x<y){
html += "<li><a href='#" + headz[x].id +"'>" + headz[x].innerText + "</a></li>";
x++;
}
$("#meny").append( html + "</ul>")

This one is similar to rissicay's answer but I think it's more concise:
var html = []; // create an empty array to store iterated html in
// loop over every heading...
$('h4').each(function(index) {
// and add it to array previously created
html.push("<li><a href='#" + index +"'>" + $(this).html() + "</a></li>");
// add name attribute to heading
$(this).attr('name', index);
});
// finally, append all to menu together with unordered list
$('#menu').append('<ul>' + html.join() + '</ul>');
Basically, try to minimize dom manipulation (.append(), .prepend(), .html()) as much as possible

I think the concept you refer to is sometimes known as an "internal link" - see here under the second section "HTML Links - The id Attribute".
Now looking at your example code you are clearly using jQuery so why not make the most of it?
$("h4").each(function() {
$("#links").append("<a href='#" + this.id + "'>link to " + this.id + "</a><br /><br />");
});
See the following fiddle - http://jsfiddle.net/r0k3t/PhrB6/
Hope that helps.

Related

Building html output with a input checkbox with javascript

I'm building a string that will be place in a div pro grammatically. I am trying to call the onclick attribute of the input checkbox and having a little bit of trouble. I am trying to pass a unique value id with each checkbox click. The code below is what I'm using. See below for the problem:
var count = 1;
$.each(JSON.parse(data.d), function (k, v) {
var searchName = v.searchName;
resultString += "<div class='row form-group'>";
resultString += "<div class='col-sm-1 right-content'><input type='checkbox' onclick = 'authorCheckboxclick(this)' id='" + searchName + "'></div>";
resultString += "<div class='col-sm-11'>";
resultString += "<span>";
//resultString += v.text
resultString += count + ". " + v.text
resultString += "</span>";
resultString += "<br />";
resultString += "<span>";
//resultString += "Consectetur adipisicing, Consequatur, 2015.";
resultString += "</span>";
resultString += "</div>";
resultString += "</div>";
//resultString += "<br><br>";
count++;
});
In the authorCheckboxclick function if I put var answerid = $(this).attr('id'); I get undefined.
function authorCheckboxclick(elem) {
var answerid = $(this).attr('id');
alert(answerid); //I get undefined
var answerid = $(this).attr(elem.id);
alert(answerid); //I get undefined
var answerid = $(this).attr(elem.id);
alert(answerid); //I get undefined
var searchTerm = elem.id;
alert(searchTerm); //I get proper value
searchTerm = searchTerm.substring(0, 3);
alert(searchTerm); //I get proper value
var answerid = $(this).attr(elem.id);
alert(answerid); //I get undefined
var search = searchTerm.toUpperCase();
var array = jQuery.grep(dataMembers, function (value) {
return value.toUpperCase().indexOf(search) >= 0;
});
Is there a reason my jQuery call is not working and my JavaScript is? Is there a best practice to send the id value to a junction? Am I mixing Apples with Orange? Which method show be faster?
The immediate solution to your problem is that you're using the this keyword in your function. As you are calling the function from an on* attribute the scope of the function will be the window, not the element that raised the event. To fix this, simply use the element you provide in the parameter, ie. $(elem) instead of $(this).
A better solution entirely would be to use an unobtrusive delegated event handler which can utilise the this keyword as you're attempting to. It also has the benefits of leaving cleaner HTML code and being a better separation of concerns. Try this:
var count = 1;
$.each(JSON.parse(data.d), function(k, v) {
var searchName = v.searchName;
resultString += '<div class="row form-group">' +
'<div class="col-sm-1 right-content"><input type="checkbox" id="' + searchName + '"></div>' +
'<div class="col-sm-11">' +
'<span>' + count + ". " + v.text + '</span><br />' +
'<span></span>' +
'</div>' +
'</div>';
count++;
});
$(document).on('change', '.row :checkbox', function() {
var answerid = this.id;
var search = searchTerm.toUpperCase();
var array = jQuery.grep(dataMembers, function(value) {
return value.toUpperCase().indexOf(search) >= 0;
});
});

this.id is not working to detect which link is clicked in href

I am new to javascript and I am creating a bookstore using the google API. I have a small issue which I couldn't figure out. In the below piece of code that I saw from example code of google api bookstore function, I am trying to create href for the title of the book and pass its selfLink to the destination page i.e book-description.html.
When I put alert(this.id) on onclick It works, but for a normal method get(this) it does not work. I do not need an alertbox I want to take the id of the link clicked in href and pass it to another html.
handleResponse(response) {
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var a = item.volumeInfo.title;
var selfL = item.selfLink;
//var b = a.link("book-description.html");
var image = item.volumeInfo.imageLinks.smallThumbnail;
document.getElementById("content").innerHTML += "</br>" + "</br>" + "<br>" + "<img src =" + "'" + image + "'" + " class='im'/>";
document.getElementById("content").innerHTML += "<h4 class='right'>" + "<a href = 'book-description.html'id = " + "'" + selfL + "'" +
"onclick ='get(this);'>" + a + "</a></h4>";
function get(e) {
var link = e.id;
localStorage.setItem("Link", link);
}
document.getElementById("content").innerHTML += "<h4 class='right'>" + "AUTHOR:" + item.volumeInfo.authors + "</h4>";
document.getElementById("content").innerHTML += "<h5 class='right'>" + "PUBLISHER:" + item.volumeInfo.publisher + "</h5>";
var rating = item.volumeInfo.averageRating;
if (rating) {
document.getElementById("content").innerHTML += "<h5 class='right' id='rating'>" + rating + "</h5>";
} else {
document.getElementById("content").innerHTML += "<h5 class = 'right' id ='rating'>Not Rated Yet</h5>";
}
//document.getElementById("content").innerHTML += "<br>" + "<br>" + "<br>" + item.volumeInfo.publisheddate;
}
}
There are a number of problems with your code, but specifically in answer to your question; your function get is scoped so it is only available within the function handleResponse. For it to be accessible from an onclick it must be in page scope.
Simply move this
function get(e) {
var link = e.id;
localStorage.setItem("Link", link);
}
Into the head of your page
In programming there is the concept of DRY (Don't repeat yourself). So store a reference to document.getElementById("content") and reuse that variable.
var content = document.getElementById("content");
content.innerHTML = ...
You're missing some spaces in your output html. This may work in some browsers, others will struggle
<a href = 'book-description.html'id=
Should have a space between the end of one attribute and the start of another
<a href='book-description.html' id=
And for heaven sake, sort out the concatenation of your strings. You dont need a + if its just a simple string
document.getElementById("content").innerHTML += "</br>" + "</br>";
should be
document.getElementById("content").innerHTML += "</br></br>";

Removing objects from an array onclick

I have a an array of items which holds item objects. I want to create a function that when I click on a certain item it is removed from the array. I know I need to use something like splice and I have implemented the following solution but it does the seem to work.
Can anyone tell me what am I doing wrong.
function updateView() {
for (var i = 0; i < storeItems.length; i++) {
output += "<a href='#' id='itemTitle' onclick='removeRecord(" + i + ");'>"
+ storeItems[i].title + " " + "\n" + "</a>";
}
function removeRecord(i) {
storeItems.splice(i, 1);
var newItem = "";
// re-display the records from storeItems.
for (var i = 0; i < storeItems.length; i++) {
newItem += "<a href='#' onclick='removeRecord(" + i + ");'>X</a> "
+ storeItems[i] + " <br>";
};
document.getElementById('foods').innerHTML = newItem;
}
I think this the error is in the line below:
output += "<a href='#' id='itemTitle' onclick='removeRecord(" + i + ");'>" + storeItems[i].title + " " + "\n" + "</a>";
Because it does not recognise the "onclick" event even when I try to do a test with a simple alert.
Can anyone tell me what am I doing wrong. Also if you think you need more information to answer this question please let me know.
Thank you in advance.
Try ...
storeItems = storeItems.splice(i, 1);
WRONG: Basically, you have to assign the spliced array to something.
UODATE:
Here's the way I would do it ... tested in jsFiddle:
var storeItems = [{
title: "Dog"
}, {
title: "Cat"
}, {
title: "Bird"
}];
var foods = document.getElementById('foods');
foods.addEventListener('click', function(e) {
var index = e.target.getAttribute('value');
storeItems.splice(index, 1);
// re-display the records from storeItems.
updateView();
});
function updateView() {
var output = "";
for (var i = 0; i < storeItems.length; i++) {
output += "<a href='#' class='item' value='" + i + "'>" + storeItems[i].title + " " + "\n" + "</a>";
}
document.getElementById('foods').innerHTML = output;
}
updateView();
HTML:
<div id='foods'></div>
This effectively takes the onclick event off of the anchor tag (you could have them on any type of tag at this point) and I also reused your updateView code in the Listener so that it only needs maintained in one location.

Loop through object and order sub values

First of all:
I created a forum structure in MYSQL:
Table: [boards] -> id, parent_board, title, description
Simple and good.
This is the database response:
[{"id":1,"parent_board":0,"title":"Lorem 1","description":"ec40db959345153a9912"},
{"id":2,"parent_board":0,"title":"Lorem 2","description":"bb698136a211ebb1dfedb"},
{"id":3,"parent_board":1,"title":"Lorem 1-1","description":"6062bc28a9f781e06417d"}]
As you can see board id 3 is a sub-board of board id 1 since its parent_board value is set to 1.
I would like to receive the following output:
Lorem 1
Lorem 1-1
Lorem 2
But this is my result:
Lorem 1
Lorem 2
Lorem 1-1
How can I loop this object so that sub-board (board 3) will be below board 1?
I use the <ul> and <li> tags.
Here is my code:
var html = "</ul>";
for(var i = 0; i < boards.length; i++){
if(boards[i].parent_board == 0){
html += "<li>" + boards[i].title + "</li>";
}else{
html += "<ul>";
html += "<li>" + boards[i].title + "</li>";
html += "</ul>";
}
}
I would put an ID attribute on the <li> for each board. Then whenever I iterate through a sub-board, I just append the new items as children of the parent with the matching id, to do this, you would have to create and add each element to the document as you encounter them instead of storing them in a string first.
var htmlElem = document.getElementById('htmlElemId');
htmlElem.innerHTML = "";
for(var i = 0; i < boards.length; i++){
if(boards[i].parent_board == 0){
htmlElem.innerHTML += "<li id='" + boards[i].id + "'>" + boards[i].title + "</li>";
}else{
var parent = document.getElementById(boards[i].parent_board);
if (parent){
parent.innerHTML += "<ul><li id='" + boards[i].id + "'>" + boards[i].title + "</li></ul>";
}
}
}
Replace 'htmlElemId' with the actual id of your container element, and also make sure that it is of type <ul>.
EDIT: You may also want to consider using some kind of prefix in your ID, so you aren't just using plain numbers that could conflict with things elsewhere
"<li id='SomePrefix-" + boards[i].id + "'>" + boards[i].title + "</li>"
var parent = document.getElementById("SomePrefix-" + boards[i].parent_board);
EDIT2: Here is a JSFiddle

Removing row refresh page jquery

I am facing an issue with my jquery. I have used jQuery to add controls to table, along with a remove button to remove that particular row in table. here is my code on how i am creating controls in table.
HTML
<table id="controls" cellpadding="10" cellspacing="10">
</table>
<input id="btnAdd" type="button" value="Add" />
my jquery code looks like this
jquery
$(document).ready(function() {
$("#btnAdd").click(function() {
var field = $("#field").val();
var year = new Date().getFullYear()
var DDL_fromProfession = "<select name='ParametersFromProf' id='DDL_FromProYear'>";
for (var i = 1950; i <= year; i++) {
DDL_fromProfession += "<option text='" + i + "' value='" + i + "'>" + i + "</option>";
}
DDL_fromProfession += "</select>";
var DDL_ToProfession = "<select name='ParametersToProf' id='DDL_ToProYear'>";
for (var i = 1950; i <= year; i++) {
DDL_ToProfession += "<option text='" + i + "' value='" + i + "'>" + i + "</option>";
}
DDL_ToProfession += "</select>";
var newRow1 = "<tr><td align='center' style='font-size: large; color: #212121;' height='35px'>from"
+ DDL_fromProfession + " to " + DDL_ToProfession + "</td></tr>"
+ "<tr><td align='center' style='font-size:large;color:#212121;' height'35px'>"
+ "<input type='checkbox' name='chkbx_CurrPro' value='" + k + "'>I currently work here</input>";
newRow1 += "<br/><button id='btn_rmv'>Remove</button>";
var input = "<input name='parameters' id='field' type='text' />";
var input1 = "<input name='parametersCompany' id='field' type='text'/>"
//var inputCurrent="<input name='Current' id='Currfield' type='hidden'/>"
var newRow = "<tr><td align='center' style='font-size: x-large; color: #212121;' height='35px'>"
+ input + " at " + input1 + "</td></tr>";
$('#controls').append(newRow);
$('#controls').append(newRow1);
});
});
to remove last row i am using.
jquery
$(document).ready(function() {
$("#controls").delegate("#btn_rmv", "click", function() {
$(this).closest("tr").remove();
return false;
});
});
clicking on remove button refresh the page and remove all the rows that i have added instead of last one.
NOTE: What i ahve digged out is .delegate is server side and it refresh the page. i am unable to remove last row with $("#btn_rmv").click(function() on my page
Please point me to right direction.
Thanks in advance
The code in question does not work as k is not defined, as used in the line
value='" + k + "'
If this error is corrected then the next problem is that you are creating multiple elements with the same id, as seen here
newRow1 += "<br/><button id='btn_rmv'>Remove</button>";
which in invalid HTML and will cause problems for jQuery in finding the element with the unique id.
By changing k for 0 and changing the id to a class, the remove code will only remove the current row with the button on. I assume that you really want to remove that row and also the preceding 2 rows.
$('#controls').delegate('.btn_rmv', 'click', function() {
var index = $(this).closest('tr').index() + 1 // as nth-child is 1-based indexing
$('#controls tr:nth-child(n+' + (index - 2) + '):nth-child(-n+' + index + ')').remove(); // remove 3 rows
return false
});
See demo
Please note that since jQuery 1.7, .delegate() is superseded by .on() so the updated function is:
$('#controls').on('click', '.btn_rmv', function() {
var index = $(this).closest('tr').index() + 1
$('#controls tr:nth-child(n+' + (index - 2) + '):nth-child(-n+' + index + ')').remove();
return false
});
I had a similar experience: I was using Google Chrome and it would refresh the page everytime I called a function. You will have to return false. My problem was when I called a function from an element using "onclick". When I called the function from onclick I had to include the "return false;":
onclick="return false; functionName()"
Try this and see if it works:
$(document).ready(function() {
$("#btnAdd").click(function() {
/* YOUR CODE */
return false;
});
});
Or this and see if it works:
$(document).ready(function() {
$("#btnAdd").click(function() {
/* YOUR CODE */
});
return false;
});
Sorry my Javascript is not very good :(
You can do it in this way..
var RowCount = 0;
$(document).ready(function() {
$("#btnAdd").click(function() {
RowCount = RowCount + 1;
var newRow1 = "<tr id='tr" + RowCount + "'><td align='center' style='font-size: large; color: #212121;' height='35px'>from"
+ DDL_fromProfession + " to " + DDL_ToProfession + "</td></tr>"
+ "<tr><td align='center' style='font-size:large;color:#212121;' height'35px'>"
+ "<input type='checkbox' name='chkbx_CurrPro' value='" + k + "'>I currently work here</input>";
newRow1 += "<br/><button id='btn_rmv' onclick='RemoveRow(" + RowCount + ")'>Remove</button>";
});
});
function RemoveRow(RowID) {
$('#RemoveRow' + RowID).remove();
}
It looks like you are hooking up the remove click handler on $(document).ready.
On document.ready, the remove buttons do not yet exist (since they are generated dynamically when clicking 'Add', after the document.ready code has run). That's why $("#btn_rmv").click(function()... is not working.
So, after dynamically inserting a remove button in the $("#btnAdd").click event, you explicitly have to add a click handler to it.
EDIT:
If you generate your remove buttons with a unique id (eg. btn_rmv_1, btn_rmv_2, etc), you can add the following to your Add-handler (after appending the new button to the DOM):
$('#btn_rmv_1').click(removeButtonFunction);

Categories

Resources