javascript dynamic function call undefined - javascript

The function savefromtextarea() & varialbe globe is undefined wen called on click of save button...
This one part of my code...I need to access the save from texarea method when clicked on the save text button...when I try to invoke the saveFromTextArea method its throws globe is undefined but globe variable is global variable ...
ME.ZFP.annotaion.Text = function () { //function to annotate the text
var canvas = myscreen.getTempCanvas().ele;
var context = canvas[0].getContext('2d');
var global = this;
$(canvas).mousedown(function(e){ //on mouse down event
if ($('#textAreaPopUp').length === 0) {
var mouseX = e.pageX - this.offsetLeft + $(canvas).position().left;
var mouseY = e.pageY - this.offsetTop;
//append a text area box to the canvas where the user clicked to enter in a comment
var textArea = "<div id='textAreaPopUp' style='position:absolute;top:"+mouseY+"px;left:"+mouseX+"px;z-index:30;'><input type='text' id='textareaTest' ></input>";
//Click on save buttom global.saveTextFromArea undefined
var saveButton = "<input type='button' value='save' id='saveText' onclick='global.saveTextFromArea("+mouseY+","+mouseX+");'></div>";
var appendString = textArea + saveButton;
$("#container").append(appendString);
}
});
//Function to be called
this.saveTextFromArea = function(y,x){
//get the value of the textarea then destroy it and the save button
var text = $('textarea#textareaTest').val();
$('textarea#textareaTest').remove();
$('#saveText').remove();
$('#textAreaPopUp').remove();
}
}
Thanks
Ajain

An inline event handler like your onclick='...' can only reference globally scoped variables and functions, but if your variable named global is declared inside a function (inside a document.ready handler, for example) then it is not global and the inline attribute event handler can't see it.

Well your code has some errors, fixed in this fiddle.
You forgot }); at the very end of the code.
Lastly (nitpicking) I corrected:
if ($('#textAreaPopUp').length == 0) to
if ($('#textAreaPopUp').length === 0)
But.. does this corrected code fix your problem?

Related

jQuery - Detect TD ID on click

I'm trying to get a TD ID when I'm clicking on a table's row.
I've searched for ways to realize this, and found a way. But everytime I'm clicking, an alert pops up but it's an empty text. Using the console I saw that's the error code is "undefined".
Here's my code :
function chooseCell() {
let square = 0;
let squareNumber = 0;
$("td").click((e) => {
let data = $(this).attr('id');
alert (data);
for (square in squarePositions) {
squareNumber += 1;
if (square[1] <= e.pageX <= square[3] && square[0] <= e.pageY <= square[2]) {
alert(squareNumber);
alert("Square Number : " + squareNumber);
}
}
}
)}
If I replace the alert(data) by :
alert($('td').attr('id'));
The alert pops up the first table's TD. Whenever I click on a different TD, the first ID is displayed
Does someone know how to display the current clicked id ? There were no answers for my problem on Google and SOF
Thank you very much, best regards.
You are using an arrow function for your event handler.
An arrow function does not newly define its own this when it's being
executed in the global context; instead, the this value of the
enclosing execution context is used, equivalent to treating this as
closure value.
$("td").click((e) => {
let data = $(this).attr('id');
alert (data);
// ...
});
Hence in your code this doesn't refer to the td as you expect it to.
You can use the event.target to access the td with the following code
let data = $(e.target).attr('id');
Or you can also use a regular function instead of the arrow function and now this would refer td
$("td").click(function(e){
let data = $(this).attr('id');
alert (data);
// ...
});

Create a child div accordingly if another child already exists at that location (x,y)

I am inserting a textarea to a side bar (exactly on the right to), wherever a click is made on the page. The code is:
$('#page_to_be_clicked').click(function(e){
var offset = $(this).offset();
var comment_box_y_coord = e.pageY - offset.top;
alert(comment_box_y_coord);
$("#sidebar").append('<textarea id="cmmnt" rows="4" cols="10" '+
'style="position:absolute;top:'+comment_box_y_coord +
'px;left:5px"></textarea>');
})
The problem with this is that, if a textarea is already present at the location, it will overlap the existing, i.e. if a click is made twice at the same point on the page, then two textareas are created on top of each other. Instead, it should be created one below the other.
Is there a way to check, if a child already exists at the required co-ordinates?
Any help will be appreciated. Thanks.
How exactly should the textareas appear on clicks in a sequence:
This needs to be tested properly, but I think you need to do this:
DEMO
In your function change this line:
var comment_box_y_coord = checkCoords(e.pageY - offset.top);
and then add this function:
function checkCoords(y) {
if ($("textarea").length>0) {
$ts = $("textarea");
for (var i = 0; i<$ts.length;i++) {
var $ti = $ts.eq(i),
tcoords = [$ti.offset().top, $ti.offset().top+$ti.height()]
if (y>=tcoords[0] && y <= tcoords[1]) {
y = tcoords[1]+3;
}
}
}
return y;
}

