Javascript/Jquery logic regarding changing classes in different areas - javascript

I am trying to figure something out. I have 10 buttons. A button looks like the following but with different classes
<button id="1" class="btn active"></button>
Now each of these buttons are in an area. I have defined these areas like so
var areaOne = [1, 2];
var areaTwo = [3, 4, 5];
var areaThree = [6, 7, 9];
var areaFour = [8, 10];
Now I could do most of what I need too, but I want to do it efficiently.
Each area should only have one button with the class active.
All other buttons should have the classes inactive and throb.
If an inactive button is clicked, inactive and throb should be removed and an active class added. However, the original active button within this buttons area then needs to become inactive and have the class throb.
At the moment I have the following
$(".btn").click( function(){
if ($( this ).hasClass("inactive")) {
$( this ).removeClass("inactive");
$( this ).removeClass("throb");
$( this ).addClass("active");
}
});
So that will make an inactive class active. I don't know if this is the best way to do this or if it can be cleaner? What I am not too sure of now is making the active class in the clicked buttons area inactive. I can get the clicked buttons id, but then I need to somehow loop the buttons within this area to find the original active one and make it inactive.
How would I achieve something like this?
Thanks

I have created a multidimensional array instead of defining them in seprate variables.
var arr = [[1,2],[3,4,5],[6,7,9],[8,10]];
$(".btn").click(function(){
// Fetch the clicked id
var _id = +this.id;
// Fetch the are of the button
var _others = arr.filter(function(v,i){
return v.indexOf(_id)!=-1
});
console.log("#"+_others[0].join(", #"));
// Make a string of others like #1, #2 and exclude this and remove class active and add classes inactive and throb
$("#"+_others[0].join(", #")).removeClass("active").addClass("inactive throb");
// Add class active to clicked button and remove class inactive and throb
$(this).removeClass("inactive throb").addClass("active");
});
.active{background:#ff0000;}
.inactive{background:#00ff00;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="btn" id="1">Buttone 1</button>
<button class="btn" id="2">Buttone 2</button>
<button class="btn" id="3">Buttone 3</button>
<button class="btn" id="4">Buttone 4</button>
<button class="btn" id="5">Buttone 5</button>
<button class="btn" id="6">Buttone 6</button>
<button class="btn" id="7">Buttone 7</button>
<button class="btn" id="8">Buttone 8</button>
<button class="btn" id="9">Buttone 9</button>
<button class="btn" id="10">Buttone 10</button>
The thing is you do not need to check befire using removeClass("whatever"), if it exists it will get removed otherwise won't give any error.

Related

How to fadeOut two children elements simultaneously using $(this)

I have a div in which there are 3 buttons. What I am expecting is that when I click the 3rd button, the 2nd and the 3rd buttons should fadeOut ... but in reality, only the 3rd button is fading out ... why so?
Here's, my code
<div id="bttns">
<button class="btn btn-danger"> Delete </button> //1st Button
<button class="btn btn-warning"> Modify </button> //2nd Button
<button class="btn btn-success"> Complete </button> //3rd Button
</div>
And here is the jQuery
$(".btn-success").on("click", function(){
$( $(this) , $(this).parent().children(".btn-warning") ).fadeOut(500)
})
I couldn't find a question similar to mine ... and also I am new to all of this so if you do find that such a question exists, please redirect me to it.
This happens becuse:
$( $(this) , $(this).parent().children(".btn-warning") )
this is not a valid selector here. To chain multiple jQuery objects you can use .add() method and then call .fadeOut(500) on the collection like:
$(".btn-success").on("click", function() {
var $btn3 = $(this);
var $btn2 = $(this).parent().children(".btn-warning");
$btn2.add($btn3).fadeOut(500)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="bttns">
<button class="btn btn-danger"> Delete </button>
<button class="btn btn-warning"> Modify </button>
<button class="btn btn-success"> Complete </button>
</div>
As you have assigned classes. You can go like this :-
$(".btn-success").on("click", function () {
$('.btn-warning, .btn-success').fadeOut(500);
})
you are fading out only the button with the btn-warning class. instead use two selectors.
$(".btn-success").on("click", function(){
$(this).parent().children(".btn-warning, .btn-success").fadeOut(500)
})

How to capture two same id but different class in addEventListener

first of all, thank you for your time to read this question, and two things, I'm using ES5 and I don't use jQuery.
Right now I'm struggling a lot to figure what's the correct solution for the addEventListener, because for some reason it does not trigger for the second button which is only for the mobile screen dimensions, the problem is that the second button have the same id but different class, for example this:
<div class="product-bg-container product-general-info variation-info">
<input type="hidden" name="sku" value="Something-15892290" id="selected-option">
{/* Desktop screen button */}
<button id="buy-now" class="btn btn-lg hidden-sm-down btn-primary">
Add to Cart
</button>
{/* Mobile screen button */}
<button id="buy-now" class="btn btn-lg hidden-md-up btn-primary">
Add to Cart
</button>
</div>
Where I am trying to trigger the second button but it does not where I don't understand why it does, if the id is the same, should not matter, so I'm trying to figure how to trigger from the first button if it's clicked and also with the second if it's clicked, but I'm out of ideas...
var button = document.getElementById('buy-now');
if (!button) {
return;
}
button.addEventListener('click', function trackAddToCart() {
// more code for the event
}
I thought an idea to capture the attribute of the button, but it works in the first button but not for the second one:
var button = document.getElementById('buy-now');
var att = button.getAttribute('class');
button.addEventListener('click', function() {
console.log('class ' + att); //shows: class: btn btn-lg hidden-sm-down btn-primary
console.log('button class? '+ button); //shows: button element: [object HTMLButtonElement]
});
But when I click the second button... does not trigger or happening nothing, not sure why... and I can't change the id value (which it should be easy but I can't "company standard")
Can anyone help me to have an idea how to capture and trigger the event for the second button ??
The attribute id must be unique in a document. You can use attributeStartsWith selector or class with querySelectorAll(). Then loop through all the button to attach the event (click) individually:
//var button = document.querySelectorAll('.btn.btn-primary');
var button = document.querySelectorAll('[id^=buy-now]');
button.forEach(function(btn){
btn.addEventListener('click', function() {
console.log('class ' + this.classList);
console.log('button class? '+ this.id);
});
});
<div class="product-bg-container product-general-info variation-info">
<input type="hidden" name="sku" value="Something-15892290" id="selected-option">
<button id="buy-now" class="btn btn-lg hidden-sm-down btn-primary">
Add to Cart
</button>
<button id="buy-now2" class="btn btn-lg hidden-md-up btn-primary">
Add to Cart
</button>
</div>
nextElementSibling seems working in this case.
var btn1 = document.getElementById("btn");
var btn2 = btn1.nextElementSibling;
btn1.addEventListener("click",function(e){
console.log("btn1");
});
btn2.addEventListener("click",function(e){
console.log("btn2");
});
<div>
<button id="btn" class="btn1">butotn 1</button>
<button id="btn" class="btn2">butotn 2</button>
</div>

Moving element from one div to another

Here is my live demo: https://jsfiddle.net/johndoe1992/3uqg7y9L/
When I click some button on the left panel it must be cloned to the right panel (see live demo)
The bootstrap class 'disable' must be added on click to this button from the left panel too. We have the disabled button on the left and the enabled button on the right
When I click some button on the right panel it must relocate back to the left panel (see live demo)
We have the enabled button on the left and no button on the right
I've tried to find a solution using this, which works for #1 and #2, but I have no idea what to do with #3
$(this).clone().appendTo('.selected');
$(this).prop('disabled', true);
Thank you for your help
Firstly you need to use a delegated event handler to handle clicks on the buttons you dynamically add to the .selected div.
Secondly you need to add a way of identifying which button was clicked on in the .selected div and matching that with the original in the .base div. To do that you could use a data attribute. From there you can just set the disabled property state and remove() the clone. Something like this:
<div class="base">
<button type="button" class="btn btn-default" data-state="default">Text 1</button>
<button type="button" class="btn btn-primary" data-state="primary">Text 2</button>
<button type="button" class="btn btn-info" data-state="info">Text 3</button>
<button type="button" class="btn btn-warning" data-state="warning">Text 4</button>
<button type="button" class="btn btn-success" data-state="success">Text 5</button>
<button type="button" class="btn btn-danger" data-state="danger">Text 6</button>
</div>
<div class="selected"></div>
$(document).on('click', '.btn', function() {
if($(this).parent().attr("class") == "base") {
$(this).clone().appendTo('.selected');
$(this).prop('disabled', true);
}
else {
$('.base').find('[data-state="' + $(this).data('state') + '"]').prop('disabled', false);
$(this).remove();
}
});
Updated fiddle

hide many button with next and preview button

I have ten buttons with a button for next and previous,
when I click the next button, it should show the next two buttons (hiding the rest).
The reverse should happen when the previous button is clicked (Show the previous two buttons (hide the rest)).
thanks.
my html code is :
<div>
<button class="menu">M1</button>
<button class="menu">M2</button>
<button class="menu">M3</button>
<button class="menu">M4</button>
<button class="menu">M5</button>
<button class="menu">M6</button>
<button class="menu">M7</button>
<button class="menu">M8</button>
<button class="menu">M9</button>
<button class="menu">M10</button>
</div>
<div>
<button class="action" id="btnNext">Next</button>
<button class="action" id="btnPreview">Previous</button>
</div>
Initially make every button hidden except first two.
$("#btnNext").on('click', function(){
var vBtn = $(".menu:visible:last");
$(".menu").hide();
vBtn.next().show();
vBtn.next().next().show();
});
$("#btnPreview").on('click', function(){
var vBtn = $(".menu:visible:first");
$(".menu").hide();
vBtn.prev().show();
vBtn.prev().prev().show();
});
I manually coded not tested please check
$("button.menu").not(':eq(0),:eq(1)').hide();
var count = 1;
$("#btnNext").click(function() {
$("button.menu").hide();
count = count + 2;
$("button.menu").eq(count-1).show();
$("button.menu").eq(count).show();
});
$("#btnPreview").click(function() {
$("button.menu").hide();
count = count - 2;
$("button.menu").eq(count-1).show();
$("button.menu").eq(count).show();
});

Knockout: How do I toggle visibility of multiple divs on button click?

I want to toggle visibility of multiple divs using knockout. Below is the rough idea of my problem -
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
<div> Div 1 </div>
<div> Div 2 </div>
<div> Div 3 </div>
By default, 'Div 1' should be visible.
When I click individual buttons it should display only the related divs based on the buttons clicked.
I have gone through the Knockout live examples but not getting how to do this efficiently.
Please help!
The following will do a job for you. It's not ideal, but should give you a platform to work on.
First, everything in Knockout is tied to a view model. You want to be able to control the visibility of 3 divs, so here's a view model which might suit. Like I said, not perfect :)
var buttonVm = new function(){
var self = this;
// Flags for visibility
// Set first to true to cover your "first should be open" req
self.button1Visible = ko.observable(true);
self.button2Visible = ko.observable(false);
self.button3Visible = ko.observable(false);
self.toggle1 = function(){
self.button1Visible(!self.button1Visible());
}
self.toggle2 = function(){
self.button2Visible(!self.button2Visible());
}
self.toggle3 = function(){
self.button3Visible(!self.button3Visible());
}
}
You'll need to change your markup to:-
<!-- events here. When clicked call the referenced function -->
<button type="button" data-bind="click: toggle1">Button 1</button>
<button type="button" data-bind="click: toggle2">Button 2</button>
<button type="button" data-bind="click: toggle3">Button 3</button>
<!-- Visibility set here -->
<div data-bind="visible: button1Visible"> Div 1 </div>
<div data-bind="visible: button2Visible"> Div 2 </div>
<div data-bind="visible: button3Visible"> Div 3 </div>
Couple of things to note here. First, I've added the type attribute. Without it, the default behaviour of the button will be to try and submit your form.
Tying it all up:-
// Create view model
var vm = new buttonVm();
ko.applyBindings(vm);

Categories