jQuery loop through .hover( ) function using .each( ) - javascript

I have a function that changes the border-color of the arrows to match the hover state colour of the buttons. It is working as 3 separate functions but I want to combine them using .each( ) Please tell me where I am going wrong
Vars
var btnArrowPath = '.btn + .btn-arrow';
var btnName = ['btn-infra ','btn-dev ','btn-anal '];
var btnColor = ['#286090','#449d44','#31b0d5'];
var btnRollColor = ['#337ab7','#5cb85c','#5bc0de'];
Function
$('.btn-wrap').each(function(i, value){
$(btnName[value] + '.btn').hover(function(i, value){
$(btnName[value] + btnArrowPath).css('border-top-color',btnColor[value]);
}, function(){
$(btnName[value] + btnArrowPath).css('border-top-color',btnRollColor[value]);
});
});
HTML
<div class="hero-wrap">
<div class="hero-popup">
<div class="row">
<div class="btn-wrap btn-infra">
<button data-trigger="focus" type="button" class="btn btn-primary" data-toggle="popover" title="Infrastructure" data-content="And here's some amazing content. It's very engaging. Right? <a href='#'>Do it!</a>" data-placement="bottom">Infrastructure</button>
<div class="btn-arrow pull-right"></div>
</div>
</div>
<div class="row">
<div class="btn-wrap btn-dev">
<button data-trigger="focus" type="button" class="btn btn-info" data-toggle="popover" title="Development" data-content="And here's some amazing content. It's very engaging. Right? <a href='#'>Do it!</a>" data-placement="top">Development</button>
<div class="btn-arrow pull-right"></div>
</div>
</div>
<div class="row">
<div class="btn-wrap btn-anal">
<button data-trigger="focus" type="button" class="btn btn-success" data-toggle="popover" title="Analysis" data-content="And here's some amazing content. It's very engaging. Right? <a href='#'>Do it!</a>" data-placement="top">Analysis</button>
<div class="btn-arrow pull-right"></div>
</div>
</div>
</div>]

You want to have the hover function for the .btn element inside the .btn-wrap element, which will change the border top color of the next sibling of the hovered element, isn't it?
So
$('.btn-wrap .btn').each(function (i, value) {
$(this).hover(function (e) {
$(this).next('.btn-arrow').css('border-top-color', btnColor[i]);
}, function () {
$(this).next('.btn-arrow').css('border-top-color', btnRollColor[i]);
});
});
Demo: Fiddle
You can do it without the loop like
var $btns = $('.btn-wrap .btn').hover(function (e) {
$(this).next('.btn-arrow').css('border-top-color', btnColor[$btns.index(this)]);
}, function () {
$(this).next('.btn-arrow').css('border-top-color', btnRollColor[$btns.index(this)]);
});
Demo: Fiddle

Related

data- attribute not working to grab dynamic id from foreach

