Convert a minified jQuery plugin into a plain JavaScript plugin - javascript

I'm running a project where people can find doctors on the map and And book Online , ...
Previously I decided to use Angularjs and change the whole project, so I had to forget about some jQuery plugins which I've used before.
**Problem ** :
I'm using a jQuery plugin that works awesome with Google map API (Landcarte) , and I haven't find anything else to compare with this plugin in AngularJS.
So I couldn't do anything but to use both jquery and angular and this plugin in my site , But I dont know , I feel that its wrong to use both jquery and angular because I think that makes my firstload heavy.
**Questions : **
1- Is this possible to convert this plugin into a normal Javascript so I can omit the Jquery in my site ?
2- If not , What can I do ?
3- Can I use RequireJS to load jquery and this plugin later in my site ? (I dont know how to :()

I don't know about the Landcarte plugin so I can't help you with question 1.
If you want to initialize a jquery plugin but it's not working, a common cause of the problem is that the DOM is not ready yet.
To solve this, there are three options:
Method 1 Initialize the plugin inside of the link property of your directive. Within the link function, the children of the directive element have already been compiled and linked. If your plugin relies only on the children of the element being DOM ready, then this option is suitable.
app.directive('myDirective', function(){
return {
link: function(scope, element,attr){
element.plugin();
}
}
});
Method 2 Using $evalAsyc which runs after the compile and link phase but before the Render phase. Use this method if your plugin relies on the entire page being DOM ready, but it is not important that expressions have been rendered.
app.directive('myDirective', function(){
return {
link: function(scope, element,attr){
scope.$evalAsync(function(scope){
element.plugin();
});
}
}
});
Method 3 Using $timeout which runs after the render phase. Use this method if your plugin relies on the entire page being DOM ready, and all the expressions have been rendered.
app.directive('myDirective', function($timeout){
return {
link: function(scope, element,attr){
$timeout(function(){
element.plugin();
});
}
}
});
Depending on the plugin, one of these options should work for you. Prefer one that meets the need of the plugin minimally - meaning prefer option 1, over option 2, over option 3, but ultimately go with the one that works.

To turn min.js file into normal.js you can use this
but it just set tabulations and spaces and make script readable.
For example this script:
var a={log:function(){try{var e=Array.prototype.slice.call(arguments);if(typeof e[0]==="string"){if(/[\{\}]/.test(e[0])&&e.length>1){var t=e.length>2?e.slice(1):e[1];return console.log(this.text(e[0],t))}}return console.log.apply(console,e)}catch(n){}}}
will be:
var a = {
log: function () {
try {
var e = Array.prototype.slice.call(arguments);
if (typeof e[0] === "string") {
if (/[\{\}]/.test(e[0]) && e.length > 1) {
var t = e.length > 2 ? e.slice(1) : e[1];
return console.log(this.text(e[0], t))
}
}
return console.log.apply(console, e)
} catch (n) {}
}
}

Landcarte can be used in a pure JS code without jQuery as well. A map can be initialized by an explicit call of the at.geo.Map class constructor:
var container = document.getElementById("map");
var map = new at.geo.Map(container);
This class is mentioned in the reference.

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

Jstree custom plugin

We have a project with jstree 1.0-rc3. To extend basic funtionality we wrote custom extention using JQuery.jstree.plugin() function. Other words, we created custom plugin and used it as a usual plugin. Recently we decided to update jstree version to latest (3.3.8) and I met trouble because this function (JQuery.jstree.plugin) do not exist anymore and I can not find any analogue. Because of size of our custom plugin (hundreds of lines) and big count of place where we use it we do not want to move functionality to some another place from custom plugin cause it will take a really lot of time. Does anyone know how is it possible to create custom plugin in latest jstree ( 3.3.8 now)? Many thanks.
The functionality to add custom plugin is still there in the current jsTree version (3.3.8). As an example, it is already explained
// conditional select
(function ($, undefined) {
"use strict";
$.jstree.defaults.conditionalselect = function () { return true; };
$.jstree.plugins.conditionalselect = function (options, parent) {
this.activate_node = function (obj, e) {
if(this.settings.conditionalselect.call(this, this.get_node(obj))) {
parent.activate_node.call(this, obj, e);
}
};
};
})(jQuery);
$("#tree").jstree({
"conditionalselect" : function (node) {
return node.text === "Root node" ? false : true;
},
"plugins" : ["conditionalselect"]
});
Please the approach explained in https://github.com/vakata/jstree#more-plugins how to included your own plugin or any third party plugins.You must include its source on the page and list its name in the "plugins" config array.
You can have a look at jstree/src/misc.js for finding many such custom plugins already written.

jQuery Plugin public methods not working when applied to multiple elements

I posted a similar issue earlier, but it was flagged as a duplicate. However, this referenced article did not answer my question, so I'll try this again, this time using the solution of said article in my example.
The solution provided in this article creates the same issue I had before: when there is more than one element, I cannot call any of the public methods of the plugin.
Since no working example was provided, let's start with the code the article gave:
(function($){
$.fn.myPlugin = function(options) {
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
return this;
}
// private variables
var pOne = '';
var pTwo = '';
// ...
// private methods
var foo = function() {
// do something ...
}
// ...
// public methods
this.initialize = function() {
// do something ...
return this;
};
this.bar = function() {
// do something ...
};
return this.initialize();
}
})(jQuery);
I LOVE the internal loop so that it's applied to each instance of the element, but I feel the repeated "return this" is redundant. I think if we removed every single one of them, this plugin would work exactly the same. But, for the sake of argument, I'm going to leave them in my working example.
As you can see in this jsfiddle example, it works fine when there is only one element. The public method runs fine.
However, if I were to comment the other 4 elements back in like here, it throws an error in the console: "undefined is not a function". This, of course, makes sense since I'm attempting to run the public method on a reference to all elements on not an individual element.
Well, then I use .eq(0) to run the method only on the first instance of the element here, but I get the exact same error in the console.
So, why isn't calling the public method on the individual element working? Is this a scoping issue?
Please advise. Thanks!
Ok, so I think I've answered my own question. The issue is that I'm not applying a jQuery plugin to a DOM element. I'm applying it to a jQuery element. So, if I were to apply the jQuery plugin to a jQuery element, referenced like $element or $('.element'), I can then run any public methods because the scope is the same. But, if I were to reference it in a different way, like say $parentelement.eq(0), I'm using a difference reference, one that did not get the plugin applied to it, so naturally, it would not have the defined method. I think I'm getting the concept right. Still a little shaky on this. Maybe someone else can explain it better.
Nevertheless, while the above code does technically work, public methods are not practical on a jQuery plugin. I suggest instead using a Custom Event to make the jQuery plugin do something. Like this:
(function($) {
$.fn.extend({
myTestPlugin: function() {
if (this.length > 1) {
this.each(function() { $(this).myTestPlugin(); });
}
this.done = function() {
$(this).html('Done!');
};
var alsoDone = function() {
$(this).html('Also done!');
};
this.html('Replace me!');
this.on('alsoDone', alsoDone);
}
});
})(jQuery);
Here is an example where I am using trigger to make the plugin do something on an individual element, which works, but the method still fails as expected.
I hope this helps other people with similar issues.

