How to access a vue function from onclick in javascript? - javascript

I am building a vue component and I want to call a function defined in Vue methods by calling the onClick attribute when modifying innerHTML. However, it gives me error, "showModal is not defined" as shown below.
Here is my showModal function, I am just trying to console some data to make sure that the function is called:
methods: {
showModal: function() {
console.log("function is called")
//this.$refs.myModalRef.show();
//this.account=account;
}
}
and here is where i am trying to call that function in js by onclick function:
var inputText = document.getElementById("fileContents");
var innerHTML = inputText.innerHTML;
for(var i=0;i<this.violations.length;i++){
var index=innerHTML.indexOf(this.violations[i]);
if(index>0) {
innerHTML = innerHTML.substring(0, index) +"" + innerHTML.substring(index, index + this.violations[i].length) + "</span>" + "" + innerHTML.substring(index + this.violations[i].length);
inputText.innerHTML = innerHTML;
}
}
error: (index):1 Uncaught ReferenceError: showModal is not defined
at HTMLAnchorElement.onclick ((index):1)
Am I calling it in a wrong way?
Thanks!
Edit:
Thanks to #Ferrybig - I know I am able to call the function, however I have another problem; I want to pass the current word that I am changing its html to the funciton like this: onclick='myMethod(violations[i])' I tried setting this.violations array to be global like this:
window.violations=this.violations;
but again, (variable i) which is the index of current word in the array, is not global variable to be passed to 'myMethod' and it says (i is not defined). I cannot set i to global variable because it's an index incremented each time in the loop.
I thought about sending the current index of the tag I am editing to the function, 'myMethod', so I can track which tag I am in and its known by the html in the vue component but not sure how to do that..
Any other suggestions?

When using Vue templates, you get access to easy to use syntaxes that decrease programming time, and it is highly recommended that you start renderering your page using Vue instead.
In the case you are unable to use Vue for renderering your page, you can still use other bad techniques:
First, start by adding a created lifecycle method for created that moves a reference for your Vue method up to the global scope: created(){window.myMethod =this.myMethod;}
Since we then added the method to the global scope, you can just reference it using mymethod inside your vanilla onclick handler.
Note that the above workaround does not support multiple instances of your Vue component, but supporting this becomes way harder, and you should really use proper Vue components in that case.

Hi Just try to remove href='#' and instead add href="javascript:void(0)" along with #click="showModal"
This may help

You are not using a Vue handler in your call. Change onclick to #click
so:
#click="showModal"
or, alternatively,
v-on:click="showModal"

You have to use Vue syntax onClick like Method Event Handlers
So
innerHTML = innerHTML.substring(0, index) +"" + innerHTML.substring(index, index + this.violations[i].length) + "</span>" + "" + innerHTML.substring(index + this.violations[i].length);
need change to
innerHTML = innerHTML.substring(0, index) +""+ "<span style=\"background-color: yellow\">" + innerHTML.substring(index, index + this.violations[i].length) + "</span>" + "" + innerHTML.substring(index + this.violations[i].length);

Related

Using a variable as a classname

I am trying to put a class name stored in a variable into my JQuery where I want the class to be, this should change which class is affected depending on the parameter passed through the URL query string.
I have built the class name and stored it in the 'param' variable as below.
var param = '".' + "proj" + location.search.substring(6) + '"';
$(param).css('display', 'inline');
And want to change the css on the class inside of it but this does not seem to work for me. Perhaps because it tries to change the css of the variable rather than what is inside of it.
If not how can I solve this or if so, is there a better way I could go about this?
You're confusing a string literal to be only enclosed by double quotes ", while that is not the case. Remove them
var param = '.' + "proj" + location.search.substring(6);
Set the param variable as the location substring (assuming that this substring is correctly getting the desired result from your URL) - then use that in the jQuery by joining with the common portion as follows.
var param = location.search.substring(6);
$('.proj' + param).css('display', 'inline');
You will need to ensure that a) you have the jQuery library and b) you have the jquery code wrapped in a $(document).ready(function(){}) wrapper.
Also - its usually better to add / remove a class rather than directly affecting the CSS in the jquery
var param = location.search.substring(6);
$('.proj' + param).addClass('displayInline');
//CSS
.displayInline{display: inline}

