Javascript - onclick - javascript

first time posting here, but god know's I use this site to search for problems all the time :P Well, I'm having a problem of my own now that I can't seem to figure out easily searching around Google, and after playing with it for about 2 hours, I've finally decided to post a question and see what you guys think.
What I'm trying to accomplish here is to have a button that appears over a div when you hover over it that, when clicked, opens an editing pane. The button appears over the div correctly, but for some reason I cannot seem to make the onclick function work to save my life lol. Here's the code I'm working with. If it's not enough, please let me know and I'll add a little more sauce. :P
function place_widget(name, properties){
//bbox
var pleft = properties[0];
var ptop = properties[1];
var width = properties[2];
var height = properties[3];
var pright = pleft + width;
var pbottom = pleft + height;
var bbox = [pleft, ptop, pright, pbottom];
boxes[name] = bbox;
//ID's
var id = 'widget_' + name;
var editspanid = id + "_editspan";
var editbuttonid = id + "_editbutton";
var editpaneid = id + "_editpane";
//Creating Elements
var div = "<div id='" + id + "' class='widget' onmouseover='widget_hover(event);' onmouseout='widget_out(event);'>";
var editbutton = "<a id='" + editbuttonid + "' href='#'><img onclick='toggleEdit;' src='../images/edit_button.png'></a>";
var editspan = "<span id='" + editspanid + "' class='editspan'>" + editbutton + "</span>";
var editpane = "<span id='" + editpaneid + "' class='editpane'>:)</span>";
div += editspan + editpane + "</div>";
body.innerHTML += div;
//Configuring Elements
var editspanelement = document.getElementById(editspanid);
var editbuttonelement = document.getElementById(editbuttonid);
editbuttonelement.onclick = alert; //Does nothing.
var editpaneelement = document.getElementById(editpaneid);
var mainelement = document.getElementById('widget_' + name);
mainelement.style.left = (pleft + leftmost) + "px";
mainelement.style.top = (ptop + topmost) + "px";
mainelement.style.width = width;
mainelement.style.height = height;
getContentsAJAX(name);
}
Sorry for the ugly code :P Anyone have any idea why the onclick function isn't working?
Also, a bit of extra info: If I open up firebug and put in :
document.getElementById('widget_Text_01_editbutton').onclick = alert;
When I click the button, I get:
uncaught exception: [Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "native frame :: <unknown filename> :: <TOP_LEVEL> :: line 0" data: no]
I'm not exactly sure what that means off hand.
Thanks!

Can you try changing:
<img onclick='toggleEdit;' src='../images/edit_button.png'>
to:
<img onclick='toggleEdit();' src='../images/edit_button.png'>
Also, is "alert" a function you wrote?

Start by changing this:
editbuttonelement.onclick = alert; //Does nothing.
to this:
editbuttonelement.onclick = function() {alert("Got a click");};
and then change this:
var editbutton = "<a id='" + editbuttonid + "' href='#'><img onclick='toggleEdit;' src='../images/edit_button.png'></a>";
to this:
var editbutton = "<a id='" + editbuttonid + "' href='#'><img onclick='toggleEdit();' src='../images/edit_button.png'></a>";
What you are clicking on? The image or the link or the span? Do you know which is getting the click event?

document.getElementById('widget_Text_01_editbutton').onclick = alert;
causes illegal invocation because it is trying to set this to something else (the element) than window inside alert.
alert.call( {} )
//TypeError: Illegal invocation
alert.bind( window ).call( {} )
//works
So either:
document.getElementById('widget_Text_01_editbutton').onclick = alert.bind( window );
or even better as the above will only work in some browsers:
document.getElementById('widget_Text_01_editbutton').onclick = function(){alert();};

It will help you in executing.
<img onclick='toggleEdit;' src='../images/edit_button.png'>

Related

Error on close button with onclick javascript, maybe around quotes/single/double

