I am trying to insert a controlgroup widget in to the page but when I call controlgroup() the redering is incorrect. All the expected buttons are showing as links (Chrome 38.0.2125.101 m).
I'm assuming that it is something I'm doing and not a bug since the demos appear to work nicely. Is there a step I'm missing?
Here's my sample code:
http://jsfiddle.net/Lwr4mm4v/5/
function Body() {
this.left_buttons = $('<div data-role="controlgroup"></div>').appendTo( 'div' );
this.save_button = $('save description').appendTo(this.left_buttons);
this.run_button = $('run description').appendTo(this.left_buttons);
this.stop_button = $('stop description').appendTo(this.left_buttons);
this.add_button = $('add state').appendTo(this.left_buttons);
this.left_buttons.controlgroup();
}
var test = new Body();
Thanks
You are using an old version of JQM which requires calling an additional method .trigger("create").
It's recommended to use JQM 1.4.4 where you don't have to use any additional methods.
JQM 1.3: http://jsfiddle.net/Lwr4mm4v/6/
JQM 1.4: http://jsfiddle.net/4dfu9vtu/
Looking at the latest documentation, one adds a class="ui-btn" to anchor elements that you want to use as buttons.
Here is some sample code that achieves your goal:
function Body() {
this.left_buttons = $('<div data-role="controlgroup" data-type="horizontal"></div>').appendTo('#root');
this.save_button = $('Save').appendTo(this.left_buttons);
this.run_button = $('Run').appendTo(this.left_buttons);
this.stop_button = $('Stop').appendTo(this.left_buttons);
this.add_button = $('Add').appendTo(this.left_buttons);
this.left_buttons.controlgroup();
}
var test = new Body();
I have built a new sample illustrative jsFiddle that can be found here:
jsFiddle
See also this documentation on using the "Controlgroup Widget":
Control Group Widget
Related
I am trying to create a jsPsych plugin where the user can select a color for each stimulus. For this I am using jscolor. jscolor works well in vanilla HTML, but when I try to incorporate it in a jsPsych plugin it does not load the jscolor library.
jsPsych.plugins["color-picker"] = (function() {
var plugin = {};
plugin.info = {
name: "color-picker",
parameters: {
}
}
plugin.trial = function(display_element, trial) {
display_element.innerHTML += '<input data-jscolor="">'; // <-- This should show a color picker if jscolor.js is loaded.
// data saving
var trial_data = {
parameter_name: 'parameter value'
};
// end trial
jsPsych.finishTrial(trial_data);
};
return plugin; })();
I don't understand why this exactly happens. Maybe I need to load the library inside the plugin? Adding display_element.innerHTML += '<script src="library/jscolor.js"></script>'; does not work either.
How can I implement this in my plugin?
You can load the the jscolor library in your main experiment script and then reference the functions in the plugin.
One reason your plugin may not work right now is that the trial ends immediately after it begins because jsPsych.finishTrial() is called without waiting for any input from the user.
You'll likely want to move the jsPsych.finishTrial() call inside a function that is invoked based on the user submitting the form that includes the jscolor input element.
I am trying to make the grids static. No movement at all.
I tried:
var options = {
staticGrid: true,
};
$('.grid-stack').gridstack(options);
and also this
var options = {
setStatic: true,
};
$('.grid-stack').gridstack(options);
and this
var options = {
staticGrid: true,
};
$('.grid-stack').gridstack(options);
$('.grid-stack').data('gridstack').setStatic(true);
None of them seems to work, I used this link for documentation.
They have also mentioned a method setStatic but there are no examples of usign this method.
According to the Gridstack docs the staticGrid:true parameter is correct if you want to initialise and define the grid as STATIC at startup (your first method).
The SetStatic(true) is a function you can call on for toggling this state programatically.
If you view the source code live you will see a new CSS class has been added to the grid wrapper DIV; a class called 'grid-stack-static'. The appearance of this class confirms the parameter option staticGrid:true has been accepted and actioned.
BUT as I found myself (with v0.30 of the library), grid widgets in my initialised grid are still resizable and movable. In my opinion this suggests a bug.
You can lock down movement and resizing at a widget item level by using the item attributes data-gs-no-resize="yes" and data-gs-no-move="yes".
Seems counterproductive to have to do this if you have said 'static' already.
I have lodged an issue on Github to query this behaviour.
BTW it has been suggested to call on and use the setStatic( true ) function after grid init; as a temporary fix for this bug. Which was your third method - AND this worked for me.
Only difference between your 3rd method and mine is the function is wrapped in a document.ready function (and I am using $=jquery shortcut for convenience/compatibility on my system).
Worked:
(function ($) {
// Shortcut $=jquery
$(document).ready(function () {
// start grid
$(function () {
var options = {
staticGrid:true
};
$('.grid-stack').gridstack(options);
$('.grid-stack').data('gridstack').setStatic( true );
});
// END DOC READY
});
// SHORTCUT FIX
})( jQuery );
Just set the attribute gs-static="true"on the grid-stack's parent Grid element (on which gridstack has been initialized).
<div class="grid-stack" gs-static="true">
<div class="grid-stack-item">
<div class="grid-stack-item-content">Item 1</div>
</div>
<!-- .. and so on -->
</div
I am trying to replace the generic "Save to foursquare" button that can be set up here: https://foursquare.com/buttons/savetofoursquare
I want to replace it with my own custom foursquare button (.svg versions from Fairhead Creative, distributed by Zurb Foundation here: http://zurb.com/playground/social-webicons), and not have the script automatically wipe out and replace my custom button with the pre-packaged foursquare save button.
I am pretty sure I just need to script my own solution, using the documentation here: https://developer.foursquare.com/overview/widgets -- but I'm a bit confused. Wish there were examples there.
I also have several buttons on one page referencing various vcards (multiple museum locations). To do that, I used the data-context attribute from the answer here: Multiple Foursquare 'save' buttons on one page. That is all working.
I'm using my own html:
<span id="venue1-foursquare" class="fc-webicon foursquare" data-context="venue1_vcard">save Venue 1 to foursquare</span>
And later on the page:
<span id="venue2-foursquare" class="fc-webicon foursquare" data-context="venue2_vcard">save Venue 2 to foursquare</span>
How to do this?
OK, I knew I should keep searching and tinkering before posting this question. :)
Thanks to vnads here, I saw how to set up the global onReady functionality. I set it up to use a jQuery each(), loop through the spans, grab the data-context values, and then attach the functionality to my DOM element. The critical bit here came from vnads' comment at the end of the (currently) accepted solution: foursquare is looking for a DOM element, not a jQuery object.
Oh, and the widget.attach() instead of widget.replace() keeps the custom graphic from getting run-over.
<!-- 4Square js: -->
<script type='text/javascript'>
(function() {
window.___fourSq = {
"explicit": false,
"onReady": function () {
$('.fc-webicon.foursquare').each(function() {
var this_widget = $(this);
var this_context = this_widget.data("context");
var widget = new fourSq.widget.SaveTo({
"context": this_context
});
widget.attach(this_widget[0]);
});
}
};
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://platform.foursquare.com/js/widgets.js';
s.async = true;
var ph = document.getElementsByTagName('script')[0];
ph.parentNode.insertBefore(s, ph);
})();
</script>
I have an element $('#anElement') with a potential popover attached, like
<div id="anElement" data-original-title="my title" data-trigger="manual" data-content="my content" rel="popover"></div>
I just would like to know how to check whether the popover is visible or not: how this can be accomplished with jQuery?
If this functionality is not built into the framework you are using (it's no longer twitter bootstrap, just bootstrap), then you'll have to inspect the HTML that is generated/modified to create this feature of bootstrap.
Take a look at the popupver documentation. There is a button there that you can use to see it in action. This is a great place to inspect the HTML elements that are at work behind the scene.
Crack open your chrome developers tools or firebug (of firefox) and take a look at what it happening. It looks like there is simply a <div> being inserted after the button -
<div class="popover fade right in" style="... />
All you would have to do is check for the existence of that element. Depending on how your markup is written, you could use something like this -
if ($("#popoverTrigger").next('div.popover:visible').length){
// popover is visible
}
#popoverTrigger is the element that triggered that popover to appear in the first place and as we noticed above, bootstrap simply appends the popover div after the element.
There is no method implemented explicitly in the boostrap popover plugin so you need to find a way around that. Here's a hack that will return true or false wheter the plugin is visible or not.
var isVisible = $('#anElement').data('bs.popover').tip().hasClass('in');
console.log(isVisible); // true or false
It accesses the data stored by the popover plugin which is in fact a Popover object, calls the object's tip() method which is responsible for fetching the tip element, and then checks if the element returned has the class in, which is indicative that the popover attached to that element is visible.
You should also check if there is a popover attached to make sure you can call the tip() method:
if ($('#anElement').data('bs.popover') instanceof Popover) {
// do your popover visibility check here
}
In the current version of Bootstrap, you can check whether your element has aria-describedby set. The value of the attribute is the id of the actual popover.
So for instance, if you want to change the content of the visible popover, you can do:
var popoverId = $('#myElement').attr('aria-describedby');
$('#myElement').next(popoverid, '.popover-content').html('my new content');
This checks if the given div is visible.
if ($('#div:visible').length > 0)
or
if ($('#div').is(':visible'))
Perhaps the most reliable option would be listening to shown/hidden events, as demonstrated below. This would eliminate the necessity of digging deep into the DOM that could be error prone.
var isMyPopoverVisible = false;//assuming popovers are hidden by default
$("#myPopoverElement").on('shown.bs.popover',function(){
isMyPopoverVisible = true;
});
$("#myPopoverElement").on('hidden.bs.popover',function(){
isMyPopoverVisible = false;
});
These events seem to be triggered even if you hide/show/toggle the popover programmatically, without user interaction.
P. S. tested with BS3.
Here is simple jQuery plugin to manage this. I've added few commented options to present different approaches of accessing objects and left uncommented that of my favor.
For current Bootstrap 4.0.0 you can take bundle with Popover.js: https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js
// jQuery plugins
(function($)
{
// Fired immiedately
$.fn.isPopover = function (options)
{
// Is popover?
// jQuery
//var result = $(this).hasAttr("data-toggle");
// Popover API
var result = !!$(this).data('bs.popover');
if (!options) return result;
var $tip = this.popoverTip();
if (result) switch (options)
{
case 'shown' :
result = $tip.is(':visible');
break;
default:
result = false;
}
return result;
};
$.fn.popoverTip = function ()
{
// jQuery
var tipId = '#' + this.attr('aria-describedby');
return $(tipId);
// Popover API by id
//var tipId = this.data('bs.popover').tip.id;
//return $(tipId);
// Popover API by object
//var tip = this.data('bs.popover').tip; // DOM element
//return $(tip);
};
// Load indicator
$.fn.loadIndicator = function (action)
{
var indicatorClass = 'loading';
// Take parent if no container has been defined
var $container = this.closest('.loading-container') || this.parent();
switch (action)
{
case 'show' :
$container.append($('<div>').addClass(indicatorClass));
break;
case 'hide' :
$container.find('.' + indicatorClass).remove();
break;
}
};
})(jQuery);
// Usage
// Assuming 'this' points to popover object (e.g. an anchor or a button)
// Check if popover tip is visible
var isVisible = $(this).isPopover('shown');
// Hide all popovers except this
if (!isVisible) $('[data-toggle="popover"]').not(this).popover('hide');
// Show load indicator inside tip on 'shown' event while loading an iframe content
$(this).on('shown.bs.popover', function ()
{
$(this).popoverTip().find('iframe').loadIndicator('show');
});
Here a way to check the state with Vanilla JS.
document.getElementById("popover-dashboard").nextElementSibling.classList.contains('popover');
This works with BS4:
$(document).on('show.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', true);
});
$(document).on('hidden.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', false);
});
if ($('#anElement').data('isvisible'))
{
// popover is visible
$('#tipUTAbiertas').tooltip('hide');
$('#tipUTAbiertas').tooltip('show');
}
Bootstrap 5:
const toggler = document.getElementById(togglerId);
const popover = bootstrap.Popover.getInstance(toggler);
const isShowing = popover && popover.tip && popover.tip.classList.contains('show');
Using a popover with boostrap 4, tip() doesn't seem to be a function anymore. This is one way to check if a popover is enabled, basically if it has been clicked and is active:
if ($('#element').data('bs.popover')._activeTrigger.click == true){
...do something
}
I don't completely understand how javascript works in an OOP model, so I come to stack overflow for wisdom.
My example code:
(function($) {
var $container = $('#container');
var $sidebar = $('#sidebar');
// Sidebar
var currTab = $('#s1');
if(currTab) {
currTab.parent().parent().parent().addClass('selectedTop');
currTab.find(".sideContent").delay(300).slideToggle("slow");
currTab.addClass('selected');
}
$('#sideTop').delegate('li', 'hover', function(event) {
var $this = $(this);
if (event.type == 'mouseenter') {
if(!$this.hasClass("selected")){
$this.siblings(".selected").children(".sideContent").toggle();
$this.siblings(".selected").removeClass('selected');
$this.find(".sideContent").toggle().addClass('selected');
$this.addClass('selected');
}
}
});
})(this.jQuery);
This code caches my container and sidebar div and controls the hovering of tabs on my sidebar. These will be on every page, so I originally just included the js file on each page and it works as usual. Now I've gotten to a point where I want to customize each page with a specific tab of the sidebar open by default (defined by the currTab variable). When set, it will open by default, and stay open after the mouse leaves the sidebar.
I haven't found a way to customize currTab on each page without having to completely re-paste all the code associated with the sidebar, making any updates to the script cumbersome.
How should I be approaching this? Thanks
I'm sorry to have caused confusion with my lack of understanding, but one of the related questions answered mine in a way I didn't know how to search for:
He setup a "class" first, which could be included as a seperate JS, then communicated using jQuery.ClassName(options)
I've tried it and it works perfectly, seperating the code that is consistent, with the values that will change on each page.
(function($){
var undefined;
$.ClassName = function(options){
var self = this;
var cfg = $.extend(true, {}, this.defaults, options);
// ********************
// start:private
// ********************
function _init(){
};
// ********************
// start:public
// ********************
this.methodName = function(){
};
_init();
};
$.ClassName.prototype.defaults = {};
})(jQuery);
With classes. Just add a class such as "currTab" to whichever tab is active. In your JS, check for that class on the tab, and when the tab is changed, remove that class from the old one and add it to the new one.
Add a class to the item you want to be active by default. Use JS to detect the class and react accordingly.
One way is, to declare currTab differently inside each HTML page, and remove "var currTab = $('#s1');" from your JavaScript file. The rest of currTab occurences in the JavaScript file are still able to reference it.