I have 2 functions and i was wondering if it is possible to use a variable that is defined in 1 function, in another function. Basically I have the following code:
(function( $ ) {
//On input
$("#anid").on("input", function() {
var variable = 'testing';
});
//On change
$('#dropdown').change(function(){
var variable2 = variable;
});
})( jQuery );
Any help is greatly appreciated!
Just declare the var variable out of that context.
var variable = 'initialValue';
(function( $ ) {
//On input
$("#anid").on("input", function() {
variable = 'new Value'
});
//On change
$('#dropdown').change(function(){
//don't even need another one here..
//variable is accessible from here
});
})( jQuery );
I'll delete this once you comment and say to do so as the answer above is fine. If you do not need variable elsewhere, then it will be cleaner to do:
(function( $ ) {
var variable = 'initialValue';
//On input
$("#anid").on("input", function() {
variable = 'new Value'
});
//On change
$('#dropdown').change(function(){
//don't even need another one here..
//variable is accessible from here
});
})( jQuery );
I am very mediocre in Javascript and looking around I was not able to find any information on how to achieve the behaviour I want or if it's even possible.
I have a namespace form to access my HTML form:
var form = (function(){
all = function () $('#myform .entry');
first = function () $('#myform .entry').first();
})();
form.all.css('color', 'blue');
form.first.css('color', 'red');
Desired extra behaviour:
form.css('background-color', 'green'); // should be calling $('#myform')
Is this possible?
You don't have a namespace, you have an object literal containing functions (and now you edited it, and added an IIFE, which makes even less sense), and the functions have to return something to be able to use it
var form = {
all : function () {
return $('#myform .entry');
},
first : function () {
return $('#myform .entry').first();
}
}
form.all().css('color', 'blue');
form.first().css('color', 'red');
or if you want to store the collection in an object without looking up in the DOM each time
var form = $('#myform');
form.all = $('#myform .entry');
form.first = $('#myform .entry').first();
form.all.css('color', 'blue');
form.first.css('color', 'red');
i try to do something like a status-check to enable/ disable settings.
// file 1
function settings( valStatus ){
var status = valStatus;
this.getStatus = function(){
return status;
}
this.setStatus = function( valStatus ){
status = valStatus;
}
}
calling this function here:
// file 2
$settings = new settings( false );
$(document).ready(function() {
$( '#openSettings' ).on('click', function() {
$settings.setStatus( true );
enableSettings();
});
$('#save').on('click', function(){
$settings.setStatus( false );
closeSettings();
});
});
// file 1
enableSettings = function() {
if( $settings.getStatus() === true ){
//toggle emptyLink
$('.myButton').on('click', function(){
alert($settings.getStatus());
});
}
}
So as startup while clicking on "myButton" nothing happens.
After Clicking on "openSettings" and then on "myButton" i get the alert "true";
After clicking on "save" and then on "myButton" again, i get the alert "false", but it does not even trigger, because i checked it befere.... can somebody help me please?
Where is my mistake?
I think you probably want to put the check for status inside the .myButton click handler instead of outside. That way you only need to apply the handler once and it will either work or not depending on the value of status.
$(document).ready(function() {
var $settings = new settings( false ); // keep out of global scope
$( '#openSettings' ).on('click', function() {
$settings.setStatus( true );
});
$('#save').on('click', function(){
$settings.setStatus( false );
});
$('.myButton').on('click', function(){
if ($settings.getStatus()) {
alert($settings.getStatus());
}
});
});
First of all, you can write JavaScript with less code than e.g. Java. You don't need the getter and setter methods since there is no package visibility. Since you do nothing with the setters you can access your fields directly. This is less code to read and less code where you can have errors. So get rid of useless code (remember this is not the request do code one-liners). Search the internet for "clean code".
Since you are in JavaScript you can do better than that. A smaller approach to store your information.
var mySetting = {};
mySetting.status = true
console.log( mySetting.status );
mySetting.status = false;
console.log( mySetting.status );
Remember to keep your global space clean! Search the internet for "javascript global scope pollution". So do this within your scope.
Your main problem is, that you are using closures. You probably don't want to use it in your case. Search the internet for "javascript closure tutorial". There are a lot of good ones out there.
Since you are using the Jquery, you can use the .data() function to store your information.
See http://api.jquery.com/jquery.data/
$(function(){
$( '#openSettings' ).on('click', function() {
$('#settings').data( "status", true );
enableSettings();
});
$('#save').on('click', function(){
$('#settings').data( "status", false );
closeSettings();
});
$('.myButton').on('click', function(){
alert($('#settings').data());
});
});
Or within the HTML itself. See http://api.jquery.com/attr/
$('#settings').attr( "status", true );
console.log( $('#settings').attr( "status" ) );
Or as switches.
$('#settings').addClass( "settingsEnabled" );
$('#settings').removeClass( "settingsEnabled" );
console.log($('#settings').hasClass('settingsEnabled'));
Use .data() if you want to store object references and HTML for simple information like switches etc. The benefit is, that you can reach that information even with CSS.
And please get rid of the $ prefix in your own code since it has no meaning. If you use frameworks like angular it will help you to identify the origin or like the $$ the ("don't") use of it.
So I've got an object, or array, declared at the beginning of anything, outside everything:
var Thing = {title:'horse'};
Then I've got:-
$('.clickedIt').fadeOut(200, function() { console.log(Thing.title); }
That will fail. However, if I place above that same console log out of fadeOut, it'll be fine.
If you want something to be global, just define it on the window Object.
window.Thing = { title: 'horse '};
Then use it like so:
$( '.clickedIt' ).fadeOut(200, function() {
console.log( window.Thing.title );
});
Just a note, putting a number of variables on the window Object is not recommended, I would recommend looking into name-spacing: http://addyosmani.com/blog/essential-js-namespacing/
Here is an example:
//simple JavaScript module
( function( window ) {
//define your applications root namespace
window.myApp = {
Thing: { title: 'horse '}
};
})( window );
//jQuery ready function
$( function() {
$( '.clickedIt' ).fadeOut( 200, function() {
console.log( myApp.Thing.title );
});
});
The value you assigned to title horse is undefined wrap it within quotes to make it string litral,
Live Demo
var Thing = {title:'horse'};
$('.clickedIt').fadeOut(200, function() { console.log(Thing.title); })
I'm writing a simple jQuery plugin, but I'm having trouble being able to use multiple instances on a page.
For instance, here is a sample plugin to illustrate my point:
(function($) {
$.fn.samplePlugin = function(options) {
if (typeof foo != 'undefined')
{
alert('Already defined!');
} else {
var foo = 'bar';
}
};
})(jQuery);
And then if I do this:
$(document).ready(function(){
$('#myDiv').samplePlugin({}); // does nothing
$('#myDiv2').samplePlugion({}); // alerts "Already defined!"
});
This is obviously an over-simplified example to get across the point. So my question is, how do I have two separate instances of the plugin? I'd like to be able to use it across multiple instances on the same page.
I'm guessing that part of the problem might be with defining the variables in a global scope. How can I define them unique to that instance of the plugin then?
Thank you for your guidance!
I have the very same problem but i find a very handy solution i´ll post it for someone who may have this problem
when you define your variables insinde the plugin you could use the .data() to store all the variables you define
like this
(function($) {
$.fn.samplePlugin = function(options) {
var base = this;
this.foo // define foo
// do stuff with foo and other variables
// Add a reverse reference to the DOM object
this.data("pluginname", base);
};})(jQuery);
And when you want to use the same foo variable you should retrive the reference with this:
base = this.data("pluginname");
base.foo
Hope it helps
Logan
html:
<code class="resize1">resize1</code>
<code class="resize2">resize2</code>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.resize1').ratiofix({message:'resize1'});
$('.resize2').ratiofix({message:'resize2'});
});
</script>
I have found 2 solutions - the first one is jquery widget factory
http://jqueryui.com/widget/
js code:
$.widget("custom.ratiofix",{
options:{
message:"nothing"
},
_create:function (){
var self=this;
this.setListeners();
},
setListeners:function (){
var self=this;
$(window).on('resize',$.proxy(self.printMsg,self));
},
printMsg:function (){
console.log(this.options.message);
}
});
And the second (without widget factory):
(function ($){
var Ratiofix = {
init: function(options, elem) {
this.options = $.extend({},this.options,options);
this.elem = elem;
this.$elem = $(elem);
this.setListeners();
return this;
},
options: {
message: "No message"
},
printMsg: function(){
console.log(this.options.message);
},
setListeners:function (){
var self=this;
this.$elem.on('click',function (){
console.log(self.options.message);
});
$(window).on('resize',$.proxy(self.printMsg, self));
}
};
$.fn.ratiofix=function (options){
this.init= function(options, elem) {
this.options = $.extend({},this.options,options);
this.elem = elem;
this.$elem = $(elem);
return this;
};
if ( this.length ) {
return this.each(function(){
var ratiofix = Object.create(Ratiofix);
ratiofix.init(options, this);
$.data(this, 'ratiofix', ratiofix);
});
}
};
})(jQuery);
In both cases plugins work separately and have own settings. In my case - 2 widgets listen to window resize and print to console own options.message
I'm not sure what you mean by having more than one instance of a plugin. A plugin would be available to use on any element.
This comment doesn't clarify much for me:
So say that it was a plugin that took
a "color" parameter and turned the
object into that color. Well, in that
case you'd need multiple instances, as
you're dealing with more than one page
element turning more than one color.
In this case, you would pass in different colors are arguments as needed:
$('div#foo').makeColor('red');
$('div#bar').makeColor('blue');
Each time you call the plugin, it will use whatever arguments you give it. The plugin isn't a class that needs instances.
Just throwing my solution in here:
(function ($){
$.fn.plugin = function (options){
var settings = $.extend({}, $.fn.plugin.defaults, options);
settings.that = $(this);
$.fn.plugin.init (settings);
};
$.fn.plugin.defaults = { objval: 'default' };
$.fn.plugin.init = function (settings){
settings.that.val (settings.objval);
};
}( jQuery ));
$('#target1').plugin ({objval: 'not default'});
$('#target2').plugin ();
DEMO
The settings variable is isolated every time you initialize the object.
To answer your question directly, you can use jQuery.noconflict() to avoid namespace collisions and thus potentially have multiple instantiations on a page..
var $j = jQuery.noConflict();
// Use jQuery via $j(...)
$j(document).ready(function() {
// etc
check here
But I question your design. Why are you writing a plugin that appears to not operate on a jQuery wrapped set ? .. Plugins should be written to assume they are operating on a jQuery array held in 'this'. In which case any state can be stored in each of the items being acted upon... But maybe you are building something different?
Please review this page
instead of writing this
$("#divid1").samplePlugin();
$("#divid2").samplePlugin();
you can do this way
$.plugin('samplePlugin1', samplePlugin);
$("#divid1").samplePlugin1();
$.plugin('samplePlugin2', samplePlugin);
$("#divid2").samplePlugin2();
You can have much details from here
http://alexsexton.com/?p=51
You need to use this.foo instead of var foo, so that the variable is only related to the current object.
This worked a treat for me! I had specific parameters for which pages/places I wanted to run a plugin and was able to achieve success by using a simple if statement. Hope this helps someone!
<!-- Begin JQuery Plugin Foo -->
<script src="js/foo_fun.js"></script>
<?php
if(substr_count(strtolower($currentUrl),"member")>0)
{
?>
<script>
$(document).ready(function(){
$('#vscroller').vscroller({newsfeed:'news_employee.xml', speed:1000,stay:2000,cache:false});
});
</script>
<?php
}
else
{
?>
<script>
$(document).ready(function(){
$('#vscroller').vscroller({newsfeed:'news_company.xml', speed:1000,stay:2000,cache:false});
});
</script>
<?php
}
?>
<!-- End JQuery Foo-->
I had the same problem : how to use many instances of a plugin on only one form ?
The usual way fails because in fact, the instance is not an instance of the plugin : it is an instance of jQuery.
So, if more than one element is defined to be managed by a plugin, each definition overrides the previous parameters.
It was necessary to have a look on the problem from another side.
A plugin is usually made to react on a specific event for a specific element. e.g.. onclick on a button, or when the mouse is over the element.
In my case, I had to use an autocomplete plugin for a city field, but my form has 5 tabs and in total 4 fields for the cities for 4 different parts of the information to be collected.
For each fields, parameters are specifics.
By the way, I've realised iI don't need to have the plugin active everytime : just on the appropriate event on the field is enough.
So I had an idea : an event manager for each element. When the event appends, so I define the plugin action.
Some code will be more efficient to explain : imagine you have 3 div blocks and your plugin must change the colours, but with specifics colours depending on which div is affected.
$(document).ready(function(){
// Wich elements are affected by the plugin
var ids = ['myDiv1','myDiv2','myDiv3'];
// foe each one :
for (v in ids)
{
//define from an event :
$('#'+ ids[v]).focus(function()
{
// depending which id is active :
var aParams, idDiv = $(this).attr('id');
// Choosing the right params
switch(idDiv)
{
case 'myDiv1':
aParams = {'color': '#660000', 'background-color': '#0000ff'};
break;
case 'myDiv2':
aParams = {'color': '#006600', 'background-color': '#ff00ff'};
break;
case 'myDiv3':
aParams = {'color': '#000066', 'background-color': '#ff0000'};
break;
default:
aParams = {'color': '#000000', 'background-color': '#ffffff'};
};
// Defining the plugin on the right element with the right params
$(this).myPlugin(
{
colors: aParams
});
});
}
});
And this works fine.
Sorry if my English is not perfect - I hope you understand well.