I have a small Issue Tracker which uses a couple of functions to save and fetch issues to localStorage, all of which works fine, using the Chance uid generator to generate ids. However on making a third function to set the status to closed after getting the id which was generated previously. In console I get an error as below.
(function(event){setStatusClosed(fdf7622a-8738-5384-98b6-9ff9c47b2be0)
}) invalid or unexpected token. index.html:1
It's using onclick to run the function via the close button generated in the fetchIssues() function.
The first 2 functions fetchIssues() and saveIssues() have been working as expected with no errors and correctly converting the array to JSON object on push and back to array on retrieve, but when I try the setStatusClosed function I get the error. I also get similar errors when using other uid generator methods so I decided to stick with Chance. I can't seem to find the error and the log just points me to the event as pasted above. The code is below
/*jslint browser:true */
//Fetch submitted issues or the status of localStorage
function fetchIssues() {
"use strict";
var i = 0;
var issues = JSON.parse(localStorage.getItem("issues"));
var issueList = document.querySelector('#issueList');
issueList.innerHTML = " ";
if(issues !== null) {
for(i = 0; i < issues.length; i++) {
var id = issues[i].id,
desc = issues[i].description,
severity = issues[i].severity,
assignedTo = issues[i].assignedTo,
status = issues[i].status;
issueList.innerHTML += "<div class='well'>" +
"<h6>Issue ID: " + id + "</h6>" +
"<p><span class='Label label-info'>" + status + "</span></p>" +
"<h3>" + desc + "</h3>" +
"<p><span class='glyphicon glyphicon-time'></span>" + severity + "</p>" +
"<p><span class='glyphicon glyphicon-user'></span>" + assignedTo + "</p>" +
"<a href='#' onclick='setStatusClosed("+ id +")' class='btn btn-warning'>Close</a>" +
"<a href='#' onclick='deleteIssue(" + id + ")' class='btn btn-danger'>Delete</a>" +
"</div>";
}
console.log(issues);
} else {
issueList.innerHTML = "<h6 class='text-center'>There are no issues at present</h6>";
}
}
//Save a submitted issue
function saveIssue(e) {
"use strict";
var chance = new Chance();
var issueDesc = document.querySelector("#issueDescInput").value,
issueSeverity = document.querySelector("#issueSeverityInput").value,
issueAssignedTo = document.querySelector("#issueAssignedToInput").value,
issueStatus = "Open",
issueId = chance.guid(),
issues = [],
issue = {
id: issueId,
description: issueDesc,
severity: issueSeverity,
assignedTo: issueAssignedTo,
status: issueStatus
};
//Check if entry already there
if(localStorage.getItem("issues") === null) {
//Push the issue object to issues array
issues.push(issue);
//Set the new issues array as a converted JSON object to localStorage
localStorage.setItem("issues", JSON.stringify(issues));
} else {
//Request the issues object and convert to array
issues = JSON.parse(localStorage.getItem("issues"));
//Push new object to issues array
issues.push(issue);
//Set the new issues array as a converted JSON object to localStorage
localStorage.setItem("issues", JSON.stringify(issues));
}
//Reset submit element
document.querySelector("#issueInputForm").reset();
//Run fetchIssue to reflect the new item
fetchIssues();
//Stop default submit
e.preventDefault();
}
//Submit event for the saveIssue function
document.querySelector("#issueInputForm").addEventListener("submit", saveIssue);
//Set the issue status to closed
function setStatusClosed(id) {
var i;
var issues = JSON.parse(localStorage.getItem("issues"));
for(i = 0; i < issues.length; i++) {
if(issues[i].id == id) {
issues.status = "Closed";
}
}
localStorage.setItem("issues", JSON.stringify(issues));
fetchIssues();
}
It all compiles fine in the Closure compiler
The error appears only when hitting the close issue button, so does anyone know why the function is not being properly called in the onclick event (generated via innerHTML method) ?
Any tips welcome, Thanks
Update, I have tried altering the call in the generated innerHTML to escape the quotes but now I get a slightly different error that setStatusClosed() is not defined for the onclick event.(Also I removed Bootstrap so its just using the lib js file.), so there seems to be an error with the onclick call.
issueList.innerHTML += '<div class="well">' +
'<h6>Issue ID: ' + id + '</h6>' +
'<p><span class="Label label-info">' + status + '</span></p>' +
'<h4>' + desc + '</h4>' +
'<p><span class="icon icon-clock"></span> ' + severity + '</p>' +
'<p><span class="icon icon-user"></span> ' + assignedTo + '</p>' +
'Close' +
'Delete' +
'</div>';

Getting "Uncaught SyntaxError: Unexpected token }

