Is there anyway to grab the default value of the slider handle if it is not moved? - jquery-ui

I am using JQuery UI sliders in a mobile survey application. I can correctly capture the slider value if the label is clicked or the handle is moved to the label. My problem is that if the user does not click on a label/move the slider. I want to record the initial value of the slider. Here is the html where the slider goes:
<div class="well-lg">
<b>#Html.DisplayFor(model => model.QuestionsText)</b><div id="mySlideOutput"></div>
<br />
<div id="mySlideOutput"></div> // testing output of slider value
<br />
#*Include ID of EvaluationQuestion in ID of slider*#
<div id="slider-#(Model.ID)"></div>
#Html.Hidden("QR-" + #Model.ID)
</div>
Here is the Jquery code:
<script>
var items = ['Very Exceptional Results', 'Above Standard', 'Standard', 'Results Not Acceptable', 'Less Than Standard', 'N/A'];
#*var sliderDefault = $("#slider-#(Model.ID)"),
initialValue = 1;*#
// commented out code that was used to make sure the value is being populated at certain states
//NOTE: Needs to be changed to populate slider item labels from database.
$("#slider-#(Model.ID)").slider({
value: initialValue,
min: 1,
max: 6,
//step: 1,
slide: function (event, ui) {
$("#QR-#(Model.ID)").val(ui.value);
$('#mySlideOutput').html('ui-value = ' + ui.value);
},
#*stop: function(event, ui) {
$("#QR-#(Model.ID)").val(ui.value);
//alert(ui.value);
},*#
#*start: function(event, ui) {
$("#QR-#(Model.ID)").val(ui.value);
alert(ui.value);
}*#
});
$("#slider-#(Model.ID)").slider("pips", { rest: "label", labels: items });
I would like the initial value to populate the db if the slider is not moved to another option. Any suggestions? I appreciate the help.

$("#slider-#(Model.ID)").slider("value");
This will just return the value of the slider at any time it is called... whether you want to call this function at run time, or just before page unload is up to you.

Related

jQuery UI tooltip on pseudo disabled elements

