I am using the below code to render the same as many as times,
I have two sections, one section with show-all class and another with no class.
When 'show-all' class is not available, it need to run countIncrease function, if class available no need to run the function,
In every time section need to check whether the class is available or not.
class Grid {
init() {
$('.grid').each(function() {
const $this = $(this);
// getting values & url from from html
const dropDownUrlpath = $this.find('.grid__dropdown-select').attr('data-ajaxurl');
const hasClass = $this.find('.grid').hasClass('grid_showall');
// countIncrease shows the inital 6 compoents/div and rest of will be hidden
// onclick it will display 3 components/div
function countIncrease() {
let limit = parseInt($this.find('.grid__component').attr('data-initcount'), 10);
const incrementalCall = parseInt($this.find('.grid__component').attr('data-incrementalcount'), 10);
$this.find(`.grid__content > .grid__component:gt(' ${limit - 1} ') `).hide();
if ($this.find('.grid__content > .grid__component').length <= limit) {
$this.find('.grid__cta').hide();
}
else {
$this.find('.grid__cta').show();
}
$this.find('.grid__cta').on('click', function(event) {
event.preventDefault();
limit += incrementalCall;
$this.find(`.grid__content > .grid__component:lt(' ${limit} ')`).show();
if ($this.find('.grid__content > .grid__component').length <= limit) {
$this.find('.grid__cta').hide();
}
});
}
if (hasClass.length === true ) {
console.log('class exist-----'+ hasClass);
countIncrease();
}
// on dropdown change taking the selected dropdown value and adding #end of the url and replacing the previous html
$this.find('.grid__dropdown-select').on('change', function() {
const optionValue = this.value;
$.ajax({
url: dropDownUrlpath + optionValue,
success(result) {
$this.find('.grid__content').html(result);
countIncrease();
}
});
});
});
}
}
I written if condition, but it running once and giving false condition in both the scenarios,
if (hasClass.length === true ) {
console.log('class exist-----'+ hasClass);
countIncrease();
}
How to handle it...?
shouldnt you add a parameter to the .hasClass so it knows what to check?
if ( $this.hasClass ('some class') === true ) {
alert('something');
}
or set if(hasClass.length > 0){}
keep the checking class in a variable by finding with parent div,
const hasClass = $this.find('.grid').hasClass('grid_showall');
gets the attribute value for only the first element in the matched set with .attr() method
const classInthis = hasClass.attr('class');
check the condition, with
if (classInthis !== 'grid_showall') {
countIncrease();
}
Related
I have an issue with HTML and Javascript where I'm trying to create a condition that follows the following rules:
If the first text-box contains a certain word, disable the following drop-down.
If it doesn't contain that certain word, keep it enabled.
So far, I've got this code
var noSample = "HW8020";
const interval = setInterval(function() {
// method to be executed;
function codeCheck() {
var x = document.getElementById("form-RequestAQuoteUK-9bbb_Products_Interest_Value").value;
}
function validateSample() {
if ( x == noSample) {
document.getElementById(
"form-RequestAQuoteUK-9bbb_DropDown_Samples_SelectedValue"
).disabled = true;
} else {
document.getElementById(
"form-RequestAQuoteUK-9bbb_DropDown_Samples_SelectedValue"
).disabled = false;
}
}
}, 5000);
The noSample variable being the code that, when input into the text-field, will disable the dropdown. The Ids weren't my choice of naming, but I'm new to Javascript and am trying to fix an issue with the company I work for!
Any ideas?
You should rather use event input instead of setInterval and use indexOf to check if input.value contains certain value.
var noSample = "HW8020";
let input = document.getElementById(
"form-RequestAQuoteUK-9bbb_Products_Interest_Value",
);
input.addEventListener("input", () => {
validateSample(input.value)
});
function validateSample(inputValue) {
let selectEl = document.getElementById(
"form-RequestAQuoteUK-9bbb_DropDown_Samples_SelectedValue",
);
if (inputValue.indexOf(noSample) > -1) {
selectEl.disabled = true;
} else {
selectEl.disabled = false;
}
}
As suggested in the comments, you can add an event listener to your Products_Interest_Value input and then enable or disable the dropdown based on whether or not this matches your noSample value.
const noSample = "HW8020";
document.querySelector("#form-RequestAQuoteUK-9bbb_Products_Interest_Value").addEventListener("input", e => {
document.querySelector("#form-RequestAQuoteUK-9bbb_DropDown_Samples_SelectedValue").disabled = (e.target.value == noSample);
});
So. to begin with,
I am writing my eventlisteners in this way.
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classOne'){
fire_function_one();
}
if(element.classList.contains('classTwo'){
fire_function_two();
}
});
I have a div like follows
<div class='classOne classTwo'>Something</div>
So what I want to achieve is,
When our div has classOne, I want to fire 'fire_function_one()', However when our div has both classOne and ClassTwo, I want to fire 'fire_function_two()' but I dont want to run 'fire_function_one()'.
What I have tried,
event.stopPropogation; //Not working
event.preventDefault; //Not working
if(element.classList.contains('classTwo' && !element.classList.contains('classOne'){
fire_function_two();
//Doesnt acheive what I want
}
Change the Order of your condition and use else if statement.
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classTwo'){
fire_function_two();
}
else if(element.classList.contains('classOne'){
fire_function_one();
}
});
If you are sure that the element can have classOne or both classTwo and classOne, you can just change the order and use else if statement:
document.addEventListener('click',(e)=>{
const element = e.target;
if(element.classList.contains('classTwo'){
fire_function_two();
} else if(element.classList.contains('classOne'){
fire_function_one();
}
});
You need to write click on element as below.
var eleOne = document.getElementsByClassName('classOne')
if(eleOne.length > 0) {
var currentEleOne = eleOne[0];
currentEleOne.onclick = function () {
// Click code for classOne
}
}
var eleTwo = document.getElementsByClassName('classTwo')
if(eleTwo.length > 0) {
var currentEleTwo = eleTwo[0];
currentEleTwo.onclick = function () {
// Click code for classTwo
}
}
Here you have two cases,
When both classes are present, fire only class two
If only class one is present, fire class one
So, First check with if whether both classes are present or not. If true then fire class two. Otherwise inside else if, check if class one is present and if this condition is met, fire class one.
document.addEventListener('click', function(e) {
const element = e.target;
if (element.classList.contains('classTwo')) {
console.log("Fire class two");
} else if (element.classList.contains('classOne')) {
console.log("Fire class one");
}
});
<div class='classOne classTwo'>Something 1 2</div>
<div class='classOne'>Something 1</div>
You could try a simple ternary like this:
document.addEventListener('click', (e) => {
const element = e.target;
element.classList.contains('classTwo') ? fire_function_two() : fire_function_one();
});
If the classList contains 'classTwo' then run fire_function_two() else fire_function_one()
I have a form with one input field for the emailaddress. Now I want to add a class to the <form> when the input has value, but I can't figure out how to do that.
I'm using this code to add a class to the label when the input has value, but I can't make it work for the also:
function checkForInputFooter(element) {
const $label = $(element).siblings('.raven-field-label');
if ($(element).val().length > 0) {
$label.addClass('input-has-value');
} else {
$label.removeClass('input-has-value');
}
}
// The lines below are executed on page load
$('input.raven-field').each(function() {
checkForInputFooter(this);
});
// The lines below (inside) are executed on change & keyup
$('input.raven-field').on('change keyup', function() {
checkForInputFooter(this);
});
Pen: https://codepen.io/mdia/pen/gOrOWMN
This is the solution using jQuery:
function checkForInputFooter(element) {
// element is passed to the function ^
const $label = $(element).siblings('.raven-field-label');
var $element = $(element);
if ($element.val().length > 0) {
$label.addClass('input-has-value');
$element.closest('form').addClass('input-has-value');
} else {
$label.removeClass('input-has-value');
$element.closest('form').removeClass('input-has-value');
}
}
// The lines below are executed on page load
$('input.raven-field').each(function() {
checkForInputFooter(this);
});
// The lines below (inside) are executed on change & keyup
$('input.raven-field').on('change keyup', function() {
checkForInputFooter(this);
});
I've updated your pen here.
Here it is, using javascript vanilla. I selected the label tag ad form tag and added/removed the class accoring to the element value, but first you should add id="myForm" to your form html tag. Good luck.
function checkForInputFooter(element) {
// element is passed to the function ^
let label = element.parentNode.querySelector('.raven-field-label');
let myForm = document.getElementById("myform");
let inputValue = element.value;
if(inputValue != "" && inputValue != null){
label.classList.add('input-has-value');
myForm.classList.add('input-has-value');
}
else{
label.classList.remove('input-has-value');
myForm.classList.remove('input-has-value');
}
}
You can listen to the 'input' event of the input element and use .closest(<selector>) to add or remove the class
$('input').on('input', function () {
if (!this.value) {
$(this).closest('form').removeClass('has-value');
} else {
$(this).closest('form').addClass('has-value');
}
})
Edit: https://codepen.io/KlumperN/pen/xxVxdzy
if ($('<input/>').length == 0) {
T.stop();
}
the above is how I create the timer stop function.
This is where the part of the code has been placed:
$.map(exercise.syllables, function (syllable, j) {
if (!syllable || !syllable.trim().length) {
// If it doesn't exist or is an empty string, return early without creating/appending elements
return;
}
var innerSylCol = $('<div/>', {
class: 'col-md-3 inputSyllables'
});
var sylInput = $('<input/>', {
'type': 'text',
'class': 'form-control syl-input',
'name': +c++,
'id': +idsyll++
}).on('blur', function() {
var cValue = $(this).val();
if(cValue === "") {
return;
}
if (cValue === syllable) {
correctSylls.push(cValue);
console.log(correctSylls);
}
if (exercise.syllables.length === correctSylls.length) {
$(this).closest('.syll-row').find('input.syl-input').each(function () {
$(this).replaceWith(getCorrectBtn($(this).val()))
});
S.addRight();
S.playRight();
} else if (cValue !== syllable){
// $(this).css({'color':'#e00413'});
S.playWrong();
S.addWrong();
}
});
innerSylCol.append(sylInput);
sylRow.append(innerSylCol);
});
idsyll = 0;
sylCol.append(sylRow);
exer.append(colLeft, sylCol);
exerciseArea.append(exer);
});
return exerciseArea;
if ($('<input/>').length == 0) {
T.stop();
}
}
The loop creates inputs based on words in my array, the inputs change to buttons when the inserted data is correct. I am trying to create it such that when the length of the inputs becomes 0 (so there are no input fields left, only buttons) it will stop the timer.
Two problems:
This code:
if ($('<input/>').length == 0) {
creates an input element, which is put in a jQuery wrapper, and then checks the number of elements in the wrapper. So the condition will always be false, because the length will always be 1. To search for input elements, remove the < and />: $("input")
You need to run that code in response to some condition (perhaps within the timer itself?) that might make $("input").length 0 by removing all input elements. Your quoted code is incomplete, but it doesn't seem like that check is being done later or in response to some event where inputs may have been removed.
I have this wizard step form that I simulated with <ul> list items by overlapping inactive <li> items with absolute positioning.
The wizard form is working as desired except that I want to hide next or previous button on a certain step.
This is my logic in jQuery but it doesn't do any good.
if (index === 0) {
$('#prev').addClass(invisible);
$('#prev').removeClass(visible);
} else if (index === 1) {
$('#prev').addClass(visible);
$('#prev').removeClass(invisible);
} else {
$('#next').addClass(invisible);
}
To get the index value I used eq() chained on a current step element like the following
var current;
var index = 0;
$(function () {
current = $('.pg-wrapper').find('.current');
$('#next').on('click', function() {
if (current.next().length===0) return;
current.next().addClass('current').show();
current.removeClass('current').hide();
navstep.next().addClass('active');
navstep.removeClass('active');
current = current.next();
navstep = navstep.next();
index = current.eq();
});
I tried to isolate it as much as possible but my full code will give you a better idea.
If you would care to assist please check my JS BIN
There were several issues
you used .eq instead of index
you were missing quotes around the class names
your navigation logic was flawed
no need to have two classes to change visibility
I believe the following is an improvement, but let me know if you have questions.
I added class="navBut" to the prev/next and rewrote the setting of the visibility
Live Demo
var current;
var navstep;
$(function () {
current = $('.pg-wrapper').find('.current');
navstep=$('.nav-step').find('.active');
$('.pg-wrapper div').not(current).hide();
setBut(current);
$('.navBut').on('click', function() {
var next = this.id=="next";
if (next) {
if (current.next().length===0) return;
current.next().addClass('current').show();
navstep.next().addClass('active');
}
else {
if (current.prev().length===0) return;
current.prev().addClass('current').show();
navstep.prev().addClass('active');
}
current.removeClass('current').hide();
navstep.removeClass('active');
current = (next)?current.next():current.prev();
navstep = (next)?navstep.next():navstep.prev();
setBut(current);
});
});
function setBut(current) {
var index=current.index();
var max = current.parent().children().length-1;
$('#prev').toggleClass("invisible",index<1);
$('#next').toggleClass("invisible",index>=max);
}
The eq function will not give you the index, for that you need to use the index() function.
I have not looked at the whole code but shouldn't your class assignemnts look like:
$('#prev').addClass('invisible');
$('#prev').removeClass('visible');
i.e. with quotes around the class names? And is it really necessary to have a class visible? Assigning and removing the class invisible should easily do the job (provided the right styles have been set for this class).
You should make 4 modifications.
1) Use .index() instead of .eq();
2) Add a function changeIndex which changes the class depends on the index and call it on click of prev and next.
3) add quotes to invisible and visible
4) There is a bug in your logic, try going to 3rd step and come back to 1st step. Both buttons will disappear. So you have to make next button visible if index = 0
Here is the demo :
http://jsfiddle.net/ChaitanyaMunipalle/9SzWB/
Use index() function instead of eq() because eq() will return object and index() will return the integer value.
DEMO HERE
var current;
var navstep;
var index = 0;
$(function () {
current = $('.pg-wrapper').find('.current');
navstep=$('.nav-step').find('.active');
$('.pg-wrapper div').not(current).hide();
}(jQuery));
$('#next').on('click', function() {
if (current.next().length===0) return;
current.next().addClass('current').show();
current.removeClass('current').hide();
navstep.next().addClass('active');
navstep.removeClass('active');
current = current.next();
navstep = navstep.next();
index = current.index();
change_step(index)
});
$('#prev').on('click', function() {
if (current.prev().length===0) return;
current.prev().addClass('current').show();
current.removeClass('current').hide();
navstep.prev().addClass('active');
navstep.removeClass('active');
current = current.prev();
navstep = navstep.prev();
index = current.index();
change_step(index)
});
function change_step(value)
{
if (value === 0) {
$('#prev').hide();
$('#next').show();
} else if (value === 1) {
$('#prev').show();
$('#next').show();
} else {
$('#next').hide();
$('#prev').show();
}
}