Cannot change variable using click event with jQuery - javascript

I am trying to change global variable finish from false to true using click event in order to prevent hovering the circles.
After I use click event, my global variable finish did not change (it is still false) and I can still do hovering over some circles.
Why is that happening?
var finish = false;
$( ".rating-circle" ).click( function() {
$( this ).addClass( "rating-chosen" );
$( this ).prevAll().addClass( "rating-chosen" );
finish = true;
});
if ( finish == false )
{
$( ".rating-circle" ).hover(
function() {
$( this ).addClass( "rating-hover" );
$( this ).prevAll().addClass( "rating-hover" );
},
function() {
$( this ).removeClass( "rating-hover" )
$( this ).prevAll().removeClass( "rating-hover" );
} );
}
body {
font-family: Verdana;
}
h1, h2, h3 {
color: darkblue;
}
.rating-circle {
height: 2em;
width: 2em;
border: .1em solid black;
border-radius: 1.1em;
display: inline-block;
margin: 0;
padding: .1em;
}
.rating-hover {
background-color: yellow;
}
.rating-chosen {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Finding elements using jQuery</h2>
<h3>Rate this session</h3>
<div id="rating-container">
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
</div>

The problem is that your checking logic takes place above your hover event binding, so it is only evaluated once when the code is first run. You need to check the finish flag within the handler function itself, or you could just unbind the handlers on click.
$( ".rating-circle" ).hover(function() {
if (finish) return;
$( this ).addClass( "rating-hover" );
$( this ).prevAll().addClass( "rating-hover" );
}, function() {
$( this ).removeClass( "rating-hover" )
$( this ).prevAll().removeClass( "rating-hover" );
} );
Also, it would be more idiomatic/semantic to name your flag something like finished or hasFinished.

Your global variable does change, but it's too little too late, by that time the event handlers are already bound, and the condition doesn't matter.
As you're adding a unique class anyway on click, you could just check for that class inside the hover events
$(".rating-circle").click(function() {
$(this).addClass("rating-chosen");
$(this).prevAll().addClass("rating-chosen");
});
$(".rating-circle").hover(
function() {
if ($(".rating-circle.rating-chosen").length === 0) {
$(this).addClass("rating-hover");
$(this).prevAll().addClass("rating-hover");
}
},
function() {
if ($(".rating-circle.rating-chosen").length === 0) {
$(this).removeClass("rating-hover")
$(this).prevAll().removeClass("rating-hover");
}
});
body {
font-family: Verdana;
}
h1,
h2,
h3 {
color: darkblue;
}
.rating-circle {
height: 2em;
width: 2em;
border: .1em solid black;
border-radius: 1.1em;
display: inline-block;
margin: 0;
padding: .1em;
}
.rating-hover {
background-color: yellow;
}
.rating-chosen {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Finding elements using jQuery</h2>
<h3>Rate this session</h3>
<div id="rating-container">
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
</div>

var finish = false;
$( ".rating-circle" ).click( function() {
$( this ).addClass( "rating-chosen" );
$( this ).prevAll().addClass( "rating-chosen" );
finish = true;
});
$( ".rating-circle" ).hover( function() {
if ( finish == false ){
$( this ).addClass( "rating-hover" );
$( this ).prevAll().addClass( "rating-hover" );
}
},function(){
if ( finish == false ){
$( this ).removeClass( "rating-hover" )
$( this ).prevAll().removeClass( "rating-hover" );
}
});
body {
font-family: Verdana;
}
h1, h2, h3 {
color: darkblue;
}
.rating-circle {
height: 2em;
width: 2em;
border: .1em solid black;
border-radius: 1.1em;
display: inline-block;
margin: 0;
padding: .1em;
}
.rating-hover {
background-color: yellow;
}
.rating-chosen {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Finding elements using jQuery</h2>
<h3>Rate this session</h3>
<div id="rating-container">
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
<div class="rating-circle"></div>
</div>

Related

jQuery UI sortable prevent drop into connected sortable if item has already some childs

I need your help. I'm currently trying to make a sortable list of items. Each item can also be a child item of another one:
(function ( $ ) {
$( document ).ready( function () {
$( '#import-sort-wrapper' ).sortable( {
placeholder: 'sortable-placeholder',
connectWith: '.import-sort-item-variations',
start: function ( e, ui ) {
ui.placeholder.height( ui.item.height() );
},
beforeStop: function ( e, ui ) {
console.log( 'before stop' );
// Check if product has already variations
if (ui.item.find( '.import-sort-item-variations:first li' ).length > 0) {
$( ui.sender ).sortable( 'cancel' );
}
},
stop: function ( e, ui ) {
let itemVariations = ui.item.find( '.import-sort-item-variations:first' );
// Check if item is variable product and display / hide variations list
if (ui.item.closest( '.import-sort-item-variations' ).length === 1) {
// itemVariations.empty();
itemVariations.hide();
} else {
itemVariations.show();
}
}
} );
$( '.import-sort-item-variations' ).sortable( {
placeholder: 'sortable-placeholder',
connectWith: '#import-sort-wrapper',
start: function ( e, ui ) {
ui.placeholder.height( ui.item.height() );
},
stop: function ( e, ui ) {
let itemVariations = ui.item.find( '.import-sort-item-variations:first' );
// Show variation option again in case item is moved out of variation list
if (ui.item.closest( '.import-sort-item-variations' ).length === 0) {
itemVariations.show();
}
}
} );
} );
});
#import-sort-wrapper {
text-align: left;
display: flex;
flex-direction: column;
list-style-type: none;
margin: 0;
padding: 0;
}
#import-sort-wrapper li {
font-size: 14px;
line-height: 1.5;
position: relative;
padding: 10px 15px;
margin: 9px 0 0;
cursor: move;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
box-sizing: border-box;
}
#import-sort-wrapper li.import-sort-item {
background: #f6f7f7;
border: 1px solid #dcdcde;
}
#import-sort-wrapper li.import-sort-item .import-sort-item-header .sort-item-header-id {
font-weight: 600;
}
#import-sort-wrapper li.import-sort-item .import-sort-item-header .sort-item-header-type {
color: #50575e;
font-style: italic;
font-weight: 400;
margin-left: 4px;
font-size: 13px;
}
#import-sort-wrapper li.import-sort-item .import-sort-item-variations {
border: 1px solid #dcdcde;
min-height: 30px;
background: #ffffff;
margin-top: 10px;
}
#import-sort-wrapper li.import-sort-item .import-sort-item-variations li {
margin: 10px;
}
#import-sort-wrapper li.ui-sortable-placeholder {
border: 1px dashed #c3c4c7;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<ul id="import-sort-wrapper">
<li class="import-sort-item">
<span class="import-sort-item-header">
<span class="sort-item-header-id">30:</span>
<span class="sort-item-header-name">Testprodukt</span>
<span class="sort-item-header-type">Variables Produkt</span>
</span>
<ul class="import-sort-item-variations">
</ul>
</li>
<li class="import-sort-item">
<span class="import-sort-item-header">
<span class="sort-item-header-id">28:</span>
<span class="sort-item-header-name">Erdbeeren</span>
<span class="sort-item-header-type">Variables Produkt</span>
</span>
<ul class="import-sort-item-variations">
</ul>
</li>
<li class="import-sort-item">
<span class="import-sort-item-header">
<span class="sort-item-header-id">29:</span>
<span class="sort-item-header-name">Variables Produkt</span>
<span class="sort-item-header-type">Variables Produkt</span>
</span>
<ul class="import-sort-item-variations">
</ul>
</li>
</ul>
Now I somehow want to prevent any drag-n-drop of an element which already has some childs into another main element. It should only be possible if the element which should be dragged has no childs! I've tried checking some things inside the beforeStop callback, but somehow I don't get this thing working correctly. Any ideas? Maybe I'm on the wrong way and this is not possible...
if you change your code
beforeStop: function ( e, ui ) {
console.log( 'before stop' );
// Check if product has already variations
if (ui.item.find( '.import-sort-item-variations:first li' ).length > 0) {
$( ui.sender ).sortable( 'cancel' );
}
},
To :
beforeStop: function ( e, ui ) {
console.log( 'before stop' );
// Check if product has already variations
if (ui.item.find( '.import-sort-item-variations:first li' ).length > 0) {
$( '#import-sort-wrapper' ).sortable('cancel')
}
},
Is that what you want? ?
I've found the solution. Thanks to Funky for the hint. Also I've moved the function to the child sortable and used a different callback received since sortable('cancel') causes some JS errors when used in beforeStop:
receive: function ( e, ui ) {
console.log( ui.sender );
// Check if product has already variations
if (ui.item.find( '.import-sort-item-variations:first li' ).length > 0) {
$( '#product-import-sort-wrapper' ).sortable( 'cancel' );
}
}