getting JavaScript client side divs to spawn inside of a parent div container

so i've written some JS code that creates new div's every few milliseconds and stacks them up. but I want this script to happen inside the space of a DIV. so far the script runs outside of any div container.
is document.getElementById("parent-div").innerHTML=scriptFunction(); the right solution?
<script>
//where to begin.
//wrap code in functions and load them up via an DOM event handler.
//aim is too eliminate the function when the array collects 30 elements/data types.
var collect = []; //this array has global scope. because it's..
//been declared using var outside of a function.
window.onload = function(){
var holder = function(){
var invent = function(){
//var create = document.createElement("div").setAttribute("id","posts");
var d = document.createElement("div");
d.style.width="350px";
d.style.height="100px";
d.style.border="1px solid #333";
d.style.cssFloat="left";
var random = Math.random();
i = 1;
collect.push(i);
var content = ["Bogus",
"<p>lala haha</p>", "<p>sooooooooooooooooooooooooooooooo</p>", "<P> foxy lady sinks into the bed</P>" ];
d.innerHTML = collect.length + content[collect.length];
document.body.appendChild(d); //appendChild?
if(collect.length == 5){
alert("ahhhh 30"); //could trigger a new function.
}
}; //end of invent.
setInterval(invent,200);
}; //end of holder function.
//ok now i want this script to happen inside the "roll-out" div so i've tried this:
document.getElementById("roll-out").innerHTML=holder();
};
</script>
Try changing
document.body.appendChild(d); //appendChild?
to something like
document.getElementById("parent-div").appendChild(d);

Using this within functions called with onclick event in Javascript

I'm currently building a small Todo list application using vanilla Javascript but I'm having some issues creating a delete button that onClick removes it's parent element.
From what I have read, when an onClick is called in Javascript the this keyword can be used to refer to the element that called the function. With this in mind I have the following code:
window.onload = initialiseTodo;
function addRecord(){
var title = document.getElementById('issueTitle');
var issueContent = document.getElementById('issueContent');
var contentArea = document.getElementById('contentArea');
if(title.value.length > 0 && issueContent.value.length > 0){
var newItem = document.createElement('div');
newItem.id = 'task' + count++;
newItem.className = 'task';
newItem.innerHTML = '<div class="taskbody"><h1>' + title.value + '</h1>'+ issueContent.value + '</div><div class="deleteContainer">'
+ '<a class="delete">DELETE</a></div>';
contentArea.appendChild(newItem);
assignDeleteOnclick();
}
}
function deleteRecord(){
this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
deleteArray[i].onclick= deleteRecord();
}
}
function initialiseTodo(){
var btn_addRecord = document.getElementById('addRecord');
btn_addRecord.onclick = addRecord;
}
Basically I have a form that has two fields. When these fields are filled and the addRecord button is clicked a new div is added at the bottom of the page. This div contains a delete button. After the creation of this I assign an onclick event to the delete button which assigns the deleteRecord function when the delete button is clicked. My issue is with the deleteRecord function. I have used this to refer to the calling element (the delete button) and wish to remove the task div that is the outermost container however I current get a message that says: 'Cannot read property 'parentNode' of undefined ' which suggests to me the this keyword is not working correctly.
Any help would be greatly appreciated.
I've added the full code to a fiddle.
http://jsfiddle.net/jezzipin/Bd8AR/
J
You need to provide the element itself as a parameter. I did so by changing the html to include onclick="deleteRecord(this)" to make it a little easier to deal with. This means you can remove the assignDeleteOnclick() function
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
Demo
You might style the .content to be hidden better if there are no elements to prevent that extra white space
Edit
Since you don't want an inline onclick, you can do it with js the same:
function deleteRecord(elem){
elem.parentNode.parentNode.remove();
}
function assignDeleteOnclick(){
var deleteArray = document.getElementsByClassName('delete');
for(var i=0;i<deleteArray.length;i++){
// Has to be enveloped in a function() { } or else context is lost
deleteArray[i].onclick=function() { deleteRecord(this); }
}
}
Demo