I have written a function which prints a certain area of the DOM which is triggered by a button click which is rendered via JavaScript. See the below code...
function MarkQuiz() {
var CorrectAnswers = 0,
TotalQuestions = 0,
CurrentQuestion = "",
Percentage = 0,
Output = "";
$("select").each(function(key,value) {
CurrentQuestion = "#" + $(value).attr("id");
TotalQuestions = key + 1;
if($(CurrentQuestion).val() == "Correct") {
CorrectAnswers++;
}
});
Percentage = (CorrectAnswers / TotalQuestions) * 100;
Output = "You Scored..." +
"<h1>"+Percentage+"%</h1>" +
"Which means you got " + CorrectAnswers + " out of " + TotalQuestions + " correct.<br/>" +
"<br/><a href='#' onclick='PrintCertificate('#QuizMainContent')' class='button' id='PrintCertificate'>Print your Certificate</a>";
$("#QuizMainContent").html(Output);
}
function PrintCertificate(DOMArea) {
var PrintArea = $(DOMArea),
PrintWindow = window.open('','');
PrintWindow.document.write($(PrintArea).html());
PrintWindow.document.close();
PrintWindow.focus();
PrintWindow.print();
PrintWindow.close();
}
However, when I click that button, I receive this error...
This is the URL to the project: http://historicalperiods.esy.es/
What I am doing wrong?
Thanks in Advance.
Print your Certificate
This is in your HTML. Which is what is causing the problem. As you can see, you open the attribute with ", then you use " in your javascript function, and you close the parameters in the function ', then you close the attribute with ', then you do ="" (which doesn't make sense).
The proper way it should be:
Print your Certificate
Thanks for the help...
I corrected this with a little modification to the answer provided by L Ja...
'<br/>Print your Certificate';

Creating and deleting divs using javascript

I have a few JavaScript functions designed to add and remove HTML divs to a larger div. The function init is the body's onload. New lines are added when an outside button calls NewLine(). Divs are removed when buttons inside said divs call DeleteLine(). There are a few problems with the code though: when I add a new line, the color values of all the other lines are cleared, and when deleting lines, the ids of the buttons, titles, and line boxes go out of sync. I've gone through it with the Chrome debugger a few times, but each time I fix something it seems to cause a new problem. I would greatly appreciate some input on what I'm doing wrong.
function init()
{
numOfLines = 0; //Keeps track of the number of lines the Artulator is displaying
}
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
LineBoxCode += "<div class = 'Line Box' id = 'LineBox" + numOfLines + "'>" //The code is only split onto multiple lines to look better
+ " <h6 id = 'Title " + numOfLines + "' class = 'Line Box Title'>Line " + numOfLines + "</h6>";
+ " <p>Color: <input type = 'color' value = '#000000'></p>"
+ " <input type = 'button' value = 'Delete Line' id = 'DeleteLine" + numOfLines + "' onclick = 'DeleteLine(" + numOfLines + ")'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
function DeleteLine(num)
{
deletedLineName = "LineBox" + num;
deletedLine = document.getElementById(deletedLineName);
deletedLine.parentNode.removeChild(deletedLine);
num++;
for ( ; num < numOfLines + 1 ; )
{
num++;
var newNum = num - 1;
var changedLineName = "LineBox" + num;
var changedHeaderName = "Title" + num;
var changedButtonName = "DeleteLine" + num;
var changedButtonOC = "DeleteLine(" + newNum + ")";
var changedLine = document.getElementById(changedLineName);
var changedHeader = document.getElementById(changedHeaderName);
var changedButton = document.getElementById(changedButtonName);
var changedLine.id = "LineBox" + newNum;
var changedHeader.innerHTML = "Line" + newNum;
var changedHeader.id = "Title" + newNum;
var changedButton.setAttribute("onclick",changedButtonOC);
var changedButton.id = "DeleteLine" + newNum;
}
num--;
numOfLines = num;
}
You are having a hard time debugging your code because of your approach. You are "marking" various elements with the IDs you construct, and using the IDs to find and address elements. That means that when things change, such as line being deleted, you have to go back and fix up the markings. Almost by definition, the complicated code you wrote to do something like that is going to have bugs. Even if you had great debugging skills, you'd spend some time working through those bugs.
Do not over-use IDs as a poor-man's way to identify DOM elements. Doing it that way requires constructing the ID when you create the element and constructing more IDs for the sub-elements. Then to find the element again, you have to construct another ID string and do getElementById. Instead, use JavaScript to manage the DOM. Instead of passing around IDs and parts of IDs like numbers, pass around the DOM elements themselves. In your case, you don't need IDs at all.
Let's start off with DeleteLine. Instead of passing it a number, pass it the element itself, which you can do my fixing the code inside your big DOM string to be as follows:
<input type='button' value='Delete Line' onclick="DeleteLine(this.parentNode)"/>
So we have no ID for the line element, no ID for the element, and no ID within the onclick handler. DeleteLine itself can now simply be
function DeleteLine(line) {
{
line.parentNode.removeChild(line);
renumberLines();
}
We'll show renumberLines later. There is no need to adjust IDs, rewrite existing elements, or anything else.
Since we no longer need the ID on each line or its sub-elements, the code to create each element becomes much simpler:
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
var LineBoxCode = "<div class='LineBox'>" +
+ " <h6 class='LineBoxTitle'>Line " + "numOfLines + "</h6>"
+ " <p>Color: <input type='color' value='#000000'></p>"
+ " <input type='button' value='Delete Line' onclick= 'DeleteLine(this.parentNode)'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
The only remaining work is to fix up the titles to show the correct numbers. You can do this by just looping through the lines, as in
function renumberLines() {
var LineBoxHolder = document.getElementById("LineBoxHolder");
var lines = LineBoxHolder.childElements;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var h6 = line.querySelector('h6');
h6.textContent= "Line " + (i+1);
}
}
I voted to close because the question is too broad, but will answer anyway on a few points to... well, point in the right direction.
var changedButton.setAttribute("onclick",changedButtonOC); This is not a variable declaration. Omit the var.
for ( ; num < numOfLines + 1 ; ) { num++; ... The correct form here would be simply for (; num < numOfLines + 1; num++) { ....
Instead of incrementing (num++) then decrementing (num--) around the loop, why not just use the right math?
See:
for (; num < numOfLines; num++) {
...
}

Javascript style using getBoundingClientRect not working

Hi I am trying to use getBoundingClientRect javascript function but the problem is this only seems to work for 1 of my elements. Here is the code.
function getDataXML(getID, cellId) {
var divMain = document.getElementById('Main');
var divCell = document.getElementById(cellId);
var divHoverControl = document.getElementById(getID);
var rectMain = divHoverControl.getBoundingClientRect();
var rectCell = divCell.getBoundingClientRect();
var divWidth = divHoverControl.offsetWidth;
var cellWidth = divCell.offsetWidth;
alert(rectMain.left + " " + rectMain.right + " " + divWidth + " " + cellWidth);
}
Its seems as though the page gets the elements using there ID correctly as I get no error and setting some style attributes works for each element but I only seem to get a result for my rectCell and cellWidth variables but the exact same code for rectMain and DivWidth dont seem to work. Any help would be greatly appreciated.

dynamic variable setting <href> into Ajax

Hi All i have a quick question about JSON data into href for AJAX
I have JSON coming into AJAX example data[i].listingid
How do i put that into a href inside the ajax?
Below are my codes, it will explain the situation more clearly.
Thanks for your time
<script>
$.ajax({
type: "GET",
url: "listing.php",
dataType: 'json',
success: function (data) {
for (var i = 0; i < data.length; i++) {
console.log(data)
var listingid = data[i].listingid;
var myOtherUrl =
"SpecificListing.html?Listingid=" + encodeURIComponent(listingid);
var html1 = "<div class=two> Listing Address : " + data[i].address + "<a href=myOtherurl>" +
data[i].listingid + "Click to view the details" + "</div>" +
"</a>"
$('#display12').append(html1);
}
}
});
</script>
You can straightly add it with concatenation like below :
var html1 = "<div class=two> Listing Address : " + data[i].address +
"<a href='"+ myOtherurl + "'>"+
data[i].listingid+"Click to view the details" + "</a></div>";
or else you can use jquery attr method after you finish with appending html to div like below:
var listingid = data[i].listingid;
var myOtherUrl = "SpecificListing.html?Listingid=" + encodeURIComponent(listingid);
var html1 = "<div class=two> Listing Address : " + data[i].address +
"<a id='hrefholder' >"+
data[i].listingid+"Click to view the details" + "</a></div>";
$('#display12').append(html1);
$('#hrefholder').attr("href",myOtherurl );
Tip : Don't forget to add id to anchor tag
Here's a cleaned up version of your callback (I try to avoid string concatenation for HTML as much as possible):
var successCallback = function(data) {
var baseUrl = 'SpecificListing.html?Listingid=';
for (var i=0; i<data.length; i++) {
var listingId = data[i].listingid;
var newUrl = baseUrl + encodeURIComponent(listingId);
var $newDiv = $('<div />').addClass('two');
var $newLink = $('<a />')
.attr('href', newUrl)
.text(listingId + ': Click to view details');
$newDiv.append($newLink);
$('#display12').append($newDiv);
}
};
Find a full working implementation including simulated AJAX call here:
http://jsfiddle.net/klenwell/N2k8X/
var html1 = "<div class=two> Listing Address : " + data[i].address + "<a href=myOtherurl>" + data[i].listingid+"Click to view the details" + "</a></div>";
Will work. Are u binding ajax event to this link?
Anjith and Orion are both right but ya'll have a typo:
the variable in your definition is called myOtherUrl but inside your concatenated string it is myOtherurl. Variables are case-sensitive.
your variable will be parsed as a variable if you leave your double quotes around it so it's good as is

Categories