Adding text input that shows average of several jQuery UI sliders - jquery-ui

I have several jQueryUI sliders working with this code:
jQuery(document).ready(function ($)
{
$( '.rwmb-slider' ).each( function() {
var $this = $( this ),
$input = $this.siblings( 'input' ),
$valueLabel = $this.siblings( '.rwmb-slider-value-label' ).find( 'span' ),
value = $input.val(),
options = $this.data( 'options' );
if ( !value )
{
value = 0;
$input.val( 0 );
$valueLabel.text( '0' );
}
else
{
$valueLabel.text( value );
}
// Assign field value and callback function when slide
options.value = value;
options.slide = function( event, ui )
{
$input.val( ui.value );
$valueLabel.text( ui.value );
};
$this.slider( options );
});
});
JSFIDDLE: http://jsfiddle.net/q2BwE/
Everything works good but I'm struggling integrating in this code a function that allows me to display in a text input an average of the sliders which value is different than '0'.
Can you help me guys? Thank you

Here's one way to do it: jsFiddle example.
I added a text field (<input name="average" type="text" readonly />) to display the average that gets calculated after any of the sliders finish moving. Then I added the following code to do the calculation:
options.change = function (event, ui) {
var avg = 0;
var div = 0;
$('.rwmb-slider').each(function () {
avg += ($(this).slider('value'));
if($(this).slider('value')>0)div++
})
$('input[name=average]').val(avg/div);
};

Related

How to make jQuery UI Tooltip stay on, on hover

