jQuery on.change specific element of array - javascript

I'm currently struggling with my specific problem. I'm using Symfony Collection entity type and https://symfony-collection.fuz.org/symfony3/ bundle for front-end render. When I click to add a new collection, the new set of input is rendered. I need to hide a specific inputs when a condition is not met. To do that I'm using jQuery. At the start I declare an array of possible HTML ids.
var regularityWeeksArray = [
'#user_working_hours_weeks_0_regularity', '#user_working_hours_weeks_1_regularity',
'#user_working_hours_weeks_2_regularity', '#user_working_hours_weeks_3_regularity'
]
Then I join it for jQuery's requirements, because I didnt figured out how to workaround that. I would love to use this code to run that, but I need to get which specific element of an array is being changed to give my function ID of the element. Now I'm changing the first one, because I don't know how to meet my requirements.
var regularityWeeksArrayToString = regularityWeeksArray.join(', ');
$(document).on('change', regularityWeeksArrayToString, function() {
if($(this).val() === 'interim'){
showInterimWithID(0);
} else {
hideInterimWithID(0);
}
});
Do you have any ideas how to do this? Thanks a lot in advance, I'm really losing my hair for couple of hours now.
//EDIT: for context, this is how showsInterimWithID() looks like, it shows specific inputs and its labels.
function showInterimWithID(id){
$('#user_working_hours_weeks_'+ id +'_interim_from, label[for=user_working_hours_weeks_'+ id +'_interim_from]').show();
$('#user_working_hours_weeks_'+ id +'_interim_to, label[for=user_working_hours_weeks_'+ id +'_interim_to]').show();
}

this.id is the ID of the target of the event. You can get its index in the array.
$(document).on('change', regularityWeeksArrayToString, function() {
var index = regularityWeeksArray.indexOf(this.id);
if($(this).val() === 'interim'){
showInterimWithID(index);
} else {
hideInterimWithID(index);
}
});

Related

Utilizing .each() with an array

I am creating a Matching Card game using jQuery. Currently, I am running into an issue where the playerChoices array in my code does not update the 'matched' cards with the 'matched' class.
var playerChoices = [];
function showCard(){
$(this).addClass('selected'); //mark the selection with the selected class
playerChoices.push($(this)); //push the players choice onto the playerChoices array
console.log(playerChoices);
moves++;
console.log(moves);
$('#buttons').show();
matchCards(playerChoices);
}
Here is the function in question where the issues lie:
function matchCards(array){
if(playerChoices.length === 3){
//when the player finds the first match
if(playerChoices[0].attr('class') === playerChoices[1].attr('class')){ //if both playerChoices have the class
console.log("match found at index 0 and 1 of playerchoice!");
**$(playerChoices).each(playerChoices, function(index, element){
$(this).addClass('matched');**
})
}
//Deselect the two choices that were made
else{
$(playerChoices).each(function(index, element){
$(this).removeClass('selected');
})
playerChoices = [];
}
}
else if(playerChoices.length === 4){
//when the player gets the second match
if(playerChoices[2].attr('class') === playerChoices[3].attr('class')){
console.log("match found at index 2 and 3 of playerchoice!");
**$(playerChoices).each(playerChoices, function(index, element){
$(this).addClass('matched');**
})
**showGameOverMessage();**
}
//Deselect the last two choices that were made
else{
$(playerChoices).each(function(index, element){
$(this).removeClass('selected');
})
}
}
}
The primary issue here are the area's that I have 'asterisks' around in my code. I set up break points in the console, and I found that the code was never reaching the $(this).addClass('matched') lines. I've never used .each before and have looked at the examples api.jquery.com but I still was not able to overcome this issue of applying the matched class to my 'matched' cards.
FYI: I tried to get my code to work in JSFiddle but I kept getting errors with the images of my cards. My code works outside of that, I am just not able to get the matching class to apply appropriately.
https://jsfiddle.net/2sharkp/54s47vzb/ Works now
Any help is greatly appreciated!
Your updated question makes the problem clear: You're pushing jQuery instances into playerChoices:
playerChoices.push($(this));
...then later using $(playerChoices).each(...) to try to loop over them. While $() accepts arrays of HTML elements in the $() function, it doesn't correctly understand it if you pass it an array of jQuery instances — you end up with a jQuery instance wrapped around that set of jQuery instances, which isn't useful — you may as well just use the array (or use a single jQuery instance as I describe later).
You can use $.each (the one on the jQuery function itself):
$.each(playerChoices, function() {
// ...`this` (not `$(this)`) here will be a jQuery instance:
this.addClass('matched');
});
Updated Fiddle
But you really dont need $.each, just use the array's built-in forEach:
playerChoices.forEach(function(entry) {
// ...`entry` here will be a jQuery instance
entry.addClass('matched');
});
Updated Fiddle
...or there are lots of other ways to loop through arrays outlined in my answer here.
That said, you might consider making playerChoices a (single) jQuery instance. jQuery is set-based, so a single jQuery instance can contain multiple HTML elements that you can then act on with just a single method call. For instance, if you made playerChoices a jQuery instance, instead of:
playerChoices.forEach(function(entry) {
entry.addClass('matched');
});
You could do this:
playerChoices.addClass('matched');
To do that, start with:
playerChoices = $();
...and add elements via add:
playerChoices.add(this);
Try removing playerChoices before callback
$(playerChoices).each(function(index, element){
$(this).addClass('matched');
})
jsfiddle https://jsfiddle.net/xowkyh6p/1/

Use a Selector instead of "this" in Jquery