JavaScript, using a function to change the text displayed in a HTML <p> tag

I have a HTML5 canvas, which is displaying a number of images and a paragraph of text on the page underneath the canvas. I want the text in the paragraph to be updated to display a different element from a JS array depending on which image the user clicks on.
Currently, I have a 'mousedown' function that looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
var id = shape.id;
selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
I tried using the line var id = shape.id to update the ID that's being passed to the function, so that it will get the correct element from my 'tips' array, but for some reason, when I view the page in the browser, and click on an image, the text beneath the canvas is not updated. It seems that this function is not updating the 'id' variable to the ID of whichever image has been clicked.
After looking into this, it seems to me that I will want to use a loop inside the 'mousedown' function, that will take the 'id' of the image on which the click has been detected, and loop through my 'sources' array (which is where all of the images have been loaded from the HTML into the JS), checking at each position whether the image stored at that location has the same ID as that of the image that has been clicked on. If it does, the loop should set the text to the text stored at that position of the array, and if not, it should continue looking through the array until it find it. Would this make sense? I tried adding the following code to the 'mousedown' function, but it doesn't change the text as I expected:
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
Is there something I'm missing from the loop?
The code for the whole function currently looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
/*This line needs to get the element of the sources array that has been selected,
and then select the element at the same position from the tips array.*/
//var id = null;
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
//var id =
//selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
Edit 11/01/2013 # 16:10
The code for selectTip is:
function selectTip(id){
$("#tipsParagraph").text(tips[id]);
}
and I've put a jsFiddle up here: http://jsfiddle.net/cd8G7/ although the 'result' panel is not showing what I actually see when I view the page in my browser- I get the canvas with all of the images displayed, and the paragraph underneath the canvas shows the text from the first element of my 'tips' array.
Edit 23/01/2013 # 13:50
Here's my isClickOnImage function:
function isClickOnImage(event){
var clickX = event.clientX;
var clickY = event.clientY;
//var imageCheckIteration = 0;
while(imageCheckIteration < sources.length){
if((clickX > sources[imageCheckIteration].x && clickX < sources[imageCheckIteration].x + imageWidth) &&
(clickY > sources[imageCheckIteration].y && clickY < sources[imageCheckIteration].y + imageHeight)){
/*This is where I need to print the variable that holds the text I want to display, but I need to display its contents
outside the canvas, in the <p></p> tags below. */
console.log("Click on image detected");
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip /*tips[imageCheckIteration]*/;
} else {
document.getElementById("tipsParagraph").innerHTML = "";
}
}
}
What I intended that this function do is, capture the X & Y coordinates of any click on the canvas, and store them in the variables "clickX" and "clickY". Then, I have a variable called "imageCheckIteration" that has been initialised to 0, and while this variable is less than the length of my "sources" array (which is the array where all of the images have been stored), the function should check whether the click was on an area of the canvas that is covered by one of the images in the array.
If it was, then a console log should display the message "click on image detected", and the line
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip;
should set the value of the "tipsParagraph" to be the value of the 'data-tip' attribute of whichever image is at the 'imageCheckIteration' position of the 'sources' array. If the click was detected on an area of the canvas that does not have an image displayed, then the value of the "tipsParagraph" should be set to hold nothing.
However, for some reason, when I view the page in the browser, the 'tipsParagraph' displays the text "This is where the text will be displayed", which is its default value, so that's fine. But, when I click on an image, or click anywhere else on the canvas, the text displayed in the 'tipsParagraph' is not updated.
I can't figure out why this is- can someone point me in the right direction? Does it mean that my isClickOnImage(event) function is never being called?
I simplified the way you are getting a reference to an image through the canvas. The trick here is to swap the z-index of the canvas and the image container and grab the reference to the image on the mouse up event. I don't know of a clean way to get elements behind a canvas, hence the workaround.
$('canvas').bind('mousedown', function(e) {
$('section').css('z-index', 4);
});
$('img').bind('mouseup', function(e) {
$('#tipsParagraph').text($(this).attr('id') + ":" + $(this).attr('alt'));
$('section').css('z-index', 2);
});
The second portion here is grabbing some attributes from the image itself and updating the text inside your div.
You can see more of the solution here.

Categories