How to use star rating (input) field many times in a page - javascript

I am new to jquery. I want to use this star rating(input) field several times in a page with same ids(as it will come dynamic). Please let me know how i do this.
Jsfiddle: http://jsfiddle.net/9xrkr/
<script src="http://www.radioactivethinking.com/rateit/src/jquery.rateit.js"></script>
<input type="range" min="0" max="5" value="0" step="1" id="backing1">
<div class="rateit" id="rateitHover" data-rateit-backingfld="#backing1" data-rateit-step="1" >
<span class="tooltip" style="float:right; padding-left:10px;"></span>
</div>
<script>
var tooltipvalues = ['Bad', 'Poor', 'Average', 'Good', 'Excellent'];
var valueToDisplay
$("#rateitHover").bind('over', function (event, value) {
$('.tooltip').text(tooltipvalues[value - 1]);
});
$("#rateitHover").bind('reset', function () {
$('.tooltip').text('');
$('#rateitHover').rateit('value')
});
$("#rateitHover").bind('rated', function (event, value) {
$('.tooltip').text('R: ' + tooltipvalues[value - 1]);
});
$('#rateitHover').bind('mouseleave', function() {
var v = $('#rateitHover').rateit('value');
if (v == 0) {
$('.tooltip').html('');
} else {
$('.tooltip').html('R: ' + tooltipvalues[v - 1]);
}
});
</script>

You must use classes (not the unique id of the element)
Try this:
HTML
<input type="range" min="0" max="5" value="0" step="1" id="backing1">
<input type="range" min="0" max="5" value="0" step="1" id="backing2">
<div class="rateit" id="rateitHover1" data-rateit-backingfld="#backing1" data-rateit-step="1" >
<span class="tooltip" style="float:right; padding-left:10px;"></span>
</div>
<div class="rateit" id="rateitHover2" data-rateit-backingfld="#backing2" data-rateit-step="1" >
<span class="tooltip" style="float:right; padding-left:10px;"></span>
</div>
JAVASCRIPT
var tooltipvalues = ['Bad', 'Poor', 'Average', 'Good', 'Excellent'];
var valueToDisplay
$(".rateit").bind('over', function (event, value) {
$(this).find('.tooltip').text(tooltipvalues[value - 1]);
});
$(".rateit").bind('reset', function () {
$(this).find('.tooltip').text('');
$(this).rateit('value')
});
$(".rateit").bind('rated', function (event, value) {
$(this).find('.tooltip').text('R: ' + tooltipvalues[value - 1]);
});
$('.rateit').bind('mouseleave', function() {
var v = $(this).rateit('value');
if (v == 0) {
$(this).find('.tooltip').html('');
} else {
$(this).find('.tooltip').html('R: ' + tooltipvalues[v - 1]);
}
});
Fiddle
http://jsfiddle.net/9xrkr/1/