Maybe it's a silly question. But I really can't understand it.
I'm using the Jquery Cycle2. And after some personalization I got a simple problem.
I need to know what is the "Index" of my current slide.
On the plugin's website a found this line of code that perfectly works.
$('#cycle-1 .cycle-slide').click(function(){
var index = $('#cycle-1').data('cycle.API').getSlideIndex(this);
alert(index);
});
It gives me the right index. But I'm trying to catch this Index when another element is clicked. So I can't use the parameter (this).
Then I tried this.
$('.anotherelement').click(function(){
var mycycle = $('#cycle-1 .cycle-slide');
var index = $('#cycle-1').data('cycle.API').getSlideIndex($(mycycle));
alert(index);
});
It doesn't return my current slide index. It returns "-1". Does anyone knows how I should pass the Object (selector) as a parameter to the getSlideIndex() ?
Thanks a lot :D
You can use $('.cycle-slideshow').data('cycle.opts').currSlide to get the current slide index
$('.anotherelement').click(function(){
var index = $('.cycle-slideshow').data('cycle.opts').currSlide;
var currSliderNum = index+1;
alert(currSliderNum);
return false;
});
FIDDLE
In the first piece of code this is a DOM element and not a jquery object. Try this instead:
var index = $('#cycle-1').data('cycle.API').getSlideIndex(mycycle[0]);
However, presumably, you have multiple .cycle-slide elements. This will just get the first one. In your first code you have access to a single one since only one was clicked. You need to decide which one you want to target here.

Is there any function in javascript, to detect a change in document? [duplicate]

This question already has answers here:
Attaching jQuery plugin calls to dynamically loaded elements via jQuery,on()
(3 answers)
Closed 9 years ago.
I have an HTML page, which contains many select boxes, to beautify those boxes I have used "select2", What I have done is:
$(document).ready(function() { $("select").select2(); });
This makes all of the select boxes to get transform like "select2".
But now I am generating the tables on a button click(after the document is ready), therefore the newly generated select boxes doesn't looks like "select2", Please help me if there is any function that detects the change in document?
Something like:
$(document).change(function() { $("select").select2(); });
In at least some browsers (not any current version of IE, though), you can do this, via a MutationObserver (this is the new DOM4 thing, not the old DOM3 mutation events, which you want to stay away from).
But I don't recommend it, just call select2 again after your code that appends the new selects.
Another option is to use a timer: Get a NodeList of all select elements on the page:
var allSelects = document.getElementsByTagName('select');
...and poll checking its length (NodeLists are live, you don't have to re-query):
var lastLength = 0;
setInterval(function() {
if (allSelects.length !== lastLength) {
lastLength = allSelects.length;
// Hook up the new ones here
}
}, 1000); // 1000ms = 1 second
You could put a class on them to keep track of which ones are already done (if select2 doesn't already do that).
But again, you have code adding select elements, just re-trigger there.
You can try something like this:
function checkDocumentChange() {
// Run a simple task to check whether any new "selects" were added
var old_value = checkDocumentChange.num_selects || 0;
var new_value = $("select").length;
if (old_value != new_value) {
$("select:not(.already_done)").select2();
}
checkDocumentChange.num_selects = new_value;
setTimeout(checkDocumentChange, 100);
}
DOM events are not recommended to use since those are deprecated.
Better approach would be, of course, to call .select2() right after you insert select into DOM. So that you will not have to delegate this to some checker or event.
You can try DOMNodeInsertedIntoDocument
$(document).on('DOMNodeInsertedIntoDocument', function() {
}
Or mutation observer
use this id or class
in this code
var id = document.getelementbyid("id for select 1 or 2");
//here the code

JQuery retrieving id from Checkbox at run time

My problem is, I want to retrieve checkbox id at runtime and use them later for other purpose.
But retrieved id is read as object.
My Code is:
// Following code gives id of checkbox which contains myCheckbox as its id.
var myCheckbox= $('input[id$=myCheckbox]')[0].id;
// and Now I want to check if that checkbox is checked with following code:
if ($(myCheckbox).is(':checked'))
return 1;
else
return 0;
But here myCheckbox id is read as Object instead of id and thus always enter in else condition and returns 0. This code works when I enter id of checkbox directly.
if ($('#ctl001_myCheckbox').is(':checked'))
return 1;
else
return 0;
It shouldnot be so complicated, I have been working with Javascript but new to JQuery.
You are getting the ID correctly, but the jQuery selector requires the # symbol, much in the same way as a CSS selector does. You need to add the # character to your selector:
if ($('#'+myCheckbox).is(':checked'))
return 1;
else
return 0;
BenM is correct, but why are you getting the ID of the element, and then look it up again? You already found the element, there is no need to search for it a second time.
Just keep a reference to the element:
var myCheckbox = $('input[id$=myCheckbox]').first();
// or var myCheckbox = $('input[id$=myCheckbox]')[0];
// and later
if (myCheckbox.is(':checked')) {
// or if (myCheckbox.checked) {
Simply:
return (($('#' + myCheckbox).is(':checked')) ^ false);
Have you tried using:
var myCheckbox= $('input[id$=myCheckbox]').attr('id');

How do I attach detached objects

The title already says it ... I'm looking for a way to attach my detached objects.
http://jsfiddle.net/jy2Zj/
At the moment I can realize an alert only. How would I replace the function?
Thanks for your help.
Edit
Another question came up to my mind. Is there a way to suppress the closing of the select box after choosing "all"?
not sure if i understood what you meant..
If i am right you want to simply make a list of all detached objects so you can add them again later:
myArr = ['v2', 'v11'];
var detached = [];
$('select[name="test"] option').each(function() {
if ($.inArray(this.value, myArr) !== -1) {
detached.push($(this).detach());
}
});
$.each(detached,function() {
$('select[name="test"]').find('option').end().append(this);
});
$('select[name="test"]').find('option').end().append('<option value="all">All</option>');

Categories