fake jquery document.ready calls on pages without jquery - javascript

I wanted to use some data in another JS script which had a JQuery call $(document).ready(function() inside the block, but i did not want to use JQuery nor init the script, because i just wnat to use some of the predefined variables.
So simply using the script from external source ( as it might get changed ) but skipping the ready() call and just do some data manipulation afterwards.

I got it working with
<script>
var fakeJquery = function(fn) {
this.ready = function () {
return true;
}
};
var $ = function(fn) { return new fakeJquery();}
</script>
But i wonder if there is a better, easier way to do that?

Related

How to use external scripts e.g. jquery for YouTrack Workflow scripts

I want to clean the comments from youtrack by scheduler in a for Each loop with:
action: (ctx) => {
var issue = ctx.issue;
issue.comments.added.forEach(function(comment) {
// https://stackoverflow.com/questions/822452/strip-html-from-text-javascript
comment.text = jQuery(comment.text).text();
});
},
But I get the error: jQuery is not defined.
How can I include jQuery in the script to use it to clean the comment from HTML tags.
It is not possible to use jQuery inside of a workflow script. Still, you can create a helper function that does the trick:
function cleanComment(text) {
return text.replace(/(<([^>]+)>)/gi, '')
}
and use it inside of the action part of the rule

How to call javascript function inside jQuery

We have this tag with a javascript function in our HTML,
<select name="My_Saved_Billing" onchange="Choose_My_Saved_Billing(this.selectedIndex)" >
<option>Select</option>
<option value="1714">Address line 1, QC</option>
</select>
<script type="text/javascript">
function Choose_My_Saved_Billing(arg_index) {
switch(arg_index) {
// some commands here
}
}
</script>
And I also added a jQuery to it which is below so that on windows load, it will automatically select the second option.
<script type="text/javascript">
$(window).load(function(){
$("select").val($("select option:eq(1)").val());
});
</script>
But is it possible to call javascript function using jQuery? If so, how should I call this one?
Should I use Choose_My_Saved_Billing(this.selectedIndex)or Choose_My_Saved_Billing(arg_index)or you might know something. I've tried these two but none are working. Please let me know. Just a beginner here.
The way to call a JavaScript function from a JQuery file is the same as calling a JavaScript function from a JavaScript file :) This is so because JQuery is a library based from JavaScript. Say, you want to call function foo from a JavaScript file, when the window loads.
JQuery:
$(window).on('load', function() {
foo();
});
And JavaScript:
function foo() {
alert('This works!');
}
I hope this helps!
Yes, it's possible to call functions inside a jQuery ready block. Since you've defined the function at global scope (should probably move this into the jQuery ready block or, if you want to go to the trouble, into a module), it can be called from anywhere. So inside your ready block:
$(function () {
// do stuff
Choose_My_Saved_Billing(args);
});
jQuery is JavaScript. It's just a library for JavaScript. The main jQuery global $ is a JavaScript function that takes a valid selector as an argument and provides several methods on the return value of that function.
So calling a JavaScript function inside the callback function to .load is not an issue.
It is not clear what the Choose_My_Saved_Billing function actually does.
Think about what's happening here. In your onchange event you're calling the function with the index of the selected option passed as an argument. Since JQuery is just a library of shortcuts for things you can do in JavaScript, we should easily be able to do the same thing.
So let's get the element for which we want the selected index:
// maybe think about adding an ID here for better selection
var select = $('select[name^="My_Saved_"]');
Then let's get the index with a change event, then call the function:
var index = 0;
select.change(function(){
index = select.selectedIndex || 2; // set the index to default to 2
Choose_My_Saved_billing(index);
});
Instead of using onchange="...", just use jQuery to attach a change listener:
$(window).load(function() {
$('.colors_backgroundneutral select').on('change', function () {
Choose_My_Saved_Billing(this.value);
});
});
$(document).ready(function() {
$("#Submit1").click(function() {
$("#id1").hide();
Raise1();
});
$("#Raise").click(function() {
$("#id1").show();
});
});
function Raise1() {
var value1;
alert("hi");
value1 = document.getElementById("amount").value;
alert(value1);
alert("done");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
As jQuery is a more simple and advanced JavaScript solution, my guessing is you can call you JS function like this:
$(window).load(function(){
my_js_function(arg1, arg2);
});
Now, what you want is to call the JS function named Choose_My_Saved_Billing() with argument arg_index
So, your jQuery will look like this:
$(window).load(function(){
Choose_My_Saved_Billing(arg_index);
});
This only works if the function is already declared through raw code, on via the <script type="text/javascript" src="path/to/my_file.js"> head tag.
It should work like a charm, if not, feel free to share the errors returned by your browser.

Running JavaScript inside a Handlebars Template

I want to execute a bit of Javascript code inside my handlebars template. Typically in the application I do this
<script type="text/javascript">
var #Model.JavascriptVariableName;
$(function () {
#Model.JavascriptVariableName = new TagInput()
.withAvailableTags(#Html.Raw(Model.AvailableTagsJson))
.withAppliedTags(#Html.Raw(Model.AppliedTagsJson))
.withMinCharsAutocomplete(#Model.MinCharsAutocomplete)
.allowBackspaceDelete(#Model.DeleteWithBackspace.ToString().ToLowerInvariant())
.allowNewTags(#Model.AllowNewTags.ToString().ToLowerInvariant())
.initialize($('##Model.ElementId'), $('##(Model.ElementId)_hidden'));
#if(Model.OnChangeJavascript.IsNotNullOrEmpty()) {
#:#(Model.JavascriptVariableName).onChange = function () { #Html.Raw(Model.OnChangeJavascript) }
}
});
</script>
But since I am already inside of a handlebars template with I tried to just insert the $(function(){}) that just gets spit out as text which makes sense. So how then can I create a bit of dynamic Javascript inside of handlebars???
<script type="text/x-handlebars-template" id="tagsTemplate">
<div>Tags</div>
var #Model.JavascriptVariableName;
$(function () {
#Model.JavascriptVariableName = new TagInput()
.withAvailableTags(#Html.Raw(Model.AvailableTagsJson))
.withAppliedTags(#Html.Raw(Model.AppliedTagsJson))
.withMinCharsAutocomplete(#Model.MinCharsAutocomplete)
.allowBackspaceDelete(#Model.DeleteWithBackspace.ToString().ToLowerInvariant())
.allowNewTags(#Model.AllowNewTags.ToString().ToLowerInvariant())
.initialize($('##Model.ElementId'), $('##(Model.ElementId)_hidden'));
#if (Model.OnChangeJavascript.IsNotNullOrEmpty())
{
#:#(Model.JavascriptVariableName).onChange = function () { #Html.Raw(Model.OnChangeJavascript) }
}
});
</script>
The above code wont work.
Unless you are using handlebar to compile your webpage server side I don't see why you need to wait every time for the window Ready event: $(function(){}) in fact wrap a function to make it sure it will fire only when the DOM is ready (has been loaded).
You can simply skip that part in your code if you want.
I would strongly discourage to put JS code in a template: why don't you generalize that code and compile with Handlebars some DOM stuff with ids or classes that you can use in your "generic" function instead?

Revealing module pattern with jQuery not working

I've been playing around with the revealing module patter. I originally started using the Singleton pattern but from reading around the module pattern seems to be the better option.
So i've tested the following:
var test = (function() {
var init = function () {
alert('hello');
};
return {
init: init
};
})();
and this works fine when calling
<script>test.init();</script>
However, i want to use jQuery so i tried:
var test = (function($) {
var init = function () {
$("#samplediv").html('test');
alert('hello');
};
return {
init: init
};
})(jQuery);
but this doesn't work. It does work when using:
<script>$(function() { test.init(); });</script>
How can i get it to work without the added jQuery when calling it?
Usually, anything that touches the DOM needs to done in the $(document).ready(fn) callback. $(fn) is a shortcut for this.
So the reason it doesn't work is because you are searching for DOM elements that don't exist yet. So you have 2 choices. Either you must use the $() wrapper, or find another way to run your code only after the DOM elements exist. Another way to do this is to move your script tag the bottom of the body tag so that the DOM elements can exist when it's ran.
<body>
<!-- your page elements here -->
<script>test.init();</script>
</body>

Execute local Javascript after remote javascript loads?

I have a page where I am using jquery/ajax to pull down a chunk of HTML/JS from another component and injecting it into the page. That HTML references additional JS files, and I need those referenced JS files to be loaded before I run my javascript.
The HTML/JS that is being injected looks something like this:
<script type="text/javascript" src="http://myserver/js/ABunchOfStuff.js"></script>
<div>
blah blah blah
</div>
<script type="text/javascript">
//"sourceList" is defined in the ABunchOfStuff.js above, but it's not available by the time this executes.
$("input#autocomplete").autocomplete({
source: sourceList,
minLength: 2
});
</script>
Normally I would just hook into a window load event or a $(document).ready() or whatever, but in this case the window and document have already been completely loaded, and now we're adding additional content after the fact.
One possiblity would be to put a recursive setTimeout call in that would keep firing until the referneced javascript was available, but that's pretty ugly.
So is there any clean way to trap the event of a referenced javascript has been loaded and to execute code at that time?
Thanks
You can also use getScript and do your autoComplete in the success callback:
jQuery.getScript( 'http://myserver/js/ABunchOfStuff.js', function(data, textStatus) {
$("input#autocomplete").autocomplete({
source: sourceList,
minLength: 2
});
} );
The big question is, how do you inject this script ?
If you using "standard" script tag insertion, you can go and watch for the onload event (onreadystatechange in IE).
var scr = document.createElement('script');
scr.type = 'text/javascript';
scr.src = 'somewhere/somename.js';
scr.onload = scr.onreadystatechange = function() {
if( /complete|loaded/.test(scr.readyState) ) {
// do something
}
else {
// do something
}
};
What you are doing wrong here is not waiting for the DOM to load.
If you change your .autocomplete to only execute once the DOM is loaded through $(document).ready it will have executed the ABunchOfStuff.js
Like this:
(function($) {
$(document).ready(function() {
$("input#autocomplete").autocomplete({
source: sourceList,
minLength: 2
});
}
}(jQuery));
If you control the http://myserver/js/ABunchOfStuff.js file, then you can call your other JS from it when it first executes. Since it executes when it first loads and when it's available, you have the perfect timing.
If this JS file is used other places too, you could add some generic functionality to it for calling a callback when it executes by adding something like this to it:
try {
if (aBunchOfStuffCallbacks) {
for (var i = 0; i < aBunchOfStuffCallbacks.length; i++) {
aBunchOfStuffCallbacks[i].call(this); // call callback to announce we're loaded
}
} catch(e) {}
And, then in any web page where you want to be called when aBunchOfStuffCallbacks was loaded, you would just do this:
var aBunchOfStuffCallbacks = [];
aBunchOfStuffCallbacks.push(myFunc);
function myFunc() {
// put my code here for when aBunchOfStuffCallbacks is loaded
}
This would allow for multiple callbacks. The simpler version for just one callback looks like this:
try {
if (aBunchOfStuffCallback) {
aBunchOfStuffCallback.call(this); // call callback to announce we're loaded
}
} catch(e) {}
And, it would look like this to set it:
var aBunchOfStuffCallbacks = function () {
// put my code here for when aBunchOfStuffCallbacks is loaded
}

Categories