I have a slider. When the user slides it, it adjusts the gamma of an image. Here is the code, very straightforward, works perfectly.
$('#gammaSlider').slider({
max: 125,
min: -125,
value: 0,
slide: function () {
//stuff to adjust gamma of image
},
change: function () {
//stuff to adjust gamma of image
}
});
However, when the user loads a different image, I want to programmatically set the slider to the value it should be at for the new image (a.k.a. allow flipping back and forth between multiple pages with separate gamma settings). To be clear, the newly loaded image's gamma is already at whatever value it was last set to. I am only seeking to adjust the UI to match the new image's value. For instance, if I increase page 2's gamma, then flip to page 1, I need to move the slider back to default from its increased position, and I need to do it without the code thinking I'm trying to decrease the gamma.
When I do this using the following, there's a problem:
$('#gammaSlider').slider('value', gamma);
The problem is that this is triggering the slide and change calls that I set up for the slider in the original declaration above, causing it to try to reload the image redundantly with new gamma values. Is there a way to change the slider programmatically WITHOUT triggering those calls?
You can use the fact that you can differentiate between a user change and a programmatic change via event.originalEvent. For example, you can have code that gets executed when the user makes a change, and different code that gets executed when you make a programmatic change like changing the value. Since changing the value will trigger the slider's change event, you can put your gamma change code within the block that only is triggered on a user's change, not a programmatic change:
change: function (event) {
if (event.originalEvent) {
//stuff to adjust gamma of image ONLY WHEN USER CHANGES THE SLIDER
console.log('user change');
}
}
You can see in this jsFiddle example that the slider's value is changed to 50, yet no log message is generated unless the user moves the slider. If you comment out the if condition you'll see the log message gets generated not only after the user changes the slider's value, but when you make a change to the value programmatically.
Maybe you can call the slider method passing a new configuration, which probably would be exactly the same object you are passing as parameter, but with the "value" field changed.
I have done a test in one of my old projects and it worked for me.
Related
I am testing code that contains a mat-slider and I cannot get the test to set the value of the slider or move the slider.
I have tried various things, including these:
Cypress: set attribute value
How do interact correctly with a range input (slider) in Cypress?
https://github.com/cypress-io/cypress/issues/1570
No luck so far. Is there any other way?
The problem is that mat-slider is not an input=range... When moving the slider, the attribute that changes is the aria-valuenow. I tried setting that and triggering change or input but it hasn't worked so for.
Do I need to work with mousemove etc.?
You could set the focus to the slider and use the arrow keys to increase/decrease the value.
If you have a slider with label "Some slider", initial value of 0 and step 1, the following code would get your value to 3 :).
cy.findByLabelText("Some slider")
.focus()
.type("{rightarrow}{rightarrow}{rightarrow}");
These are all the keys you can use:
https://docs.cypress.io/api/commands/type#Arguments
https://docs.cypress.io/api/commands/focus#Usage
I am using this in a project on cypress 7.4.0
In Vaadin 12, I have created a button which, when clicked, sets the split layout position to some non-zero, non-100 value, as shown below:
btnHelp.addClickListener(event -> {
log.info("info pressed");
MainApp.sp.setSplitterPosition(80);
MainApp.iFrameHelp = new Html( "<iframe src=\"https://docs.readthedocs.io/en/latest/intro/getting-started-with-sphinx.html/intro/getting-started-with-sphinx.html\"></iframe>");
//btnHelp.setIcon(new Icon(VaadinIcon.INFO_CIRCLE));
});
This works great. However, if I pretend to be a user and, via the Chrome browser, I adjust the split layout (by dragging the vertical layout) such that I "close" (or just reduce the size of) the second vertical "panel", and THEN I click on the button again, it does NOT seem to obey the command to reset the splitter position to 80. It only seems to obey the command on the first call. Is this a bug? If so, is there a workaround? (Or, should I do this differently?)
This is a side effect of https://github.com/vaadin/vaadin-split-layout-flow/issues/50. What happens is basically that the server-side still believes that the split position is set to 80 which makes it ignore the setSplitterPosition(80) call.
You can work around this by using low-level APIs to set the position in a way that bypasses the server's dirty checking logic:
MainApp.sp.getPrimaryComponent().getElement().executeJavaScript(
"this.style.flexBasis='80%'");
MainApp.sp.getSecondaryComponent().getElement().executeJavaScript(
"this.style.flexBasis='20%'");
I am using the jQueryUI resizable widget, and have a bunch of resizable boxes on a page. When the document loads, I initialize the widget, like so:
$('.ui-draggable').resizable({
minHeight: 10, // 10 is actually the default
minWidth: 10, // 10 is actually the default
resize: function() {
showProperties(this);
},
});
However, at some point I want only some of those elements to change resize options. What I'm trying to do is this:
if (type == 'sometype')
{
console.log($('#'+elementID).resizable('option', 'handles'));
$('#'+elementID).resizable('option', 'handles', 'e,w');
console.log($('#'+elementID).resizable('option', 'handles'));
}
This indeed outputs:
e,s,se
e,w
in the console, so the event is triggered and the selector is correct, but the code doesn't actually work: in fact, the handles remain the same, namely e, s, se.
Is this because I'm using a different selector from the original init? If so, how can I change the resize options only on a subset of originally-resizable elements? And if not, what could be the problem?
Handles are actually divs added to the element on which resizable is applied. It seems that changing the option doesn't refresh these handles. Maybe there's a way to apply the changes on specific subset and refresh, but I'm not sure how.
But one quick workaround would be to hide the handles you don't want instead of changing the handle option. You would have to set handle option to all the handles you'll need, and then hide those not wanted. Like this to remove se handle for example:
$('#'+elementID).find('.ui-resizable-se').hide();
I have two Meteor.Collections in my app. One contains a bunch of "slider" objects, which define a title, max, min, base value, and step for each slider. Now, I have two problems. The first is making the sliders show up in the first place. I've tried to put the following code:
Sliders.find().forEach(function(slider) {
$("#"+slider._id).slider({
min:slider.min,
max:slider.max,
value:slider.base,
step:slider.step,
change:function(event,ui) {
Data.update({_id:Data.findOne({slider:event.target.id})._id}, {$set:{value:ui.value}});
}
});
});
in Meteor.startup, at the end of my client.js file, in a $(document).ready() block, and nothing seems to get it to work. When I paste it into the javascript console, however, it works. Anyways, that's my first problem.
My second problem is that whenever I slide the slider, the slider disappears. I can keep dragging the mouse around to change the value, but once I let go of the clicker, I can't change the value anymore. I've tried using the above way and calling a Meteor.method that changes it on the server side. It's the fact that I'm updating a collection that is published to the same client that makes the slider disappear. Anything short of that doesn't cause it to disappear. How should I deal with this?
Thanks!
Have you already tried using the Template.preserve method? http://docs.meteor.com/#template_preserve
Is there a way to set by how much the slider moves when someone presses page up or page down? Currently, my slider moves by a value which is equivalent to one fifth of the slider range. I would like to set it to move by, say, 10 steps. Is there a way to do it?
You have to use the 'step' option for that:
$( "#slider" ).slider({
value:100,
min: 0,
max: 500,
step: 50
});
To solve the page up/ page down strange behavior, try this: http://jsfiddle.net/SPDBw/
From version 1.8. to 1.11., they've put the variable numPages inside the ui.slider container, and fixed it to 5.
Even if you override the keyCode handler to recognize the keys "PageUp" and 'PageDown" wouldn't fix the problem.
BUT, as a workaround, you can override this variable, contained in the prototype scope of the slider widget, at the beggining of your page load.
Pros: I don't need to worry about fetching the objects' max and min values
Cons: Solution is only a workaround, and solution can(and will) be broken in a future patch.
What I did was:
$(document).ready(function() {
$.ui.slider.prototype.numPages = 10;
});
Hope it works ;)