How do I get Jasmine to always show the spec list?

If my Jasmine test has failures, it only shows those by default. I have to click "Spec List" to see all of the tests that were run.
Can I somehow get it to always show the spec list by default?
I am using jasmine 2.1.3 with require.js as outlined in this stackoverflow question:
Getting requirejs to work with Jasmine
and this was bugging me too.
I am also using jquery so I added an event trigger after the .execute() like so:
require(specs, function (spec) {
jasmineEnv.execute();
$('.spec-list-menu').click();
});
I couldn't find any configuration for setting the default, but you can see in the jasmine-html.js file:
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
if you changed it to:
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('spec-list');
It will also set the default.
I don't really like editing libraries like that since I usually forget what I have changed when I update the library.
That was the reason I went with the jquery route.

Require and Backbone - Loading jQuery mobile dynamically

I'm working on an app that uses Backbone and RequireJS (using the Backbone boilerplate).
What I'd like to do is detect if the user is on a mobile device (currently using Modernizr to check for touch), and if so then load jQuery Mobile's css and js, and have it applied to all modules and their templates.
I'm not sure of the best way to do this with RequireJS.
Cheers
Edit: After re-reading your question, I'm not sure this is what you're asking for. Sorry for the noise.
I'm currently in a similar situation. You can set properties on Backbone's View/Router/Model/Etc prototypes and they'll filter down the chain. So, for example:
//Assuming we're in 'mobile' mode, you'd do this in whatever code gets loaded.
Backbone.View.prototype.useMobileView = true;
Then you can do whatever is necessary if this.useMobileView == true. For example:
ResponsiveView = Backbone.View.extend({
getTemplate: function () {
if(this.useMobileView) {
return this.mobileTemplate;
} else {
return this.template;
}
}
});
SomeView = ResponsiveView.extend({
render: function () {
var template = this.getTemplate();
//do stuff
}
});

Categories