how to get class of a dragged item after been received by the target sortable?

$(".target").droppable({
connectWith: ".connected",
drop: function (event, ui) {
var targetId = event.target.id;//--> id of the target (where elements will be dropped into)
var orderId;//--> id of the dragged element (NOT the targetId)
if ($(this).hasClass("source connected")) {
orderId = sourceElementSo;
}
else {
orderId = $(ui.draggable).attr("id");
};
i've tried ui.item and ui.draggable, but no success
PS: Newbie :)
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
connectWith: ".connected",
drop: function( event, ui ) {
var targetId = event.target.id;//--> id of the target (where elements will be dropped into)
var orderId;//--> id of the dragged element (NOT the targetId)
if (ui.draggable.hasClass("connected")) {
console.log("ok");
orderId = sourceElementSo;
}
else {
orderId = $(ui.draggable).attr("id");
};
}
});
});
#draggable { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
#droppable { width: 150px; height: 150px; padding: 0.5em; float: left; margin: 10px; }
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div id="draggable" class="ui-widget-content connected">
<p>Drag me to my target</p>
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop here</p>
</div>

Expanding Search Bar

I'm developing a webpage of videos, like YouTube or Vimeo...
I'm working now in a search input... I was searching in Google about guides and I found this one: http://tympanus.net/codrops/2013/06/26/expanding-search-bar-deconstructed/
I have almost done it, but the problem is, the guy who posted it, did it with Javascript, not with JQuery (easier...)
I have been trying to modify the code, the search input appears when you click on the button, but it doesn't dissapear...
Could you help me in this part?
Javascript:
;( function( window ) {
function UISearch( el, options ) {
this.el = el;
this.inputEl = el.querySelector( 'form > input.sb-search-input' );
this._initEvents();
}
UISearch.prototype = {
_initEvents : function() {
var self = this,
initSearchFn = function( ev ) {
if( !classie.has( self.el, 'sb-search-open' ) ) { // open it
ev.preventDefault();
self.open();
}
else if( classie.has( self.el, 'sb-search-open' ) && /^\s*$/.test( self.inputEl.value ) ) { // close it
self.close();
}
}
this.el.addEventListener( 'click', initSearchFn );
this.inputEl.addEventListener( 'click', function( ev ) { ev.stopPropagation(); });
},
open : function() {
classie.add( this.el, 'sb-search-open' );
},
close : function() {
classie.remove( this.el, 'sb-search-open' );
}
}
// add to global namespace
window.UISearch = UISearch;
} )( window );
My JQuery code:
$(document).ready(function () {
$("#search_container").click(function(){ if(!$("#search_container").hasClass("open")){ $("#search_container").addClass("open"); } });
$(".search_input").click(function(){
if($("#search_container").hasClass("open")){
if($(".search_input").val() == ""){
$("#search_container").removeClass("open");
} else {
// Search
}
}
});
});
And my HTML code:
<div id="search_container">
<form>
<input type="search" class="search_input" placeholder="Búsqueda" id="search" value="" />
<input type="submit" class="search_submit" value="" />
<span class="btn icon_search"></span>
</form>
</div>
You can achieve it by combining a little css, and the .animate() function of jQuery.
Here is the JS part, see the fiddle for live demo
$(document).ready(function () {
$("#btnsearch").on('click',function(e){
e.preventDefault();
e.stopPropagation();
/* Check if field is already displayed, if not, displays it, else, submit */
if($('#search_container').hasClass('closed')){
$('#search_container').toggleClass('closed');
$('#hint').html('');
$('#search').animate({
right: '40px',
}, 200, function(){
/*
* Bind event to hide field when clicking OUT
* use .one() instead of .on() to avoid stacking binding click events on document
*/
$(document).one('click', function(){
$('#search_container').toggleClass('closed');
$('#search').animate({
right: '-200px',
}, 200);
$('#hint').html('');
});
});
}
else {
/* Add here your field entry check */
/* Submit your form with $('#myform').submit(); */
$('#hint').html("Your form has been submitted with $('#myform').submit();");
}
});
$('#search').on('click',function(e){
/* Needed to avoid closing field when clicking on it */
e.preventDefault();
e.stopPropagation();
});
});
LIVE DEMO HERE
Sliding effect can be achieved with CSS (or jQuery .animate({width: '100%'})). Also, you are removing class, but never adding it back.
$(document).ready(function() {
$('.input-wrapper')
.click(function() {
$(this).toggleClass('active');
$('input', this).focus();
})
.focusout(function() {
$(this).removeClass('active');
});
});
.wrapper {
width: 200px;
background-color: #ddd;
padding: 10px 25px;
}
.input-wrapper {
width: 25px;
height: 25px;
overflow: hidden;
position: relative;
float: right;
-webkit-transition: width .5s;
/* For Safari 3.1 to 6.0 */
transition: width .5s;
}
.input-wrapper input {
width: 100%;
border: none;
}
.input-wrapper.active {
width: 100%;
}
.input-wrapper:after {
content: '?';
width: 25px;
height: 25px;
text-align: center;
font-weight: bold;
background-color: red;
color: black;
line-height: 20px;
font-size: 20px;
display: block;
position: absolute;
right: 0;
top: 0;
}
.clear {
clear: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="input-wrapper">
<input type="text" placeholder="Enter your search term..." />
</div>
<div class="clear"></div>
<div class="input-wrapper">
<input type="text" placeholder="Enter your search term..." />
</div>
<div class="clear"></div>
<div class="input-wrapper">
<input type="text" placeholder="Enter your search term..." />
</div>
<div class="clear"></div>
<div class="input-wrapper">
<input type="text" placeholder="Enter your search term..." />
</div>
<div class="clear"></div>
</div>

jQuery focus is not working?

I have been trying to add focus function to my specific input i.e want to show a div on focus with class as : .search_by_name but it's not working so if you people please take a look at my code that what I am doing wrong please?
Here is code as :
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style>
.search_by_business_name {
background: #474747;
display: none;
width: 297px;
margin-left: 179px;
margin-top: 15px;
height: 15px;
position: absolute;
-webkit-animation: fadeIn 0.5s;
animation: fadeIn 0.5s;
}
.arrow-up_search_by_business_name {
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 8px solid #474747;
position: relative;
top: -8px;
left: 20px;
}
.search_by_business_name_text {
background: #99cc33;
font-family: Arial;
font-style: italic;
color: #fff;
padding: 7px;
font-size: 14px;
text-align: left;
padding-left: 15px;
margin-top: -4px;
}
</style>
<input type="text" class="search_input" id="search_by_business_name_input" placeholder="Hi Ruyben, what do you want to find today ?">
<div class="search_by_business_name">
<div class="arrow-up_search_by_business_name"></div><!-- end div arrow-up_search_by_business_name -->
<div class="search_by_business_name_text">Search by business name, or keyword</div><!-- end div search_by_business_name_text -->
</div><!-- end div search_by_business_name -->
<script>
$( "#search_by_business_name_input" ).focus(function() {
$( this ).next( ".search_by_business_name" ).css( "display", "block" );});
</script>
Please have a look at live version as : http://huntedhunter.com/waseem_jobs/pacific_site/index.html
As I explained in the comments, you should not use .next() as the element you are looking for is not the next sibling of the target element.
Also .focus() takes only one function as argument, you need to use .blur() to hide the element
$("#search_by_business_name_input").focus(function () {
$(".search_by_business_name").show();
}).blur(function () {
$(".search_by_business_name").hide();
});
The script should be inside the <body> tag.
In your page the script is after </body></html>
<script>
$( document ).ready(function() {
$( "#search_by_business_name_input" )
.focus(function() {
$( ".search_by_business_name" ).show();
})
.blur(function() {
$( ".search_by_business_name" ).hide();
});
});
</script>
</body>
</html>
Edit:
Of course it does not work.
Have you read the documentation for $.next()?
.next()
Description: Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
Replace this:
$( this ).next( ".search_by_business_name" ).css( "display", "block" );
With:
$( ".search_by_business_name" ).css( "display", "block" );
Edit2:
Wrap your code in $.ready:
$( document ).ready(function() {
$( "#search_by_business_name_input" )
.focus(function() {
$( ".search_by_business_name" ).show();
})
.blur(function() {
$( ".search_by_business_name" ).hide();
});
});
You should put
<script>
$( "#search_by_business_name_input" ).focus(function() {
$( ".search_by_business_name" ).show();
});
</script>
at the bottom of body element, because when excute this code,
$("#search_by_business_name_input" ) = []
or
you can write it like this
$(document).on("focus", "#search_by_business_name_input", function(){
$( ".search_by_business_name" ).show();
})

Display hidden container element - hover only works after I click the container

I have a situation like this set up:
http://jsfiddle.net/gz4Z7/2/
The difference in my situation is that all of the elements are created in javascript with document.createElement, and they are appended to the DOM of various webpages on the internet.
Everything works great except one thing: The hover functionality doesn't work until I click on the container. This only happens on some webpages.
My question is: What would cause the need to click on the container element in order for the hover functionality of its children to work? I have tried doing a focus() on the container element but it doesn't seem to make a difference.
Here is the fiddle code:
<input id="myInput" type="text"/>
<myContainer id="myContainer">
<outerThing id="outerThing">
<myThing id="myThing"></myThing>
</outerThing>
</myContainer>
<button type="button" onclick="buttonClick()">show container</button>
#myContainer {
position: absolute;
top:100px;
bottom:auto;
right:auto;
left:100px;
width:200px;
height:200px;
display: none;
background-color: red;
}
#outerThing{
width:50px;
height:50px;
margin-top: 10px;
margin-left: 10px;
display: block;
background-color: white;
}
#myThing{
width:20px;
height:20px;
margin-top: 15px;
margin-left: 15px;
display: none;
background-color: blue;
}
function buttonClick() {
document.getElementById("myInput").focus();
var cont = document.getElementById("myContainer");
cont.style.display = "block";
var outerThing = document.getElementById("outerThing");
$( outerThing ).hover(
function()
{
$(this).children(":last").css( "display", "inline-block" );
},
function()
{
$(this).children(":last").css( "display", "none" );
});
}
$(document).ready(function({
function buttonClick() {
document.getElementById("myInput").focus();
var cont = document.getElementById("myContainer");
cont.style.display = "block";
var outerThing = document.getElementById("outerThing");
$( outerThing ).hover(
function()
{
$(this).children(":last").css( "display", "inline-block" );
},
function()
{
$(this).children(":last").css( "display", "none" );
});
}
});
Like this

Categories

Resources