Does anybody know how can I make jQuery UI tooltip to stay visible on hover. That is- I want it to stay visible when I move mouse from p element to tooltip.
Have tried on fiddle, but it seems there's a problem with :hover.
$("p").tooltip({
hide: {
effect: 'explode'
}
}).mouseleave(function () {
if ($('p').is(':hover')) {
ui.tooltip.preventDefault();
$('p').tooltip('open');
}
}).focusout(function () {
$('p').tooltip('close');
});
jsFiddle
That was a little tricky...
This script extends the standard jQuery UI 1.12.1, so that you get two extra options, allowing you to keep the tooltip open, while hover (the mouse stays on) it.
(function($) {
var uiTooltipTmp = {
options: {
hoverTimeout: 200,
tooltipHover: false // to have a regular behaviour by default. Use true to keep the tooltip while hovering it
},
// This function will check every "hoverTimeout" if the original object or it's tooltip is hovered. If not, it will continue the standard tooltip closure procedure.
timeoutHover: function (event,target,tooltipData,obj){
var TO;
var hov=false, hov2=false;
if(target !== undefined) {
if(target.is(":hover")){
hov=true;}
}
if(tooltipData !== undefined) {
if($(tooltipData.tooltip).is(":hover")){
hov=true;}
}
if(target !== undefined || tooltipData !== undefined) {hov2=true;}
if(hov) {
TO = setTimeout(obj.timeoutHover,obj.options.hoverTimeout,event,target,tooltipData,obj);
}else{
target.data('hoverFinished',1);
clearTimeout(TO);
if(hov2){
obj.closing = false;
obj.close(event,true);}
}
},
// Changed standard procedure
close: function(event) {
var tooltip,
that = this,
target = $( event ? event.currentTarget : this.element ),
tooltipData = this._find( target );
if(that.options.tooltipHover && (target.data('hoverFinished')===undefined || target.data('hoverFinished') === 0)){
target.data('hoverFinished',0);
setTimeout(that.timeoutHover, that.options.hoverTimeout,event, target, tooltipData, that);
}
else
{
if(that.options.tooltipHover){
target.data('hoverFinished',0);}
// The rest part of standard code is unchanged
if ( !tooltipData ) {
target.removeData( "ui-tooltip-open" );
return;
}
tooltip = tooltipData.tooltip;
if ( tooltipData.closing ) {
return;
}
clearInterval( this.delayedShow );
if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
target.attr( "title", target.data( "ui-tooltip-title" ) );
}
this._removeDescribedBy( target );
tooltipData.hiding = true;
tooltip.stop( true );
this._hide( tooltip, this.options.hide, function() {
that._removeTooltip( $( this ) );
} );
target.removeData( "ui-tooltip-open" );
this._off( target, "mouseleave focusout keyup" );
if ( target[ 0 ] !== this.element[ 0 ] ) {
this._off( target, "remove" );
}
this._off( this.document, "mousemove" );
if ( event && event.type === "mouseleave" ) {
$.each( this.parents, function( id, parent ) {
$( parent.element ).attr( "title", parent.title );
delete that.parents[ id ];
} );
}
tooltipData.closing = true;
this._trigger( "close", event, { tooltip: tooltip } );
if ( !tooltipData.hiding ) {
tooltipData.closing = false;
}
}
}
};
// Extending ui.tooltip. Changing "close" function and adding two new parameters.
$.widget( "ui.tooltip", $.ui.tooltip, uiTooltipTmp);
})(jQuery);
jQuery(document).ready(function($) {
$("h3").tooltip({hoverTimeout: 250, tooltipHover: true});
});
body {
background-color: #f3f3f3;
}
h3 {
display: inline-block;
margin: 1em 0 0 1em;
padding: 1em;
background-color: #FF7E6B;
color: #fff;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<div>
<h3 title="I'll be here while you are hovering me or my creator.">
Hover me</h3>
</div>
$('[data-toggle="popover"]').popover({ trigger: "manual" }).on(
{
mouseenter: function () {
var $this = $(this);
$this.popover("show");
$(".popover").on("mouseleave", function () {
$this.popover('hide');
});
},
mouseleave: function () {
var $this = $(this);
setTimeout(function () {
if (!$(".popover:hover").length) {
$this.popover("hide");
}
}, 350);
}
});
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span type="button" role="button" class="glyphicon glyphicon-question-sign" data-toggle="popover" data-trigger="hover" data-placement="auto" data-html="true" data-content="For instance enter a link here <a href='https://google.com' target='_blank'>Almost know everything</a>"></span>

How to correctly destroy spinner once it reaches certain value

In my application once user has entered certain value in the spinner I should change content of the view. As part of this process I need to destroy and remove spinner.
The problem is that spinner gets into the loop and increments its' value to no end.
Sample code:
spinner = $( "#spinner" ).spinner({
change: function( event, ui ) {
console.log('change');
},
spin: function( event, ui ) {
console.log( 'spin event, value = ', ui.value );
if ( ui.value == 3 ) {
spinner.spinner( "destroy" );
}
}
});
Please check the following sample: http://jsfiddle.net/XseWc/312/
Increase value 3 times: click, click, click
How can this be achieved?
Update:
Two options available here.
To use stop event instead of spin.
To trigger mouse up event before destroying spinner. With mouse up spinner will remove it handlers and destroy will work correctly.
Just prevent the default event!
spinner = $( "#spinner" ).spinner({
change: function( event, ui ) {
console.log('change');
},
spin: function( event, ui ) {
if ( ui.value == 3 ) {
//NEW
event.preventDefault();
spinner.spinner( "destroy" );
}
}
});
old fiddle
See this documentation entry. It prevents the spinner from doing the normal (default) behaviour.
EDIT
Perhaps this can be seen as a workaround but this solution works and doesn't trigger tons of errors.
$(function () {
var value;
spinner = $("#spinner").spinner({
change: function (event, ui) {
console.log('change');
},
spin: function (event, ui) {
value = ui.value;
},
stop: function (event, ui) {
if (value == 3) {
$(this).spinner("destroy");
}
}
});
});
updated fiddle
Try this instead (both hide() and remove() worked for me)
spinner = $( "#spinner" ).spinner({
change: function( event, ui ) {
console.log('change');
},
spin: function( event, ui ) {
if ( ui.value == 3 ) {
spinner.hide();
}
}
});
Will this accomplish what you're looking for?
spinner = $( "#spinner" ).spinner({
change: function( event, ui ) {
console.log('change');
},
spin: function( event, ui ) {
if ( ui.value == 3 ) {
spinner.remove();
}
}
});

jquery ui autocomplete with autoselect plugin

I am using a jquery ui autocomplete. when the user types in their own value, rather than selecting an item from the list, the textbox clears. This is ok (I don't want the user to be able to enter their own values) except if the user types in a value that does exist on the list.
I tried using the autoSelect plugin as detailed in this post, but it is not working - I added the plugin but when I type in a value that IS on the list and hit tab, I get the same results as before - the textbox clears.
Here is my autocomplete:
$(function () {
$('[id$="txtDocType').autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/MyPage.aspx/myFunction",
data: "{'prefixText':'" + request.term.toLowerCase() + "', 'ddvId':'" + this.element.data('autocomplete') + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) { }
});
},
minlength: 1,
select: function (event, ui) {
$('#divOtherFields input[type=text], input[type=password]').prop("disabled", false).removeClass("disabled");
$('[id$="btnSaveNext"],[id$="btnSaveClose"]').prop("disabled", false);
$('[id$="txtReceiptDate"]').datepicker("setDate", new Date());
}
});
});
Here is the plugin:
(function( $ ) {
$.ui.autocomplete.prototype.options.autoSelect = true;
$( ".ui-autocomplete-input" ).on( "blur", function( event ) {
var autocomplete = $( this ).data( "autocomplete" );
if ( !autocomplete.options.autoSelect || autocomplete.selectedItem ) { return; }
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" );
autocomplete.widget().children( ".ui-menu-item" ).each(function() {
var item = $( this ).data( "item.autocomplete" );
if ( matcher.test( item.label || item.value || item ) ) {
autocomplete.selectedItem = item;
return false;
}
});
if ( autocomplete.selectedItem ) {
autocomplete._trigger( "select", event, { item: autocomplete.selectedItem } );
}
});
}( jQuery ));
I set a breakpoint in the plugin on this line - "$( ".ui-autocomplete-input" ).on( "blur", function( event )" and the breakpoint was hit, yet the code would not step through. When I set a breakpoint to this line - "var autocomplete = $( this ).data( "autocomplete" );" the breakpoint was NOT hit.
Any ideas? I am at my wits end with this.
I solved this by making a couple of tweaks to the autoSelect plugin. Here is the code that eventually worked for me:
$(".ui-autocomplete-input").bind("focusout", function (event) {
var autocomplete = $(this).data("ui-autocomplete");
if (!autocomplete.options.autoSelect || autocomplete.selectedItem) { return; }
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i");
autocomplete.widget().children(".ui-menu-item").each(function () {
var item = $(this).data("ui-autocomplete-item");
if (matcher.test(item.label || item.value || item)) {
autocomplete.selectedItem = item;
return false;
}
});
if (autocomplete.selectedItem) {
autocomplete._trigger("select", event, { item: autocomplete.selectedItem });
}
});
I used the focus event to set the first value to a hidden variable. The same hidden variable also got updated in the select event. And then this was the hidden variable which I posted to the ajax call.
Why I did not use focus to set the value in the autocomplete input box, was because doing so populated the autocomplete input box even while I was typing in this box.
focus: function (event, ui) {
if($("#streetid")) $("#streetid").val(ui.item.label); //this was my hidden variable
}
},