I would like to show a tooltip on a text input that has a ui-state-disabled class.
I took a peek to the tooltip source code and I couldn't find something that checks against that particular class. So I don't know why it won't show.
As far as I can tell, the elements aren't disabled per se, they just have a class applied to them.
So, how can I show a tooltip on elements that have that class? I don't want to use a wrapper or anything like that. Maybe extending through widget factory...
Here's a sample code
HTML
<input name="#1" class="text" data-tooltip="message A">
<input name="#2" class="text" data-tooltip="message B">
<br>
<button id="disable">disable input #2</button>
<button id="enable">enable input #2</button>
JS
$(".text").each(function()
{
$(this).tooltip({
content: $(this).data("tooltip"),
items: ".text"
});
});
$("#disable").click(function()
{
$("input[name='#2']").addClass("ui-state-disabled");
});
$("#enable").click(function()
{
$("input[name='#2']").removeClass("ui-state-disabled");
});
FIDDLE: https://jsfiddle.net/hn1o4qs2/
See the doc (http://api.jqueryui.com/tooltip/):
In general, disabled elements do not trigger any DOM events.
Therefore, it is not possible to properly control tooltips for
disabled elements, since we need to listen to events to determine when
to show and hide the tooltip. As a result, jQuery UI does not
guarantee any level of support for tooltips attached to disabled
elements. Unfortunately, this means that if you require tooltips on
disabled elements, you may end up with a mixture of native tooltips
and jQuery UI tooltips.
Solution with wrapper
Your HTML:
<span class="input-container" data-tooltip="message A">
<input name="#1" class="text">
</span>
<span class="input-container" data-tooltip="message B">
<input name="#2" class="text">
</span>
<br>
<button id="disable">
disable input #2
</button>
<button id="enable">
enable input #2
</button>
Your Javascript
$(".input-container").each(function()
{
$(this).tooltip({
content: $(this).data("tooltip"),
items: ".input-container"
});
});
// ... The rest is the same
Solution with fake disabled-property
Here you can use a readonly attribute and a custom class for disabled input.
Playground: https://jsfiddle.net/5gkx8qec/
As I've stated in my question, I needed to get this working without adding a container or anything like that. And I was willing to extend the widget somehow...
So I read the source code more carefully and searched throught the whole repository for ui-state-disabled, and found that in widget.js there is an _on() method that at some point performs a check against that class and a flag called suppressDisabledCheck
A comment in code says
// Allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
This was very important, it gave me the clue that this check could be overriden. So a quick search in google and the widget factory had the answer:
Automatically handles disabled widgets: If the widget is disabled or
the event occurs on an element with the ui-state-disabled class, the
event handler is not invoked. Can be overridden with the
suppressDisabledCheck parameter.
So basically I did this:
$.widget("ui.tooltip", $.ui.tooltip,
{
options: {
allowOnDisabled: false
},
_on: function()
{
var instance = this;
this._super(instance.options.allowOnDisabled, {
mouseover: "open",
focusin: "open",
mouseleave: "close",
focusout: "close"
});
}
});
And then used it like this:
$(".text").each(function()
{
$(this).tooltip({
allowOnDisabled: true,
content: $(this).data("tooltip"),
items: ".text"
});
});
EDIT 2022-09-15
I was having some trouble with this implementation, so I've changed it a little bit
$.widget("ui.tooltip", $.ui.tooltip,
{
options: {
allowOnDisabled: false
},
_create: function()
{
this._super();
var instance = this;
this._on(instance.options.allowOnDisabled, {
mouseover: "open",
focusin: "open",
mouseleave: "close",
focusout: "close"
});
}
});

siblings not hiding on a jqueryui slide

here's the function:
$('.popoutlink').on('click', function() {
var box = $('#' + $(this).data('box'));
box.siblings().hide();
box.toggle("slide", { direction: "left" }, 500);
box.siblings().hide();
});
the two siblings.hide statements are because I'm in the middle of trying to figure out why I'm left with two slideouts on screen if I click on two buttons in rapid succession.
The html is:
<div class="col-md-2">
<div class="popoutlink" data-box="p1">1</div>
<div class="popoutlink" data-box="p2">2</div>
<div class="popoutlink" data-box="p3">3</div>
<div class="popoutlink" data-box="p4">4</div>
<div class="popoutlink" data-box="p5">5</div>
</div>
<div class="col-md-10 bb" style="height: 400px;">
<div class="popout" id="p1"><h1>panel 1</h1></div>
<div class="popout" id="p2">
<h1>panel 2</h1>
</div>
If I click on two buttons quickly then two windows are left on screen. I would like the siblings to hide before the selected div appears.
I have tried using promise.done():
box.siblings().hide(200).promise().done(function(){
box.toggle("slide", { direction: "left" }, 500);
});
to no effect. Adding box.toggle to hide as a callback:
box.siblings().hide(200, function(){
box.toggle("slide", { direction: "left" }, 500);
});
was very funny but not useful.
How do I get the siblings to go away reliably before I show the selected div no matter how quickly I click the buttons?
You see it here just click on the numbered boxes quickly
Thanks
If I understand your question, this should help:
https://jsfiddle.net/Twisty/3mbh5p0r/
jQuery UI
$(function() {
$('.popoutlink').on('click', function() {
var box = $('#' + $(this).data('box'));
$(".popout").hide();
//box.siblings().hide();
box.toggle("slide", {
direction: "left"
}, 500);
//box.siblings().hide();
});
});
When any of the "links" are clicked, they are all hidden and then only the one whom was clicked is toggled.
Update
A little more testing of .hide() versus .css("display", "none") revealed that changing the CSS was a faster method. This page talks about how it's immediate but I found that it wasn't as fast.
The matched elements will be hidden immediately, with no animation.
This is roughly equivalent to calling .css( "display", "none" ),
except that the value of the display property is saved in jQuery's
data cache so that display can later be restored to its initial value.
If an element has a display value of inline and is hidden then shown,
it will once again be displayed inline.
And:
Note that .hide() is fired immediately and will override the animation
queue if no duration or a duration of 0 is specified.
I did try using the callback, which made it worse. The callback should be triggered when the hide animation is complete, yet it added the element of animating the hide operation. Even when the speed was 0, it was slower.
So I advise this:
$(function() {
$('.popoutlink').on('click', function() {
$(".popout").css("display", "none");
$('#' + $(this).data('box')).show("fast");
});
});

why won't my jquery dialog fully fadeOut()?

When I call fadeOut on my dialog it only does a partial fade and leaves the grey header area where the dialog title is. I've tried removing the title as well as the various attributes that disable the exit button in the upper right corner of the dialog, but that didn't work. As you'll see in my script below, I want the dialog to close after the form submission has been validated.
//HTML
<div id="dialog">
<form id="form">
<p id="thanks">Please provide a contact number. It will only be shared with the
host</p><input id="number" name="number" type="text"/>
<button id="submit" type="submit">Submit</button>
</form>
</div>
//JS
if(myConditional){
//FORM IS HIDDEN ON PAGE LOAD AND SHOWN ON CLICK
$('form').show();
$('#dialog').dialog({
//These parameters are meant to disable the dialog close button
closeOnEscape: false,
beforeclose: function (event, ui) { return false; },
dialogClass: "noclose",
title: "Thanks For Volunteeering",
minWidth: 500
});
$('button').button();
}else{
//other code
}
//Validate the phone number before saving it to local storage
$("#form").validate({
rules: {
number : {
required: true
customvalidation: true
}
},
messages: {
number : {
required: "enter a phone number"
}
},
submitHandler: function(form) {
var number = $('#number').val();
localStorage.setItem('number', JSON.stringify(number));
//THIS FADE OUT ISN'T FULLY FADING THE DIALOG
$('#dialog').fadeOut();
} //closes submit handler
});//close validate
Ok I figured it out.
I got rid of the beforeClose parameter in the dialog init code, and in the form validation submit handler I added this:
$('#dialog').fadeOut('slow', function(){
$( this ).dialog( "close" );
});
//The fadeOut method has a call back function you can use with it to do something after the fade is completed.

Use the onstatechange: function from the jQuery Slider Plugin in order to bind slider to select element (as in the jQueryUI Demo)

I am trying to modify the function given in the jQuery UI demos for binding a slider to an existing select element in order to work with the jQuery Slider Plugin. The function should allow the user to change the value to either the slider or select element and it automatically updates the other element.
I've modified the function for the plugin to update the Slider when the value of the Select element changes, but I don't know how to modify the function so that the Select element is updated when the value of the Slider changes.
UPDATE - The plugin documentation has an 'onstatechange function()' which fires when the slider change state, but I'm not sure how to modify the code to meet my needs. The sample code given is: onstatechange: function( value ){console.dir( this ); }, and a fiddle using the onStateChange: function is posted here: http://jsfiddle.net/v3gUg/18
HTML & JS
<select name="SliderSelect" id="SliderSelect">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
<div class="layout">
<div class="layout-slider">
<input id="Slider" type="slider" name="area" value="3"/>
</div>
<script type="text/javascript" charset="utf-8">
$(function () {
var select = $("#SliderSelect");
jQuery("#Slider").slider({
from: 1,
to: 5,
scale: ['Dislike','','','', 'Love'],
limits: false,
step: 1,
dimension: '',
skin: "classic"
});
$("#SliderSelect").change(function () {
jQuery("#Slider").slider("value", this.selectedIndex + 1);
});
});
</script>
</div>
Function used in the jQuery UI Demo
$(function () {
var select = $("#minbeds");
var slider = $("<div id='slider'></div>").insertAfter(select).slider({
min: 1,
max: 6,
range: "min",
value: select[0].selectedIndex + 1,
slide: function (event, ui) {
select[0].selectedIndex = ui.value - 1;
}
});
$("#minbeds").change(function () {
slider.slider("value", this.selectedIndex + 1);
});
});
Did you try specifying a function to respond to slider changes as the change attribute?
jQuery("#Slider").slider({
from: 1,
to: 5,
scale: ['Dislike','','','', 'Love'],
limits: false,
step: 1,
dimension: '',
skin: "classic"
// add this
change: function( event, ui ) {
//... add your response code here}
}
});
You can use onstatechange in place of the callback. The effect is that your function is fired as the slider is moving and it won't wait for a mouse up event
jQuery("#Slider").slider({
from: 0,
to: max_slider_val,
step: 1,
smooth: true,
round: 0,
dimension: " ",
skin: "plastic",
onstatechange: function( myvalue ){
console.log(myvalue);
} });

$scope.slider - not updated

I have a jquery-ui slider which updates a textbox with the slider's value.
the textbox has ng-model so I can get the value from the controller - but the value is not updated after the slider is moved (the value is changing inside the textbox visually, but $scope.slider remains the same).
If I change the value manually inside the textbox everything is working as expected and the value of $scope.slider is updated with the new value.
Is there a way to make the slider update the value for the scope as well?
<input type="text" id="rent" ng-model="rent" style="border: 0; color: #f6931f; font-weight: bold;" />
<div id="slider-rent" style="width: 80%;"></div>
$("#slider-rent").slider({
range: false,
min: 0,
max: 20000,
step: 10,
value: 0,
slide: function (event, ui) {
$("#rent").val(ui.value);
}
});
$("#rent").val($("#slider-rent").slider("value"));
$("#rent").change(function () {
$("#slider-rent").slider("value", $("#rent").val());
});
(This is a rtl slider, this is why the values are negative)
It would be better to put your slider code into an angular directive so you can access the controller scope.
However if you trigger input event on the input element it will update the angular model
function updateInputValue( newVal){
$("#rent").val(newVal).trigger('input');
}
$(function () {
$("#slider-rent").slider({
range: false,
min: 0,
max: 20000,
step: 10,
value: 0,
slide: function (event, ui) {
updateInputValue(ui.value);
}
});
updateInputValue($("#slider-rent").slider("value"));
$("#rent").change(function () {
$("#slider-rent").slider("value", $("#rent").val());
});
})
DEMO:http://jsfiddle.net/zwHQs/
Try this:
slide: function (event, ui) {
$scope.rent = ui.value;
}
The above assumes the code you show is inside/wrapped in a directive.

Resources