Try changing ids to classnames, and try narrowing the selectors to relate to this, which should relate to the element that is triggered:
$('#rateitHover')
changes to:
$('.rateit')
Also, you need to get the tooltip that is within the element:
$('.tooltip')
changes to:
$(this).find('.tooltip')
And the $('#rateitHover').rateit('value') should be changed to $(this).rateit('value')
UPDATE
Apparently, since this is all served up dynamically, you can't make the above adjustments. Therefore, I would recommend you use a different script.
I've made something for this purpose in the past: http://codepen.io/bozdoz/pen/ClmLI
See if this code would suit your purposes. Notice that the stars all have classes, instead of ID's. It should be easier to manipulate. Hope this helps (someone). :)
HTML:
<div class="clearfix stars">
<div class="darn">Oh no!</div>
<div class="brilliant">Thanks!</div>
<div class="starHolder">
<div class="star">
<div class="star">
<div class="star">
<div class="star">
<div class="star"></div>
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
.stars {width:450px;margin:5% auto;position:relative}
.star {width:66px;height:50px;background:url(http://www.prportfolio.ca/bjd/images/star.png) no-repeat;cursor:pointer;transition: all .5s;-moz-transition: all .5s; -webkit-transition: all .5s; -o-transition: all .5s;}
.star:hover, .star.on {background-position: -66px 0px;}
.star .star { margin-left: 66px; }
.starHolder {width:345px;margin:0 auto;}
.darn {color:#5c2222}
.brilliant {color:#a0b9d8;right:0px}
.darn, .brilliant {line-height:50px;font-weight:bold;display:none;position:absolute}
JS (jQuery):
$('.star').click(function(e){
e.stopPropagation();
var i = $('.stars .star').index(this);
if(i==0||i==5){
$(this).parents('.stars').find('.darn').show().delay(100).fadeOut(1000);
}
if(i==4||i==9){
$(this).parents('.stars').find('.brilliant').show().delay(100).fadeOut(1000);
}
$(this).addClass('on').find('.star').removeClass('on').end().parents('.star').addClass('on');
});

Related

How to disable all elements within a div using jquery

I have a div and when a checkbox is clicked I want to disable all the elements inside the div, including disabling the onClick of one of the elements. Here is the codepen: https://codepen.io/anon/pen/JVwMOq
HTML:
<input type="checkbox" onChange="checkMe(this)">
<div id="test">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe()">
</span>
</div>
JS:
function checkMe(element){
if($(element).prop('checked') === true){
$('#test').prop('disabled', true).off("click");
}
else{
$('#test').prop('disabled', false).on("click");
}
}
Any advice? Thanks!
You can use this, disabled with CSS.
you can't add disabled on div, it's working with input, etc..
$('#clickCheckbox').change(function() {
if($(this).is(":checked")) {
$('#test').addClass('disable-button');
}else{
$('#test').removeClass('disable-button')
}
$('#clickCheckbox').val($(this).is(':checked'));
});
.disable-button {
pointer-events: none;
cursor: not-allowed;
text-decoration: none;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="clickCheckbox">
<div id="test">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe()">
</span>
</div>
I have a working solution below.
I have added in an additional input field to check it works on multiple items.
I created an checking function to see if your item is checked.
const isChecked = (element) => document.getElementById(element.id).checked ? true : false
Then updated the likeMe function to pass in the current id and returned null if the checkbox is checked.
function likeMe(element) {
if (isChecked(element)) {
return null
} else {
console.log('Calling likeMe()');
}
}
Then I updated your checkMe function to pass in the current element and the targetdiv so this would be more reusable across other parts of your code.
function checkMe(element, targetDiv) {
const targetDivInput = `#${targetDiv} input`
const targetDivClassName = `.${targetDiv}`
if (isChecked(element)) {
$(targetDivInput).prop('disabled', true);
$(targetDivClassName).toggleClass('disabled')
} else {
$(targetDivInput).prop('disabled', false);
$(targetDivClassName).toggleClass('disabled')
}
}
Then made some small changes to the markup to pass in the ids into your functions
<div id="test">
<input type="text">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe('test')">
</span>
</div>
and added a disabled state to your css so the user wouldn't see the cursor.
#like{
cursor: pointer;
}
.disabled #like {
cursor: inherit;
}
This is the final result.
#like{
cursor: pointer;
}
.disabled #like {
cursor: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
const isChecked = (element) => document.getElementById(element.id).checked ? true : false
function likeMe(element) {
if (isChecked(element)) {
return null
} else {
console.log('Calling likeMe()');
}
}
function checkMe(element, targetDiv) {
const targetDivInput = `#${targetDiv} input`
const targetDivClassName = `.${targetDiv}`
if (isChecked(element)) {
$(targetDivInput).prop('disabled', true);
$(targetDivClassName).toggleClass('disabled')
} else {
$(targetDivInput).prop('disabled', false);
$(targetDivClassName).toggleClass('disabled')
}
}
</script>
<input id="textCheck" type="checkbox" onChange="checkMe(this,'test')">
<div id="test">
<input type="text">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe('test')">
</span>
</div>

Range slider with min and max values limites

I have this code, which displays a range slider with values from 1 to 100 and 4 squares of different values, i have the minimum value limite handler on the range line, as i increase the value using the handler, the squares that are bellow that value start the disapeer.
Now i want to add the maximum handler limite on the same line. ( One line with 2 handlers )
Anybody knows how ?
Thanks.
function sliderChange(val) {
document.getElementById('sliderStatusMin').innerHTML = val;
function displayItem(val) {
$('.item').filter(function() {
var price = $(this).data('price');
if (price < val) {
return price;
}
}).hide();
$('.item').filter(function() {
var price = $(this).data('price');
if (price > val) {
return price;
}
}).show();
}
displayItem(val);
}
.item {
width: 100px;
height: 100px;
background-color: red;
}
<!DOCTYPE html>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous">
</script>
<input class="first" type="range" min="0" max="100" value="50" step="2" onChange="sliderChange(this.value)" />
<br /><br /> Minimum Value = <span id="sliderStatusMin"></span>
<div class="item" data-price="90">90</div>
<div class="item" data-price="20">20</div>
<div class="item" data-price="70">70</div>
<div class="item" data-price="40">40</div>
Take a look at the jQuery UI http://jqueryui.com/slider/#range
or
take a look at this answer https://stackoverflow.com/a/31083391/7993505 for a variant without jQuery UI.

Bootstrap Slider starting from same point while changing the main

I am implementing the bootstrap slider, and involving TOP DOWN Approach to handle it i.e when the SUM slider is adjusted the value is propagated to both the sliders below it. And also the changes made to the bottom sliders will effect affects the SUM slider.
Everything is working fine, except when I am sliding the SUM slider, both the below sliders are starting from the same value, which I don't want to re-adjusted but to start from the same point of their current value.
Is there any way to fix that.
Here is the Working Fiddle.Try to slide the SUM slider, both the below slider will come to same point which I don't want. The SUM slider is to be distributed equally among two below but not from the same point i.e same value.
.html
<div class = "row">
<div class = "col-md-12">
<div class="wrapper4">
<p style = "text-align:center">
</div>
<div class = "col-md-12">
<div class = "col-md-4">
<div class="wrapper">
<hr />
<p>
SUM
</p>
<input id="ex1" data-slider-id='ex1Slider' type="text" data-slider-min="0" data-slider-max="80" data-slider-step="0.2" style="text-align: center"/>
<hr />
<input id="ex2" data-slider-id='ex2Slider' type="text" data-slider-min="0" data-slider-max="20" data-slider-step="0.1" data-slider-orientation="vertical" />
<input id="ex3" data-slider-id='ex3Slider' type="text" data-slider-min="0" data-slider-max="20" data-slider-step="0.1" data-slider-orientation="vertical" />
</div>
</div>
</div>
</div>
.js
$('#ex1').slider({
value : 17.5,
formatter: function(value) {
return 'AB: ' + value;
}
});
$('#ex2').slider({
value : 7.5,
tooltip_position:'bottom',
reversed : true,
formatter: function(value) {
return 'A: ' + value;
}
});
$('#ex3').slider({
value : 10,
reversed : true,
formatter: function(value) {
return 'B: ' + value;
}
})
// If you want to change slider main
$("#ex2,#ex3").on("slide", function() {
$('#ex1').slider('setValue', $('#ex2').slider('getValue') + $('#ex3').slider('getValue'));
});
// TOP DOWN APPROACH
$("#ex1").on("slide", function() {
$('#ex2,#ex3').slider('setValue', $('#ex1').slider('getValue')/2);
});
You can inverse the addition in the callback function for the slide event on $ex1 and keeping track of the values of $ex2 and $ex3. I've set the second parameter to setValue to false. According to the docs this should ensure not to trigger the slide event on those sliders. This is why i'm updating ex2Val and ex3Val on the slideStop event of $ex1.
Hope that makes sense. Just take a look at the snippet and you'll get the idea.
;)
var $ex1 = $('#ex1');
var $ex2 = $('#ex2');
var $ex3 = $('#ex3');
var ex2Val = 7.5;
var ex3Val = 10.5;
$ex1.slider({
value : ex2Val + ex3Val,
formatter: function(value) {
return 'AB: ' + value;
}
});
$ex2.slider({
value : ex2Val,
tooltip_position:'bottom',
reversed : true,
formatter: function(value) {
return 'A: ' + value;
}
});
$ex3.slider({
value : ex3Val,
reversed : true,
formatter: function(value) {
return 'B: ' + value;
}
})
// If you want to change slider main
$ex2.on("slide", function(evt) {
ex2Val = evt.value;
$ex1.slider('setValue', (ex2Val + ex3Val));
});
$ex3.on("slide", function(evt) {
ex3Val = evt.value;
$ex1.slider('setValue', (ex2Val + ex3Val));
});
// TOP DOWN APPROACH
$ex1.on("slide", function(evt) {
$ex2.slider('setValue', evt.value - ex3Val, false);
$ex3.slider('setValue', evt.value - ex2Val, false);
});
$ex1.on("slideStop", function(evt) {
ex2Val = $ex2.slider('getValue');
ex3Val = $ex3.slider('getValue');
});
#import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css');
#import url('https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.1.0/css/bootstrap-slider.css');
.wrapper {
padding : 0px;
margin-top: 0px;
}
.wrapper4 {
padding : 0px 30px 0px 30px;
margin-top: 10px;
}
#ex2Slider, #ex3Slider, #ex4Slider, #ex5Slider, #ex17Slider{
margin-right :20px;
}
#ex1Slider .slider-selection {
background: #ff6666;
}
#ex1Slider .slider-handle, #ex2Slider .slider-handle, #ex3Slider .slider-handle {
background: #ff6666;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/7.1.0/bootstrap-slider.js"></script>
<div class = "row">
<div class = "col-md-12">
<div class = "col-md-4">
<div class="wrapper">
<hr />
<p>SUM</p>
<input id="ex1" type="text" style="text-align: center"
data-slider-id='ex1Slider'
data-slider-min="0" data-slider-max="80"
data-slider-step="0.2"/>
<hr />
<input id="ex2"
data-slider-id='ex2Slider'
type="text"
data-slider-min="0"
data-slider-max="20"
data-slider-step="0.1"
data-slider-orientation="vertical" />
<input id="ex3"
data-slider-id='ex3Slider'
type="text"
data-slider-min="0"
data-slider-max="20"
data-slider-step="0.1"
data-slider-orientation="vertical" />
</div>
</div>
</div>
</div>