jQueryUI droppable, stop propagation to overlapped sibling

As you can see here: http://jsfiddle.net/rA4CB/6/
When I make the drop in the overlapped area it is received in both droppables, greedy doesn't work when the items are siblings. Is there any way to block the reception on droppables lower in the zIndex?
BTW, mouseOver won't fire for the droppable element as the mouse is actually over the draggable element.
relevant JS:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
tolerance:'pointer',
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
$( "#droppable2" ).droppable({
tolerance:'pointer',
greedy:true,
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
Okay, so I spend an hour trying to figure it out, then as soon as I ask I then find my answer
http://jsfiddle.net/rA4CB/7/
Modified the JS to the following:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
tolerance:'pointer',
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
$( "#droppable2" ).droppable({
tolerance:'pointer',
greedy:true,
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
},
over: function(event, ui){
$( "#droppable" ).droppable( "disable" )
},
out: function(event, ui){
$( "#droppable" ).droppable( "enable" )
}
});
});
$( "#droppable" ).droppable({
greedy: true,
drop: function( event, ui ) {
if(ui.helper.is(".dropped")) {
return false;
}
ui.helper.addClass(".dropped");
}
});
Just set a css class on ui.helper of draggable. If the draggable has been accepted once, it will be refused by all other droppables (Could be done with the droppable "accept" parameter,too , like accept : ":not(.dropped)" and the class added to ui.draggable).
If you have a number of droppable in a container area then what????
You must re think for that problem. Greedy works for only parent to child relationship not in siblings. So you must edit droppable js or put your own logic for it.
So if you have a numbers of droppable then you must write some extra code to handle dropping on perfect droppable as it is in this example A number of siblings droppables
For making perfect siblings droppable modify your droppbale as below
var topElement = undefined;
var topElementArray = Array();
$( "#draggable" ).draggable();
$( ".droppableBox" ).droppable({
activeClass: "active-droppable",
tolerance:'pointer',
over: function( event, ui ) {
// This is for only show a message that z-index must be required for proppable
// you can remove it after testing or after development
if ($(this).css("z-index") == 'auto') {
alert("Please provide z-index for every droppable.");
return;
}
//
topElement = undefined;
topElementArray = Array();
// Change it as you want to write in your code
// For Container id or for your specific class for droppable or for both
$('#demo > .droppableBox').each(function(){
_left = $(this).offset().left, _right = $(this).offset().left + $(this).width();
_top = $(this).offset().top, _bottom = $(this).offset().top + $(this).height();
if (event.pageX >= _left && event.pageX <= _right && event.pageY >= _top && event.pageY <= _bottom) {
topElementArray.push($(this).attr('id'));
}
});
},
drop: function( event, ui ) {
if (!topElement) {
topElement = determineTopElement(topElementArray);
}
if ($(this).attr('id') == $(topElement).attr('id')) {
$( this ).addClass( "ui-state-highlight" ).find( "p" ).html( "Dropped!" );
// Your code after successful dropped element on specific siblings
// Start writing code for dropped element & perfect droppable
}
}
});
determineTopElement = function(_array) {
var topElement;
var zIndexHighest = 0;
for (i = 0; i < _array.length; i++){
var element = $("#"+ _array[i]);
var z_index = $(element).css("z-index");
if( z_index > zIndexHighest){
zIndexHighest = z_index;
topElement = element;
}
}
return topElement;
}
In certain circonstances :
myjQuery.droppable({
over:function(evt,ui){
ui.draggable.attr('drg_time', this.drg_time = evt.timeStamp)
},
accept:function(draggeds){
if(draggeds.attr('drg_time'))
{
return draggeds.attr('drg_time') == this.drg_time
}
return draggeds.hasClass('acceptable_classes_here')
},
out:function(evt,ui){
// useless but cleaner
ui.draggable.removeAttr('drg_time')
}
drop:...,
})
I had the same problem and made a small plugin :)
check it out:
https://stackoverflow.com/a/16720944/1308461
I find that using #invertedSpear's method will cause UI state change which is not desirable in some cases. Here is the code.
var lastOpertion = new Date().getTime();
drop: function (event, ui) {
if (new Date().getTime() - lastOpertion < 100) return;
lastOpertion = new Date().getTime();
....
}
So, when trying to find simple solution I came up with this (and it works for me):
window.overNowOnThis = "";
window.olderOnes = [];
$obj.droppable({
accept: ".draggable_imgs",
drop: function(e, ui) {
if(window.overNowOnThis == this){
// Do whatever
}
},
over: function(event, ui){
window.olderOnes.push(window.overNowOnThis);
window.overNowOnThis = this;
},
out: function(){
var lastElem = window.olderOnes.pop();
window.overNowOnThis = lastElem;
}
});
Top element would be selected because on it "over" fires the last one. Also - if there is more than two siblings - then when moving out of element we set the last one as current. Using global "window" was for example. Better option would be using classes as it can safely keep data.
It's very similar to invertedSpear answer. I had to change it a little bit because enabling/disabling inside "over"/"out" didn't work for me .I had to do below instead
$("#droppable2").droppable({
greedy: true,
drop: function (event, ui) {
$("droppable").droppable("disable");
}
}
I had to explicitly enable"droppable" div when I needed it. For instance, enable it when starting the drag event. Eg
$("#drageMe").draggable({
start:function(event,ui){
$("droppable").droppable("enable");
}
})
try greedy option in ui dropable. see the fiddle link below for demo:
http://jsfiddle.net/creators_guru/3vT5C/embedded/result/
$( ".circles" ).droppable({
greedy: true,
drop: function( event, ui ) {
$_data = ('drgged class = ' + ui.draggable.attr('class'));
$_data1 = ('droped id = #' + $(this).attr('id'));
$('#data').html($_data + '<br/>'+$_data1);
return false;
}
});

jquery ui autocomplete pass a variable

I m using jquery UI for getting suggestions of friend names and id, but the problem is I am not able to pass user id using autocomplete json function .
$(function() {
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split(term).pop();
}
$( "#recipient" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
source: function( request, response ) {
var attm= $('.USERID').val();
$.getJSON( "modules/messages/sql.php", {
term: extractLast( request.term ),
}, response );
},
search: function() {
// custom minLength
var term = extractLast( this.value );
if ( term.length < 2 ) {
return false;
}
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
var prollNos = $('#recipientid').val()
$('#recipientid').val(prollNos + ui.item.id + ", ");
return false;
}
});
});
in which i am trying to pass a: $('.USERID').val() as user id , can anyone help me out?
I achieve something similar by GET. I use jquery-ui-autocomplete, as source I use: "source.php?param=something". So the final request my source page gets is "source.php?param=something&term=blabla"

Resources