How to inject some string and evaluate it in Vue? - javascript

in a SPA, using options API, how (where) to define a function that will be called from an html href?
In the following codepen for demo, everything works fine.
CODEPEN
However, on my Single Page:
<template>
<div v-html="my_div" />
</template>
<script>
/* function MyFunction() {
alert();
}; */
const MyFunction = () => {
alert();
};
/* Just for explanation, because the data comes from the database
export default {
data() {
return {
my_div:'link call function ',
}
}
*/
}
</script>
call the function return the error:
Uncaught ReferenceError: MyFunction is not defined
Apparently, the function is defined after the call
Any idea how to solve this?

Not sure what you're trying to do here but don't evaluate some random string coming from nowhere into a weird format. It will not work, will be clunky, non-debuggable.
If your codebase is legacy and has a lot of debt, refacto it or use jQuery or whatever to hack it even further.

Related

Overiding functions defined in an external script

I am trying to write some userscripts in JavaScript to be used with browser extensions.
In a website, I tried overriding a function defined in an external javascript, with Object.defineProperty. but it seems that this breaks the external script, because other codes in the external scripts (that are essential to the original website) seems to be not executing as well.
<html>
<head>
<!-- injected script, injected via Userscript -->
<script>
Object.defineProperty(window, 'originalFunction', { get: function() { return overridingFunction; } });
</script>
<!-- injection end -->
</head>
<body>
<script src="/external-javascript.js">
<script> originalFunction(); </script>
<script> anotherEssentialFunction(); </script>
</body>
</html>
and http://domain/external-javascript.js looks like this"
...
function originalFunction() {
some codes here;
}
...
function anotherEssentialFunction() {
....
}
and this was preventing anotherEssentialFunction from running. In the console, I see TypeError: can't redefine non-configurable property originalFunction and ReferenceError: anotherEssentialFunction is not defined
Is this expected in this situation, or there should be other problem causing it that is not described here? How can I safely override original function without causing such an error?
Object.defineProperty takes the name of a function as a parameter, so you'd have to do this instead:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
}
});
Or if that's all the getter does, simply:
window.originalFunction = overridingFunction;
But if the other functions need to call the original function, you can't really override it without breaking the functions that rely on its behavior. If you're just trying to execute custom code in addition to the original code, you can do this:
var origFn = window.originalFunction;
window.originalFunction = function () {
customFunction();
origFn.apply(this, [].slice.call(arguments));
};
Update:
Based on your comment, it sounds like you're wanting to not only override the original function but also prevent the external script from redefining that function. You can maybe add a no-op setter to avoid the external script from getting an error when trying to define it:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
},
set: function(ignored) { }
});

Cannot set property 'classRules' of undefined

am just don't know what happened it was work correctly .... What's most reasons that led us to this error ????
I was trying to run my website locally then this error comes to me from I don't know so what is this error mean and how can I solve it
the error occurs in this code .... actually , its complete website and I'm a beginner with JS and SO so please help me
// disable class and attribute rules defined by jquery.validate
$.validator.classRules = function() {
return {};
};
$.validator.attributeRules = function() {
return {};
};
Your Code tries to access an non existing JQuery namespace. You are either missing some sort of JQuery plugin, or you need to create on your self.
If you would like to create the validator namespace you can use such sample code as described here
(function ($) {
// do not overwrite the namespace, if it already exists
$.validator= $.validator|| {};
$.validator.classRules = function () { return {};}
$.validator.attributeRules = function () { return {};}
})($);

How do I use a function as a variable in JavaScript?

