On this page https://fantasy.premierleague.com/a/squad/transfers there is a dropdown where you can select a player's maximum price. It then filters a table below to only show players with a price equal or less than the selected maximum price. With my Chrome extension I have added two buttons which change the selected option
/**
* Increases the price of the /transfers maximum price filter.
*/
function increasePrice() {
const priceFilter = document.getElementById('ismjs-element-price');
if (priceFilter.selectedIndex === 0) return;
priceFilter.selectedIndex -= 1;
priceFilter.dispatchEvent(new Event('change'));
}
/**
* Decreases the price of the /transfers maximum price filter.
*/
function decreasePrice() {
const priceFilter = document.getElementById('ismjs-element-price');
if (priceFilter.selectedIndex === priceFilter.options.length - 1) return;
priceFilter.selectedIndex += 1;
priceFilter.dispatchEvent(new Event('change'));
}
/**
* Adds the increase and decrease price buttons for filtering players by the their maximum price to
* the /transfers sidebar.
*/
function addPriceButtons() {
const priceDiv = document.getElementById('ismr-price');
if (priceDiv.classList.contains('price-filter')) return;
priceDiv.className += ' price-filter';
const increaseButton = document.createElement('div');
const decreaseButton = document.createElement('div');
increaseButton.className = 'price-change-button grid-center';
increaseButton.textContent = '+';
increaseButton.onclick = increasePrice;
decreaseButton.className = 'price-change-button grid-center';
decreaseButton.textContent = '-';
decreaseButton.onclick = decreasePrice;
priceDiv.insertAdjacentElement('beforeend', increaseButton);
priceDiv.insertAdjacentElement('beforeend', decreaseButton);
}
which seems to work fine, as shown in the GIF below
The problem is that it doesn't actually change the players shown in the table. I thought that by adding
priceFilter.dispatchEvent(new Event('change'));
it would work fine. I've also tried 'click' and 'input', but these events don't do anything either.
I've also inspected the select element in Chrome's to see which event listeners it has, and if I could maybe make sense of it. Unfortunately the code is minified, so I can't really tell what to do.
Am I missing something? Where am I supposed to find out how the table is filtered in the first place and how can I trigger this myself?
Related
I am trying to create a products page with a forum that shows the price of the item, the name of the item and also the quantity with buttons to add or subtract from the quantity field.
I have no idea where to begin, I thought I'd do some looking into different types of buttons and form input types but none of them seem to have what I need.
I was wondering if anyone can point me to the right direction so I can figure out how these buttons are changing the quantity field and how I can make a plus and minus button which appears next to the quantity.
Here is a picture of what I mean:
Use JavaScript to increase and decrease the input value:
const minusButton = document.getElementById('minus');
const plusButton = document.getElementById('plus');
const inputField = document.getElementById('input');
minusButton.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
inputField.value = currentValue - 1;
});
plusButton.addEventListener('click', event => {
event.preventDefault();
const currentValue = Number(inputField.value) || 0;
inputField.value = currentValue + 1;
});
<button id="minus">−</button>
<input type="number" value="0" id="input"/>
<button id="plus">+</button>
Here what happens in the JS code. First it gets references to the HTML elements using the id HTML attribute and the document.getElementById JS function. Then it adds functions which are executed when one of the buttons is clicked. Inside the functions, the default button browser action (submitting the form) is cancelled, the input value is read, increased/decreased and put back to the input.
I am trying to work on a snippet which has 3 progress bars and it can be controlled by 4 buttons to increment or decrement the progress bar value.
It also has a select box to switch between the progress bars.
The problem is that I am unable to individualize each progress bar. When I am changing the value in the first selected progress bar it is working as expected. The problem arises when I am switching between the progress bar using the select box.
I am not able to understand why it is behaving in such manner. I am providing the link below for better understanding.
Scenario: When you select a progress bar from the select box the first time, it will work fine. When you select another progress bar then both the progress bars get effected.
I hope I was able to point out the problem clearly.
I am posting the JavaScript code below. Click here for the complete code.
const progressBars = document.getElementsByClassName('progress-bar'),
buttons = document.getElementsByClassName('btn'),
progressView = document.getElementsByClassName('percent'),
pb_1 = progressBars[0],
pb_2 = progressBars[1],
pb_3 = progressBars[2],
selector = document.getElementById('selector');
function progressControl(selectedValue){
let selectedPB = eval(selectedValue),
progressPercent = selectedPB.firstElementChild,
progress = parseInt(selectedPB.style.width);
for(let i=0; i<buttons.length; i++){
let eachBtn = buttons[i],
controlBtn = parseInt(eachBtn.textContent);
eachBtn.addEventListener('click', function(){
progress += controlBtn;
if(progress > 100){
selectedPB.classList.add('progress-bar-danger');
} else if(progress <= 100 && progress >= 0) {
selectedPB.classList.remove('progress-bar-danger');
} else {
progress = 0;
}
selectedPB.style.width = progress+'%';
progressPercent.textContent = selectedPB.style.width;
});
}
}
selector.addEventListener('change', function(){
let selectedValue = selector.options[selector.selectedIndex].value;
progressControl(selectedValue);
});
Your problem is in this line
eachBtn.addEventListener('click', function(){
Each time you change the select's value, you're adding a new click event for the old button instead of replacing the old event listener.
I can think of 2 solutions:
Move eachBtn.addEventListener outside of the function progressControl so that you add the eventListener only once.
Use eachBtn.onclick = function(){} instead of addEventListener so that you overwrite the eachBtn's existing click handler instead of creating new handlers.
I have a script running to show a number in the select list options when the user check one specific value it will display a number refering to how much times he can pay his bill.
Note this code:
var tabelaParcelas = [2,3,4,6,8,10,12];
$(document).ready(function(){
update();
});
$('input[type=checkbox]').click(function(){
update();
})
function update(){
var list = $('#instNum2'); // use selector only once whenever possible for better performance
// clear any existing options from the dropdown list
list.html("")
// count checked boxes
var checked_boxes = 0
$(".check_list").each(function(){
if(this.checked){
checked_boxes++;
}
});
// append options to the select list
for(var i=0;i<checked_boxes;i++){
var option = $("<option>", {value: tabelaParcelas[i], "text": tabelaParcelas[i]});
list.append(option);
}
}
That's correct! But the thing is, I need to display 1x as well, and that's what's not showing at all, 1x should be visible always no matter how much boxes you select, and other thing, when I select more than 7 boxes, the option keep producing empty options, while it should only keep displaying 12x without appending any new...
var tabelaParcelas = [2,3,4,6,8,10,12];
$(document).ready(function(){
update();
});
$('input[type=checkbox]').click(function(){
update();
})
function update(){
var list = $('#instNum2'); // use selector only once whenever possible for better performance
// clear any existing options from the dropdown list
list.html("")
// count checked boxes
var checked_boxes = 0
$(".check_list").each(function(){
if(this.checked){
checked_boxes++;
}
});
//add limit to check_boxes
//This section was not in original code
// Could also do if(checked_boxes > tabelaParcelas.length) {checked_boxes = tabelaParcelas.length;}
//Would make it more dynamic.
//This is added to limit the number of options added to the length of the array at the top.
//This will prevent blank options from being added as requested in the question.
if(checked_boxes > 6) {
checked_boxes = 6;
}
//add 1x option to empty list
//This was not in original code
//This was added as the list was cleared when this function is run and they always wanted 1x to appear as an option.
list.append("<option value='1' selected>1</option>");
// append options to the select list
for(var i=0;i<checked_boxes;i++){
var option = $("<option>", {value: tabelaParcelas[i], "text": tabelaParcelas[i]});
list.append(option);
}
}
I have drop down menus, the last 2 are price and tickets which then makes a calculation and shows the total amount on screen when selected. It works fine although if i change the selection to a different price the total does not update. Also the same idea applies to the part where the user selects 4 or more tickets and an message appears on screen. Im sure its something simple but i cant seem to figure it out.
I have attached a Jsfiddle.
http://jsfiddle.net/Dwdqg/
function totalPrice(ticketCount,priceAmount)
{
if (tickets.selectedIndex != 0 && price.selectedIndex != 0) // if the price and tickets is not 0 or not selected
{
tickets.onchange = ticketCount; //when tickets is changed assign the index to var ticketCount
price.onchange = priceAmount;
var ticketCount = tickets.value; //get the value of ticketCount index
var priceAmount = price.value;
var totalPrice = (ticketCount * priceAmount);
document.getElementById("totalPrice").innerHTML = ("Total Price £" + totalPrice);
}
if (ticketCount >= 4) // if ticketCount is 4 or more
{
totalPrice = totalPrice + 10; // add on 10 to the price
document.getElementById("totalPrice").innerHTML = ("Total Price £" + totalPrice);
document.getElementById("moreTickets").innerHTML = ("Buying four or more tickets will add an additional £10 fee.")
}
}
You're not calling totalPrice in your change handlers.
For example:
price.onchange = function()
// totalPrice needs to be called
}
You've attached it here
<select name="tickets" id="tickets" onChange="totalPrice(tickets)" style="width:120px">
However, that only responds to changes to number of tickets. You haven't attached it to the other elements.
Also - your onchange only fires once because you're replacing the option fields using fillList after the change event fires. You can either reattach the handler or have it respond to a click event.
With that said - I don't recommend attaching handlers as HTML attributes and I suggest cleaning up your code to be more readable.
I'm trying to write a form builder where users can generate a signup form. I need to limit the amount of items that the user can create however they also need to delete the items.
Originally I had
var limit = 5;
var counter = 0;
if (counter == limit) {
However when the user deleted items the counter remained the same and so they couldnt replace the deleted form element with a new item. So what I want to do is count how many items are currently active. I tried to do this by giving each new element a class (.kid) and then counting the amount of divs with that class but it didnt work.
Could anyone point me in the right direction? This is what I have so far however it doesn't work.
var limit = 6;
var num = $('.kid').length;
function addAllInputs(divName, inputType){
if (num == limit) {
alert("You have all ready added 6 form items");
}
else {
var newdiv = document.createElement('div');
newdiv.setAttribute('id', 'child' + (counter + 1));
newdiv.setAttribute('class', 'kid' );
Cheers all!
You need to capture the current counter in a closure. Decrease the counter when the user deletes an item and increase it after an item is created. Your code sample doesn't reveal how you handle the deletion, but I'll try to illustrate what I mean with a small code snippet:
$(document).ready(function () {
var limit = 5;
var counter = $('.kid').length;
$('#triggers_delete').click(function () {
/* delete the item */
counter--;
});
$('#triggers_creation').click(function () {
if (counter == limit) {
alert('Limit reached');
return false;
}
/* somehow determine divName and inputType
and create the element */
addAllInputs(divName, inputType);
counter++;
});
});
function addAllInputs(divName, inputType) {
/* just create the item here */
}
Is there any reason an approach like this won't work? Every time you go to add a new DIV, the length of the current collection is examined to see if it meets or exceeds the limit. Of course, you may need to refine the scope of your selector if there could be other DIVs of the form with the same class ID.
var limit = 6;
function addAllInputs(divName, inputType){
if ( $('.kid').length >= limit ) {
alert("You have all ready added 6 form items");
}
else {
var newdiv = document.createElement('div');
newdiv.setAttribute('id', 'child' + (counter + 1));
newdiv.setAttribute('class', 'kid' );
}
Edit: Just a note, I am assuming that you are either removing the deleted items from the DOM or differentiating them from active items with a different class or attribute. Otherwise, the approach I suggested will return a count that includes the deleted items as well.
The only real issue is that your num variable is being defined outside of the function. It will get the number of .kid elements at the time the page loads and will not update. Simply move this line inside the function:
var limit = 6;
function addAllInputs(divName, inputType){
var num = $('.kid').length;
...
Try this
var limit = 6;
function addAllInputs(divName, inputType){
if ($('.kid').length == limit) {
alert("You have all ready added 6 form items");
}
else {
var newdiv = $('div', { 'id': 'child' + (counter + 1), 'class': 'kid' } );
$("inputContainerSelector").append(newdiv);
}