I am using JS in a razor page to grab a dynamic ID from a col in a foreach.
In the past, I have used this and it worked fine. However, it seems that it is currently only grabbing the ID from the first col no matter which one I click.
Can someone please tell me if I am still doing this right? Or if I am missing something. Thank you.
View:
<div class="list-group container" id="JobRequestMonitorTable">
<div class="row list-group-item list-group-item-heading container divTableHeading" style="margin-bottom:0px;">
<div class="col-md-4"> Job Code </div>
<div class="col-md-4"> Description </div>
<div class="col-md-2"> Schedule </div>
<div class="col-md-1"> Running </div>
<div class="col-md-1"></div>
</div>
#if (!string.IsNullOrEmpty(ViewBag.ErrorMessage))
{
<div class="row list-group-item-danger">
<div class="col-md-1 text-center">#ViewBag.ErrorMessage</div>
</div>
}
#foreach (var item in Model.JobRequests)
{
<div class="row list-group-item container">
<div class="hidden" data-id="#item.JobRequestId" id="requestId">#item.JobRequestId</div>
<div class="col-md-4">#item.JobCode</div>
<div class="col-md-4">#item.Description</div>
<div class="col-md-2">#item.Schedule</div>
#if (#item.IsRunning == true)
{
<div class="col-md-1" style="margin-left:25px;"><span class="glyphicon glyphicon-ok"></span></div>
<div class="col-md-1"></div>
}
else
{
<div class="col-md-1"></div>
<div class="col-md-1">
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn"></button>
</div>
}
</div>
}
</div>
JS:
$("button").click(function () {
var col = $('#requestId');
var jobRequestId = col.data('Id');
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId},
success: function (results) {
$modal = $('#paramsModal');
$modal.modal("show");
var arr = results;
//loop through arr created from dictionary to grab key(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
var myKey = key;
}
}
var name = myKey;
var value = results[myKey];
$('#modalName').text(name);
$('#modalMessage').text(value);
}
});
});
Really the only important part to see in the JS is var col = $('#requestId');
var jobRequestId = col.data('Id');
But I suppose I will include the whole script just in case people ask.
Your loop is creating multiple #requestId and #paramModalBtn elements when id attributes have to be unique within the DOM. Change the logic to use common classes instead. Then you can traverse the DOM to find the elements related to the button which was clicked. Try this:
$("button").click(function() {
var $col = $(this).closest('.row').find('.requestId');
var jobRequestId = $col.data('id');
console.log(jobRequestId);
// AJAX request...
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<div class="row list-group-item container">
<div class="hidden requestId" data-id="foo-bar">Job #1</div>
<!-- other content... -->
<div class="col-md-1">
<button class="glyphicon glyphicon-list-alt btn btn-primary" name="paramsBtn"></button>
</div>
</div>
<div class="row list-group-item container">
<div class="hidden requestId" data-id="lorem-ipsum">#Job #2</div>
<!-- other content... -->
<div class="col-md-1">
<button class="glyphicon glyphicon-list-alt btn btn-primary" name="paramsBtn"></button>
</div>
</div>
All of your items inside the loop are getting the same id attribute, it is hard-codded
id="requestId"
the jQuery selector $('#requestId') is getting back the first one, this is by design.
I would add a data-id to each button and select the relevant col with that id.
For example the button will get:
<button data-col-id="#item.JobRequestId" class="glyphicon glyphicon-list-alt btn btn-primary"></button>
And then, its easy to grab that info on click:
$("button").click(function () {
var jobRequestId = $(this).data('col-id');
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId},
success: function (results) {
$modal = $('#paramsModal');
$modal.modal("show");
var arr = results;
//loop through arr created from dictionary to grab key(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
var myKey = key;
}
}
var name = myKey;
var value = results[myKey];
$('#modalName').text(name);
$('#modalMessage').text(value);
}
});
});
I like this solution as you are not depended on your HTML structure and hierarchy thus selectors won't break often.
Once you have a button for each item, you could also store the data into the button value attribute, which leads to a simple implementation in the JS:
$("button").click(function (e) {
var jobRequestId = $(e.target).val();
console.log(jobRequestId);
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId},
success: function (results) {
$modal = $('#paramsModal');
$modal.modal("show");
var arr = results;
//loop through arr created from dictionary to grab key(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
var myKey = key;
}
}
var name = myKey;
var value = results[myKey];
$('#modalName').text(name);
$('#modalMessage').text(value);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="1">Job 1</button><br />
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="2">Job 2</button><br />
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="3">Job 3</button><br />
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="4">Job 4</button><br />
<button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="5">Job 5</button>
Obs.: value must be equal to #item.JobRequestId like so: <button class="glyphicon glyphicon-list-alt btn btn-primary" id="paramModalBtn" name="paramsBtn" value="#item.JobRequestId">Job 5</button>

jQuery sort cards with up/down arrows