dynamically generated js buttons with closures to assign onclick function parameters

I am running into a problem people have posted before: JavaScript dynamic parameters
But my code uses nodes rather than innerHTML assignments, so the existing SO post doesn't seem to apply to my code.
I want to dynamically generate HTML buttons in a table. For each button, I want to call a function with parameters that depend on the button's index/position in the table. First I tried just using lambda functions with the variable over which I was incrementing. This didn't work, so I also tried dynamically named variables, meaning each button should be passing a differently named variable to deal with lazy-loading effects. But this didn't work either. You can see both versions of what I tried in the code below:
This code I paste below is in a for-loop. In the following, I increase i by 1 each time. offset and jj are unchanged within the loop.
var variableDynamic = i.toString();
window['variableName' + variableDynamic] = i + offset;
upvote.onclick = function() {
upVoteA(i + offset, jj);
//upVoteA(window['variableName' + variableDynamic] , jj);
};
upvote.innerHTML = "Upvote"
Someone told me to look into closures, so following this recommendation: http://www.usepatterns.com/blog/javascript-closures I rewrote the onclick function declaration as:
upvote.onclick = function() {
var a = i + offset;
var b = kk;
function closeIt(){
upVoteA(a,b);
}
closeIt();
};
This still has the same effect that every button calls upVoteA with the same parameter, namely the last/highest value.
I realize I could refactor my code to turn these into .innerHTML set statements and then I'd print the variable and it would be set as a printed statement instead of a lazily-loaded variable. But I'd like not to do that if possible. (apologies that it's not technically lazy loading, the name seems reasonably apt)
Is there a way to make my code work? And why are the closures failing? I thought closures should preserve the environment they were created in, but that is not the case with my code. Which portion of the "environment" are preserved with closures?
This is a very bad answer, but it works
var funcStr = "function dummy() { upVoteA(" + (i + offset) + "," + jj + "); }";
eval(funcStr);
upvote.onclick = dummy;
But if you have something better, please let me know.

jQuery each - binding to all elements instead of single

Playing with some jQuery bits and pieces, I can't seem to get it quite right.
What I'm looking to do is loop through the items on a page, and apply a custom click handler to them. This way when I populate the page I just need to fill out the correct ID and the jQuery can automate filling in the link.
The problem I have is both events are firing with the same output, and I can't work out why. I have 2 which I am using as buttons,
<img id="LightButton11Of" src="images/lightbulb_off.png" style="width:32px;
height:32px; vertical-align:middle " alt="off" >
<img id="LightButton11On" src="images/lightbulb_on.png" style="width:32px;
height:32px; vertical-align:middle" alt="on">
and the following code
$(document).ready(function(){
$("[id^=LightButton]").each(function(i,item){
if ($(this).attr('id').substr(13,2)=="On"){lightfunction="1";}
if ($(this).attr('id').substr(13,2)=="Of"){lightfunction="0";}
alert($(this).attr('id').substr(13,2));
numLight = $(this).attr('id').substr(11,2);
strLight = "*1*" + lightfunction + "*" + numLight + "##";
teststr = $(item).attr('id') + " - " + strLight;
alert(teststr);
$(this).bind("click",function(){
SendEvent("OWN","18",strLight,"OK");
});
});
});
The alert(teststr) gives exactly the output I'm expecting, but it seems when I'm binding it is actually binding to all elements and not just the singular item from that iteration of the each loop.
What am I doing wrong!?
Cheers,
Tim.
What am I doing wrong!?
Your variables are all global.
This code in the click handler:
SendEvent("OWN","18",strLight,"OK");
...refers to the global variable strLight, which will have the value set in the last iteration of your .each() loop.
You should declare all of your variables with var, which will make them local to the function, so then each of the click handlers will use the local variable from its containing scope. (Which, thanks to the "magic" of closures, will still exist even though your each callback will have finished by the time the click events occur.)
$("[id^=LightButton]").each(function(i,item){
var lightfunction = this.id.substr(13,2)=="On" ? "1" : "0";
var numLight = this.id.substr(11,2);
var strLight = "*1*" + lightfunction + "*" + numLight + "##";
$(this).bind("click",function(){
SendEvent("OWN","18",strLight,"OK");
});
});
(Note also that there's no need to use $(this).attr('id') when this.id gives you the same value in a way that is faster to type, read and execute, and it's neater to set the value of lightfunction using a ternary operator instead of two if statements.)

Creating a JavaScript global array with static elements?

Creating a JavaScript global array with static elements?
The problem isn't that removeFunction doesn't have access to bigArray. The problem is in your onclick attribute, and the id you're putting on the link:
$('#div').append("<a href='#' id='bigArray[i]' onclick='removeFunction(bigArray[i])'>Element bigArray[i]</a><br />");
In the onclick, you're referring to i, but A) I'm guessing i isn't a global, and B) Even if it is, it will not have the value of i that you used to render that row. The code will look for the value of a global i variable as of when the link is clicked.
Separately, you're creating multiple elements with the same id value, which is bigArray[i] (not bigArray[0], bigArray[1], etc.)
You could use the value instead, like this:
$('#div').append("<a href='#' id='bigArray[" + i + "]' onclick='removeFunction(" + i + ")'>Element bigArray[i]</a><br />");
The changes there are:
For the id, I changed it to: "...id='bigArray[" + i + "]'", which will output id='bigArray[0]', then id='bigArray[1]', etc., instead of repeatedly outputting id='bigArray[i]' (literally.
I just pass the index into removeFunction, again by putting the value there, not a reference to the variable i: "... onclick='removeFunction(" + i + ")' ..."
Then your removeFunction would be:
function removeFunction(i) { // <== i, not id
bigArray.splice(i, 1); // <== real code, not pseudocode
renderArray(bigArray);
}
I would not recommend doing it that way, but it's the minimal fix.
There's no need to pass bigArray to anything. It's a global.
FWIW, I would recommend refactoring so you don't have to re-render the whole thing every time.
Define a variable at the global scope first that will hold your "bigArray", then assign the value to it once you receive the data through your ajax call.
var bigArray;
$.ajax({
bigArray = bigArrayFromAjax;
renderArray(bigArray);
});
... then your other functions should have access to it.

Calendar Class in Javascript - unable to keep the reference.

I wrote a datepicker in Javascript, but it is not working properly,
as I lose the reference to the Calendar object.
here is the example
http://asexpress.de/calendar/
by clicking within the input field the calendar will be displayed.
What should I do that the reference to the Calendar object remains in contact.
From what I can tell so far of your script, the following code block:
Kalender.prototype.writeMonth = function() {
var that = this;
contains some code further down:
else if ( this.isToday(displayNum, length) && this.isLink(displayNum, length) )
{
sbuffer.push('<td class="date" onClick="that.changeDate(this,\''
+ this.id + '\'); that.returnDate('+ this.month +','+ this.year+')">' + displayNum + '</td>');
}
This would cause a problem, since the that variable is declared within the scope of this function and the onclick event will fire outside of the scope. IMO, building the HTML isn't the best method here. It would be best to build the table cells using the DOM and add event handlers that are inside the scope of the function. This happens a few times.
FYI, you're using eval() rather unnecessarily in your code:
this.months = eval("config.language."+ this.options['language'] +".months");
// Can also be written as:
this.months = config.language[this.options['language']].months;
See Eval is Evil for more information.
Further Reading
MSDN - Building Tables Dynamically
MDC - Traversing an HTML table with JavaScript and DOM Interfaces
MDC - Working with Closures
You should declare the variable which holds datepicker object globally.
var kalender;
var kalender2;
function reisedate(d) {
document.getElementById("abc").value = d.getDate() + "/" + parseInt(d.getMonth()+1) + "/" + d.getFullYear();
}
// rest of the code
Take a look at first two lines.

Categories

Resources