I want to be able to put the code in one place and call it from several different events.
Currently I have a selector and an event:
$("input[type='checkbox']").on('click', function () {
// code works here //
});
I use the same code elsewhere in the file, however using a different selector.
$(".product_table").on('change', '.edit_quantity', function () {
// code works here //
});
I have tried following the advice given elsewhere on StackOverflow, to simply give my function a name and then call the named function but that is not working for me. The code simply does not run.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals() {
// code does not work //
}
});
So, I tried putting the code into it's own function separate from the event and call it inside the event, and that is not working for me as well.
calculateTotals() {
// code does not work //
}
So what am I doing wrong ?
You could pass your function as a variable.
You want to add listeners for events after the DOM has loaded, JQuery helps with $(document).ready(fn); (ref).
To fix your code:
$(document).ready(function() {
$("input[type='checkbox']").on('click', calculateTotalsEvent)
$(".product_table").on('change', '.edit_quantity', calculateTotalsEvent)
});
function calculateTotalsEvent(evt) {
//do something
alert('fired');
}
Update:
Vince asked:
This worked for me - thank you, however one question: you say, "pass your function as a variable" ... I don't see where you are doing this. Can you explain ? tks. – Vince
Response:
In JavaScript you can assign functions to variables.
You probably do this all the time when doing:
function hello() {
//
}
You define window.hello.
You are adding to Global Namespace.
JavaScript window object
This generally leads to ambiguous JavaScript architecture/spaghetti code.
I organise with a Namespace Structure.
A small example of this would be:
app.js
var app = {
controllers: {}
};
You are defining window.app (just a json object) with a key of controllers with a value of an object.
something-ctlr.js
app.controllers.somethingCtlr.eventName = function(evt) {
//evt.preventDefault?
//check origin of evt? switch? throw if no evt? test using instanceof?
alert('hi');
}
You are defining a new key on the previously defined app.controllers.somethingCtlrcalled eventName.
You can invoke the function with ();.
app.controllers.somethingCtlr.eventName();
This will go to the key in the object, and then invoke it.
You can pass the function as a variable like so.
anotherFunction(app.controllers.somethingCtlr.eventName);
You can then invoke it in the function like so
function anotherFunction(someFn) { someFn();}
The javascript files would be structured like so:
+-html
+-stylesheets
+-javascript-+
+-app-+
+-app.js
+-controllers-+
+-something-ctlr.js
Invoke via chrome developer tools with:
app.controllers.somethingCtlr.eventName();
You can pass it as a variable like so:
$(document).ready(function() {
$('button').click(app.controllers.somethingCtlr.eventName);
});
JQuery (ref).
I hope this helps,
Rhys
It looks like you were on the right track but had some incorrect syntax. No need for { } when calling a function. This code should behave properly once you add code inside of the calculateTotals function.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals();
});
$("input[type='checkbox']").on('click',function() {
calculateTotals();
});
function calculateTotals() {
//your code...
}
You could just condense it all into a single function. The onchange event works for both the check box and the text input (no need for a click handler). And jQuery allows you to add multiple selectors.
$('input[type=checkbox], .product_table .edit_quantity').on('change', function() {
console.log('do some calculation...');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="product_table">
<input type="checkbox">
<input class="edit_quantity">
</div>

How can I use a javascript function globally in Drupal 7

How can I use a javascript function globally in Drupal 7.
I have my javascript file set up like this and add it using drupal_add_js():
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
});
In my block WYSIWIG I added the following code (The reason I add it in the WYSIWIG is because I want it to update before the page is fully rendered):
<script type="text/javascript">
add_if_country_is_not_usa();
</script>
But I get the following error:
Uncaught ReferenceError: add_if_country_is_not_usa is not defined
(anonymous function)
I read about adding functions to Drupal behaviors but that happens on document ready. I want to run the function as soon as the block is shown.
Any ideas?
Either define in the global scope, or do like below:
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
// set as a property of the global object `window`
window.add_if_country_is_not_usa = add_if_country_is_not_usa;
});
Not sure if this is the best way but I ended up being able to get it work using a namespaces. I call myGlobalObject.add_if_country_is_not_usa() from my block and it works now.
var myGlobalObject = mySingleGlobalObject || { 'country': {} };
(function ($) {
myGlobalObject.country = '';
myGlobalObject.add_if_country_is_not_usa = function() {
// Check what country it is
// myGlobalObject.country = 'US';
}
})(jQuery);

Write a namespaced function for jQuery that operates on parameters and not selectors

I've been tying to start a library of functions in jQuery to use transversally in my code
I thought that a good way of doing this would be to build a jQuery namespace and add my
methods under that (and provide the namespace for all who would like to contribute).
This is what I came up with:
(function( $ )
{
$.extend
({
mynamespace:
{
myfunction: function(a, b)
{
if (!Math.prototype.newmethod)
{
Math.prototype.newmethod = function(c, d)
{
// newmethod code
}
}
// myfunction code (uses Math.newmethod)
}
}
})
})(jQuery);
Now this worked fine in the small test file where I originally called it (the code did what I wanted it to) but after execution I got the following error:
DOM Exception:
INVALID_CHARACTER_ERR (5)
I ignored it, not being sure where it was coming from nor how to fix it (the few references I found on the web associated the problem with IE9 which I was not using) but when I used my new code site-wide everything started breaking with error messages such as
Uncaught TypeError: undefined is not a function
and
Uncaught TypeError: Object function (c, d) { // newmethod code }
Any ideas as to what I'm doing wrong are welcome
P.S.
The way I call the code described above is:
var temp = $.mynamespace.myfunction(a, b);

Categories