I am using Bootstrap cards on a page, where I want those cards to be sorted using up and down arrows. Every card has arrows in its header, to move it up or down in the layout. But of course, when it gets moved to the top, the up arrow should be gone, likewise for when it hits the bottom.
I've tried using if statements in this style:
// Result: Is never executed.
if(!$(card).find('.sort-down')) {}
// Result: Is always executed.
if($(card).not(':has(.sort-down)') {}
Where $(card) is the div containing the complete card that is being moved.
For example, my complete "move down" code block.
$(document).on('click', '.sort-down', function(e) {
e.preventDefault();
let card = $(this).closest('.card');
let sort_id = $(card).attr('data-sort');
let next_sort_id = Number(sort_id) + 1;
$('[data-sort]').each(function(index, value) {
if($(value).attr('data-sort') == next_sort_id) {
$(value).after($(card));
$(value).attr('data-sort', sort_id);
$(card).attr('data-sort', next_sort_id);
// Change buttons
if($(card).attr('data-sort') == sortCount - 1) {
$(card).find('.sort-down').remove();
if(!$(card).find('.sort-up')) {
// Insert up arrow
}
} else {
if(!$(card).find('.sort-up')) {
// Insert up arrow
}
if(!$(card).find('.sort-down')) {
// Insert down arrow
}
}
if($(value).attr('data-sort') == 0) {
$(value).find('.sort-up').remove();
if(!$(value).find('.sort-down')) {
// Insert down arrow
}
} else {
if(!$(value).find('.sort-down')) {
// Insert down arrow
}
if(!$(value).find('.sort-up')) {
// Insert up arrow
}
}
return false;
}
});
});
A little bit of the HTML so you can get an idea what classes/attributes my jQuery is selecting.
<div class="card mb-3" data-sort="0">
<div class="card-header">
Tekstveld
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-down"><i data-feather="arrow-down" width="16" height="16"></i></button>
</div>
<div class="card-body p-0">
<div id="editor"></div>
</div>
</div>
As I usually overcomplicate things, and get the result of it not even working, I'm hoping you could help me with either a simple or more advanced working solution of getting this done.
Using data-sort attribute as a sorting index could be more useful for "Global" sorting or filtering. Like when we click on one button to sort them all based on that property value.
But here, a less complicated alternative is to use jQuery default methods like : next(),prev(),closest(),insertAfter(),insertBefore()
$( document ).ready(function() {
setButtons();
$(document).on('click', '.sort-down', function(e) {
var cCard = $(this).closest('.card');
var tCard = cCard.next('.card');
cCard.insertAfter(tCard);
setButtons();
resetSort();
});
$(document).on('click', '.sort-up', function(e) {
var cCard = $(this).closest('.card');
var tCard = cCard.prev('.card');
cCard.insertBefore(tCard);
setButtons();
resetSort();
});
function resetSort(){
var i=0;
$('.card').each(function(){
//$(this).data('sort',i);
$(this).attr("data-sort", i);
i++;
});
}
function setButtons(){
$('button').show();
$('.card:first-child button.sort-up').hide();
$('.card:last-child button.sort-down').hide();
}
function resetSort(){
var i=0;
$('.card').each(function(){
//$(this).data('sort',i);
$(this).attr("data-sort", i);
i++;
});
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="card mb-3" data-sort="0">
<div class="card-header">
Tekstveld
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-down"><i class="fas fa-caret-down"></i></button>
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-up"><i class="fas fa-caret-up"></i></button>
</div>
<div class="card-body p-0">
<div class="editor"></div>
</div>
</div>
<div class="card mb-3" data-sort="1">
<div class="card-header">
Voorbeeld
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-down"><i class="fas fa-caret-down"></i></button>
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-up"><i class="fas fa-caret-up"></i></button>
</div>
<div class="card-body p-0">
<div class="editor"></div>
</div>
</div>
<div class="card mb-3" data-sort="2">
<div class="card-header">
Lorem ipsum
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-down"><i class="fas fa-caret-down"></i></button>
<button type="button" class="btn btn-sm btn-primary float-right mr-1 sort-up"><i class="fas fa-caret-up"></i></button>
</div>
<div class="card-body p-0">
<div class="editor"></div>
</div>
</div>
</div>
[UPDATE] : The setButtons() function would hide the non functional buttons when the div reach the limit.
Notice that I added another function resetSort() to reorder those data-sort values. Just in case, you need it for global sorting.

I want to dynamically create a tag by using javascript

I'm using a bootstrap modal.
The Function what I want to dynamically create a button at body tag when I click the modal button.
Description about function what I apply: As soon as I click the bluebutton, I want to create it at the body tag('beside the '+' button')
window.onlaod = function(){
var blue = document.getElementById('blue');
blue.onclick = function(){
blue.onclick = null;
var result = document.getElementById('result');
var newblue = document.createElement('span');
newblue.id = 'newblue';
newblue.innerHTML += '<button type="button" class="btn btn-primary btnWH " id="blue"></button>';
result.appendChild(newblue);
};
};
-> This is the code about event after click the bluebutton.
<!-- label color -->
<div class="modal-body">
<button type="button" class="btn btn-primary btnWH " id="blue"></button>
</div>
-> This is the code about bluebutton.
<div class="card border-secondary mb-3" style="max-width: 20rem;">
<div class="card-header">Header</div>
<div class="card-body">
<div id="result">
<span id="first">
<button type="button" class="btn btn-primary plusbtn" data-toggle="modal" data-target="#mymodal"> +
</button>
</span>
</div>
</div>
</div>
-> This is the code about '+'button.
This will create a button when click on add button inside div id of result code as follows:
<html>
<body>
<button type="button" id="blue">add</button>
<div id="result"></div>
<script>
window.onload = function() {
return addEvent();
}
function addEvent() {
var blueButton = document.getElementById('blue');
blueButton.addEventListener("click", addButton)
}
function addButton() {
var result = document.getElementById('result');
var newBtn = document.createElement('span');
newBtn.id = 'newblue';
newBtn.innerHTML += '<button type="button" id="blue">test</button>';
result.appendChild(newBtn);
}
</script>
</body>
</html>

How can I make jquery script shorter?

I have got following code (i shorted it to make it more readable)
And I would like to ask if it is possible to do not write almost the same code for every button? How can I do it the easiest way? I have got 6 buttons and code would be quite long.
<script>
$(document).ready(function(){
$("#option1").click(function(){
if($(".option1").is(":visible")){
$(".option1").hide("slow",function(){});
}
else{
$(".option2, .option3").hide("slow",function(){});
$(".option1").show("slow",function(){});
}
});
$("#option2").click(function(){
if($(".option2").is(":visible")){
$(".option2").hide("slow",function(){});
}
else{
$(".option1, .option3").hide("slow",function(){});
$(".option2").show("slow",function(){});
}
});
$("#option3").click(function(){
if($(".option3").is(":visible")){
$(".option3").hide("slow",function(){});
}
else{
$(".option1, .option2").hide("slow",function(){});
$(".option3").show("slow",function(){});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
</body>
Without the need to change much of your html, add a common class option to all your option1, option2, ... :
<div class ="option option1">a</div>
<div class ="option option2">b</div>
<div class ="option option3">c</div>
and then you can use this below:
Array.from(document.getElementsByTagName('button')).forEach(function(btn){
btn.addEventListener('click', function(e){
if($("." + e.target.id).is(":visible")){
$("." + e.target.id).hide("slow",function(){});
}
else{
$(".option").hide("slow",function(){});
$("." + e.target.id).show("slow",function(){});
}
});
});
DEMO
You can reduce the code to just one click listener. Try this:
<script>
$(document).ready(function() {
$(".btn-primary").click(function() {
var option = $(this).data("option");
if ($(".option." + option).is(":visible")) {
$(".option." + option).hide("slow", function() {});
} else {
$(".option").not("." + option).hide("slow", function() {});
$(".option." + option).show("slow", function() {});
}
});
});
</script>
<body>
<div class="containter">
<div class="row">
<div class="col-md-4">
<button type="button" id="option1" data-option="option1" class="btn btn-primary">Button1 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option2" data-option="option2" class="btn btn-primary">Button2 >></button>
</div>
<div class="col-md-4">
<button type="button" id="option3" data-option="option3" class="btn btn-primary">Button3 >></button>
</div>
</div>
</div>
<!-- common class option added -->
<div class="options">
<div class="option option1"></div>
<div class="option option2"></div>
<div class="option option3"></div>
</div>
</body>
I added a common class to all the options, and a data-option attribute to your buttons.
You don't need to check to see whether the current button is visible. It's visible because it was just clicked on.
All you need to do is show the other buttons that weren't clicked on and hide the one that was. To do this, assign the same class to all 3 buttons. In the example below, I added the class "myBtn" to all 3 buttons.
$(".myBtn").click(function () {
var id = $(this).attr('id');
$(".myBtn:not(#"+id+")").show("slow", function () {});
$(this).hide();
});
JSFiddle demo.

How to open and close div element while cliking of anchor tag

Below is my html format i want to open leftbar div tag while clicking of open-left tag and also close leftbar div tag while clicking of open-left tag.
<div id="leftbar" class="snap-drawers">
<div class="snap-drawer snap-drawer-left">
<div>
<br />
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12 text-center">
<img src="assets/img/nloop-min.png" alt="" class="drawer-logo" />
</div>
<br />
<ul>
<li><i class="fa fa-home fa-1x"></i> Home</li>
<li><i class="fa fa-dot-circle-o fa-1x"></i> Tour</li>
<li><i class="fa fa-bullseye fa-1x"></i> FAQ</li>
<li><i class="fa fa-magic fa-1x"></i> About</li>
<li><i class="fa fa-comment-o fa-1x"></i> Contact</li>
</ul>
<br />
<p>
© 2013 - nLoop</p>
</div>
</div>
</div>
<div id="content" class="snap-content">
<div id="sidebarmenu" class="col-lg-1 col-sm-1 col-xs-1 col-md-1">
</div>
<div id="rightpart" class="margingap">
Right part
</div>
</div>
<script type="text/javascript">
var snapper = new Snap({
element: document.getElementById('content'),
disable: 'right'
});
$(document).ready(function () {
var addEvent = function addEvent(element, eventName, func) {
if (element.addEventListener) {
return element.addEventListener(eventName, func, false);
} else if (element.attachEvent) {
return element.attachEvent("on" + eventName, func);
}
};
addEvent(document.getElementById('open-left'), 'click', function () {
snapper.open('left');
var state = $(this).is('.open');
if (state) {
snapper.close('left');
}
});
});
</script>
Open and close div element while cliking an anchor tag:
$("#open-left").click(function(){
$("#leftbar").toggle();
});
See more about this here: .toggle() Documentation
Code explanation:
I am just attaching a click event to the #open-left tag and then I called the .toggle() on the #leftbar. This just pretty much keeps record of what is the current state of the object, hiddden or shown, and then calls the particular function according to the state.
Also, see this working example: fiddle.
Are you maybe looking for something like jQuery's hide() and show()? Or toggle()?
Try this:
var isOpen = false;
$("#open-left").click(function(){
if(isOpen){
$("#leftbar").slideUp(); isOpen = false;}
else{ $("#leftbar").slideDown(); isOpen = true; }
});

Categories