Cannot read property 'addEventListener' of null on slider

I have a slider which when the mouse move event is fired by it I want to display its value inside a paragraph.
This is the code I am using:
var exit = document.getElementsByTagName("p");
var slide = document.getElementById('slider');
window.addEventListener("load", function(){
slide.addEventListener("mousemove", function() {
console.log(slide.value);
});
Html
<input type="range" value="0" min="0" max="10" id="slider">
<p></p>
My problem is that I get this error:
"Cannot read property 'addEventListener' of null"
Any ideas?
I think you want to add an event listener for an input event not a mousemove event.
The input event fires when the range input changes value not when the mouse just happens to be moving over the range selector.
As pointed out by #Gersey, the input event will be fired when the user changes the value with the arrow keys.
Here is a demo that highlights the issue
window.onload = function() {
var slide = document.getElementById('slider'),
p1 = document.querySelector('#oninput'),
p2 = document.querySelector('#onmousemove');
slide.addEventListener("input", function() {
p1.textContent += ' ' + slide.value;
});
slide.addEventListener("mousemove", function() {
p2.textContent += ' ' + slide.value;
});
};
div.display {
display: inline-block;
width: 40%;
height: 200px;
border: 1px solid black;
}
div {
overflow: hidden;
}
<input type="range" value="0" min="0" max="10" id="slider" />
<div>
<div class="display" id="oninput"></div>
<div class="display" id="onmousemove"></div>
</div>
move the line
var slide=document.getElementById('slider');
into your window load callback. The problem may be that the dom is not loaded when you init the slide, so its not there.
Try this bro ..
var exit = document.getElementsByTagName("p");
var slide = document.getElementById('slider');
slide.addEventListener("mousemove", function() {
console.log(slide.value);
$('p').text('value : '+slide.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="range" value="0" min="0" max="10" id="slider">
<p></p>

jQuery miniColors colorpicker not positioned right

I am using jQuery miniColors colorpicker but in the sample code the picker appears right next to the field and button, in my case it appears at the very bottom of my document, it is as if it can't read in the position data of the button calling it.
Anyone had a similar issue with this plugin?
Here is what my code looks like (before jQuery initializes this as a color-picker)
<p style='position:absolute;top:0px;left:0px;margin-left:10px;'>
<input type='text' class='color-picker miniColors' name='data_0' id='data_0' size='6' value='".$data[0]."' />
</p>
. And after I run this code on it.
$('#data_0').miniColors({
change: function(hex, rgb) { $('#slide_bg').css("background-color",hex); }
});
. It looks like this.
<p style="position:absolute;top:0px;left:0px;margin-left:10px;">
<input type="text" class="color-picker miniColors" name="data_0" id="data_0" size="6" value="#ffffff" maxlength="7" autocomplete="off">
<span class="miniColors-triggerWrap">
<a class="miniColors-trigger" style="background-color: #ffffff" href="#"></a>
</span>
</p>
. And the actual colorpicker gets inserted at the very last of my (so right before the and looks like this:
<div class="miniColors-selector color-picker miniColors" style="left: 116px; ">
<div class="miniColors-hues">
<div class="miniColors-huePicker" style="top: 0px; "></div>
</div>
<div class="miniColors-colors" style="background-color: rgb(255, 0, 0); ">
<div class="miniColors-colorPicker" style="top: -5px; left: -5px; ">
<div class="miniColors-colorPicker-inner"></div>
</div>
</div>
</div>
. And appears below the footer of my page =(
As you can see it has a value for left:116px but nothing for the vertical positioning.
Please consider trying MiniColors 2.0, which changes the way positioning is handled for the dropdown. This version is a complete rewrite of the original one. We also added a number of new features that you may find useful.
Try putting the field inside a paragraph and define the position of paragraph with css and it will work.
E.g. -
<p style="position: absolute; left: 100; top: 100; margin-left: 10px;">
<input type="input" name="color-picker" class="color-picker" size="7" />
</p>
SOLUTION:
This is how I solved it. Solution is a bit jerky though.
I used show callback and add remove classes based on view
// add jquery function removeClassPrefix
$.fn.removeClassPrefix = function(prefix) {
this.each(function(i, it) {
var classes = it.className.split(' ').map(function(item) {
return item.indexOf(prefix) === 0 ? '' : item;
});
it.className = classes.join(' ');
});
return this;
};
// add more selector expressions to jquery
$.extend($.expr[':'], {
'off-top': function(el) {
return $(el).offset().top < $(window).scrollTop();
},
'off-right': function(el) {
return $(el).offset().left + $(el).outerWidth() - $(window).scrollLeft() > $(window).width();
},
'off-bottom': function(el) {
return $(el).offset().top + $(el).outerHeight() - $(window).scrollTop() > $(window).height();
},
'off-left': function(el) {
return $(el).offset().left < $(window).scrollLeft();
}
});
// use show event
$('#div_id').miniColors({
theme: 'bootstrap',
show: function() {
var $input = $(this);
var $minicolors = $input.parent();
var $panel = $minicolors.find('.minicolors-panel');
var classPrefix = 'minicolors-position-';
$minicolors.removeClassPrefix(classPrefix);
if ($panel.is(':off-top')) {
$minicolors.addClass(classPrefix + 'bottom');
}
if ($panel.is(':off-bottom')) {
$minicolors.addClass(classPrefix + 'top');
}
if ($panel.is(':off-left')) {
$minicolors.addClass(classPrefix + 'right');
}
if ($panel.is(':off-right')) {
$minicolors.addClass(classPrefix + 'left');
}
}
});

Categories