On getting no answer on my previous question , I decided to go on with this plugin structure.
(function ( $ ) {
$.fn.myPlugin = function (options) {
options = $.extend( {}, $.fn.myPlugin.defaults, options );
return this.each(function (i, el) {
("someiD").live("click",function() {
UpdateCounter();
});
});
};
$.fn.myPlugin.defaults = {
///options here for overiding
};
}(jQuery));
I have made a plugin in which I have to select a button to increase a counter and then I don't know how to get the updated values of the counter that is OnSelect/OnClick of the button.... Can anyone give me any insights on how should I be dealing with this without changing my plugin structure?
Basically like this:
(function ( $ ) {
$.fn.myPlugin = function (options) {
options = $.extend( {}, $.fn.myPlugin.defaults, options );
// $(this) is your selected element, #someSelect in this case
$(this).on('select', function(e) {
console.log('selected!')
})
};
// execute your plugin on the selected element
$('#someSelect').myPlugin();
Related
I am using the jQuery boilerplate and am trying to call one function from within another function and thought that Proxy might be the way to achieve that. Unfortunately I can't seem to get this to work.
Below is a heavily stripped down version of the code I am using, but you should be able to get the idea. Inside the ajax success method, I am trying to call the function customSelect so that I can reapply my select styling on elements created when the ajax is run. Unfortunately I'm unable to get this to work:
;( function( $, window, document, undefined ) {
"use strict";
var pluginName = "serviceFinder",
defaults = {
propertyName: "value"
};
// The actual plugin constructor
function Plugin ( element, options ) {
this._name = pluginName;
this.init();
}
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function() {
this.customSelect("lm-service-finder__field--select");
},
/**
* When a user selects a product
*/
selectProduct: function(e){
// Send the ID of the selected product so that we can get the variations for that product.
$.ajax({
type: 'POST',
url: themeVars.ajax,
dataType: 'json',
data: {
'product_id': selectedProductId,
action: 'servicefinder_get_product_attributes' //this is the name of the AJAX method called in WordPress
}, success: function (result) {
$.proxy(Plugin.customSelect);
},
error: function () {
console.log("error");
}
});
},
/**
* Custom select field styling
*/
customSelect: function(selector) {
console.log("Apply select field styling");
},
});
$.fn[ pluginName ] = function( options ) {
return this.each( function() {
if ( !$.data( this, "plugin_" + pluginName ) ) {
$.data( this, "plugin_" +
pluginName, new Plugin( this, options ) );
}
} );
};
} )( jQuery, window, document );
I have seen a couple of other similar questions here, but with no answer. Hope someone can assist?
I need to have a vertical slider input. Since this is not possible with the built-in sliderInput function, I opted to implement it myself.
According to this thread it is either possible to (I) rotate the sliderInput widget using CSS or (II) use a common slider and implement the capability to interact with Shiny.
I decided to go for option (II) because (I) did not work out the way I wanted.
I followed this article in order to implement a custom verticalSlider function
verticalSlider <- function(inputId, min, max, value) {
tagList(
singleton(tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.8.1/css/bootstrap-slider.min.css"))),
singleton(tags$head(tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/9.8.1/bootstrap-slider.min.js"))),
singleton(tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "css/verticalSlider.css"))),
singleton(tags$head(tags$script(src = "js/verticalSlider.js"))),
tags$input(id = inputId,
class = "verticalSlider",
type = "text",
value = "",
`data-slider-min` = as.character(min),
`data-slider-max` = as.character(max),
`data-slider-step` = as.character(1),
`data-slider-value` = as.character(min),
`data-slider-orientation` = "vertical"
)
)
}
I implemented the input binding and initialized the slider in "js/verticalSlider.js".
$(function() {
$('.verticalSlider').each(function() {
$(this).slider({
reversed : true,
handle : 'square',
change: function(event, ui){}
});
});
});
var verticalSliderBinding = new Shiny.InputBinding();
$.extend(verticalSliderBinding, {
find: function(scope) {
return $(scope).find(".verticalSlider");
},
getValue: function(el) {
return $(el).value;
},
setValue: function(el, val) {
$(el).value = val;
},
subscribe: function(el, callback) {
$(el).on("change.verticalSliderBinding", function(e) {
callback();
});
},
unsubscribe: function(el) {
$(el).off(".verticalSliderBinding");
},
getRatePolicy: function() {
return {
policy: 'debounce',
delay: 150
};
}
});
Shiny.inputBindings.register(verticalSliderBinding, "shiny.verticalSlider");
So far so good. The subscribe function is called everytime I move the slider's knob.
Moving the handle has no effect when the slider's value is bound to a textOutput however.
Shiny's "reactiveness" does not seem to work for my custom component. Could someone point me in the right direction?
Hi according to bootstrap-slider readme, you should rewrite getValue and setValue methods in your bindings :
getValue: function(el) {
return $(el).slider('getValue');
},
setValue: function(el, val) {
$(el).slider('setValue', val);
}
I think setValue is only used if you define an update method.
I', creating my own jQuery plugin which can be assigned to more than one element in document. I want, on some events, to call a function inside plugin for that particular element, but everything is driving me crazy. Plugin, itself, works, but problem with external calling exists.
simple plugin:
(function ( $ ) {
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
return this.each(function () {
_init();
_load();
});
function _init() {
//some action..
}
function _load() {
//some action..
}
};
$.fn.myPlugin.reload = function () {
_load(); //or this._load();
}
}( jQuery ));
and in html:
<div id="div1"></div>
<button id="button1">Click to reload</div>
<script>
$(document).ready(function() {
var A=$("div1").myPlugin({
someOption:"someValue"
});
$("#button1").click(function(){
A.reload();
});
});
</script>
return is always that _load() is undefined... Any idea will be really appreciated.
Youre returning before you define the functions, also _load cannot be accessed from the reload function if its not in a higher scope:
(function ( $ ) {
//function definitions:
function _init() {
//some action..
}
function _load() {
//some action..
}
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
return this.each(function () {
_init();
_load();
});
};
$.fn.myPlugin.reload = function () {
_load(); //
}
}( jQuery ));
Note that it can be accessed like this:
$.myPlugin.reload();
Reload is not part of an myPlugin instance.
If you want to return a custom object for each instance do this:
(function ( $ ) {
$.fn.myPlugin = function (options) {
var settings = $.extend({
someOption: ""
}, options);
//function definitions:
function _init() {
//some action..
}
function _load() {
//some action..
}
//iterate
this.each(function () {
_init();
_load();
});
return {
reload:_load,
};
};
}( jQuery ));
Now you can do
$("test").myPlugin().reload();
A is holding a reference to a jQuery object and as such has all the methods of $.fn.
But your reload is not a method of $.fn but of $.fn.myPlugin.
If you fix this and take Jonas` answer into account then it should work;)
I creating jquery plugin, looks like this :
(function ( $ ) {
// -- This is Person Object used for plugin
var PersonObject = function(elem, options)
{
this.elem = elem;
this.options = options;
this.run();
};
PersonObject.prototype = {
run: function()
{
// console.log(this.options.person_name);
self = this;
tpl = '<a class="btn btn-link btncok">one</a>';
self.elem.after(tpl);
$('.content').on('click', '.btncok', function(e) {
e.stopImmediatePropagation();
self.show();
});
return self.options.person_name;
},
show: function()
{
console.log(this.options.person_name);
}
};
// -- end Person Object
// -- This is my jquery fn function
$.fn.myPlugin = function(options) {
// here is default options
var default_options = {person_name: 'father'};
options = $.extend({}, default_options, options);
return this.each(function() {
new PersonObject($(this), options);
});
};
// -- end jquery plugin
}( jQuery ));
.
.
so then, when the above plugin are used by many elements with different situation like this :
<div class="jumbotron content">
<p class="something-one">one</p>
<p class="something-two">two</p>
</div>
<script>
// call the plugin WITH parameters
$('.something-one').myPlugin({person_name: 'mother'});
// result wrong : father (should be mother)
// call the plugin WITHOUT parameters
$('.something-two').myPlugin();
// result correct : father
</script>
the parameters is not work expected.
all the element that using the plugin will receive same parameters by last element call
how to fix this problem :(
You are seeing the same value because of the below click handler
$('.content').on('click', '.btncok', function(e) {
e.stopImmediatePropagation();
self.show();
});
$('.content').on('click', '.btncok', .... is does not delegate event as expected. Instead attach an event to tpl directly. Something like this
this.appendedEl = $('<a class="btn btn-link btncok">'+this.options.person_name+'</a>');
this.elem.after(this.appendedEl);
this.appendedEl.on('click', function(e) { // <--- this way the event is attached to the right element
e.stopImmediatePropagation();
this.show();
}.bind(this)); // <--- I used bind instead of self
Here is a demo http://jsbin.com/jafulo/edit?js,output
i made a jQuery plugin like so
(function($){
$.fn.pluginname = function(options) {
if (!this.length) { return this; }
var settings = $.extend(true, {}, $.fn.pluginname.default, options);
$w=$(this);
$w.bind("click", function(e){
e.preventDefault();
var elm = e.target;
elm.css({top : "+=100%"});
elm.attr({settings.examplePre : settings.exampleInt});
});
return this;
};
$.fn.pluginname.default = {
examplePre:"data-object",
exampleInt: 1e3
};
})(window.jQuery);
this whould apply the fn.function once to the selected elements
so if called twice, like..
$(document)ready(function(){
$(".selector").pluginname({
examplePre: "data-first"
});
$(".secondselector").pluginname({
examplePre:"data-second",
exampleInt: 10
});
});
the second plugin call overwrites the first one.
i read and tryed but none of my plugin layouts worked.
how to change this layout so that settings from .selector and .secondselector got its own data preset, even when called twice.
You have to scope the settings variable, so it's not affected from the outside.
$.fn.pluginname = function(options) {
return this.each(function () {
var settings = $.extend(true, {}, $.fn.pluginname.default, options);
$w = $(this);
$w.bind("click", function(e) {
e.preventDefault();
$(this).css("top", "+=100%");
$(this).attr(settings.examplePre, settings.exampleInt);
});
});
};
Here is a working fiddle