I have a dropdown list i want to change the view on jquery change events
Html code is
<select id="pu_viewToLoad" class="select-dark" name="viewToLoad"></select>
Js code
$("#pu_viewToLoad").change(function(evt) {
evt.preventDefault();
var index = parseInt($("#pu_viewToLoad option:selected").val(), 10);
if (index >= 1000) {
index -= 1000;
console.log("Changing to 2D view: " + _views2D[index].name);
switchSheet();
loadView(_viewerSecondary, _views2D[index]);
}
else {
console.log("Changing to 3D view: " + _views3D[index].name);
switchSheet();
loadView(_viewerSecondary, _views3D[index]);
}
});
This function is not executing
You should either use:
var index = parseInt($("#pu_viewToLoad option:selected").attr("value"), 10);
Or
var index = parseInt($(this).val(), 10);
Please change accordingly. And make sure you are running the above function inside the $(document).ready() function.
Related
Im trying to program something using JQuery that will search a webpage for every instance of a certain word and then click on it. How would I do this?
I currently have something like this:
$(document).ready(function(){
function follow(texttofind, texttoexclude, setinterval){
var buttons = $( "*:contains('"+texttofind+"'):not(:contains('"+texttoexclude+"'))" );
var i = 0;
interval = setInterval(function() {
while(i <= buttons.length) {
i++
buttons[i].scrollIntoView();
buttons[i].click();
}
}, setinterval);
}
follow("text", "200");
});
The value of i is changing every time the while loops.
You can simplify it all by using $.each() instead of while/[i]:
$(document).ready(function() {
function follow(texttofind, texttoexclude, setinterval) {
var buttons = $("*:contains('" + texttofind + "'):not(:contains('" + texttoexclude + "'))");
interval = setInterval(function() {
buttons.each(function(i, button) {
button.scrollIntoView();
button.click();
});
}, setinterval);
}
follow("text", "stop", "2000");
});
See demo here.
I have searched for an answer for this and I understand how event delegation works but what ever I try nothing changes.
The buttons that are dynamicaly created will not trigger the on event when manually clicked however using the trigger() method works, what is wrong with my code?
components.forEach(function (component) {
var id = randomId();
var li = $.create("li").addClass("col-12");
componentList.append(li);
var btn = $.create("button")
.text(component.type)
.attr("id", id)
.addClass("btn")
.appendTo(li);
componentList.on("click", "#" + id, function () {
alert("test");
window.circuit.push(component.create());
circuitList.refresh();
});
btn.trigger("click");
});
$.create = function (arg) {
return $(document.createElement(arg));
}
randomId = function () {
return "id" + Math.floor(Math.random() * 100000) + "_" + Math.floor(Math.random() * 100000);
}
The display is as expected, the buttons just won't fire manually.
Components is an array of objects with a type property and create method.
The following statement was erroneous:
componentList.on("click", "#" + id, function () {...
jQuery is smart enough to know which button was clicked just by using a class or even a tag as the second parameter.
$('.list').on("click", '.btn', function(e) {
Details commented in Demo
Demo
/* Had no idea what components is supposed to be */
var components = ['potentiometer', 'transistor', 'capicitor', 'transformer'];
/* On each loop $.map() will run a function */
$.map(components, function(cmp, idx) {
var ranID = randomId();
/* Creating nodes is easy with jQuery
|| You can actually assign a string to a
|| jQuery object and when used with a jQuery method
|| it would be parsed into real HTML
*/
var li = $('<li class="col-12"></li>');
$('.list').append(li);
/* This string is a Template Literal. a TL is a
|| string with a powerful syntax.
*/
var btn = $(`<button id='${ranID}' class='btn' type='button'>${cmp}</button>`);
btn.appendTo(li);
});
/* Originally the OP has a dynamically generated
|| id as the 'this', that's wrong and pointless.
|| That second parameter should be a class ex. '.btn'
*/
$('.list').on("click", '.btn', function(e) {
var ID = $(this)[0].id;
$(`<label for="${ID}"> ${ID}</label>`).insertAfter($(this));
console.log(ID);
alert(`ID:${ID} Type: ${this.textContent}`);
});
function randomId() {
return "id" + Math.floor(Math.random() * 100000) + "_" + Math.floor(Math.random() * 100000);
}
<ol class='list'></ol>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Can anyone tell me why my IF statement is firing before updating the UI with the each loop?
The code basically wants to delay adding css classes to the UI then once each one has been added, redirect the user. It currently just directs immediately?!
$("#logo").click(function() {
//define variables:
var eventDuration = 500;
var elementArray = ['ribbon', 'left-panel', 'wid-id-1', 'wid-id-2'];
var animationArray = ['slideOutRight', 'slideOutLeft', 'rotateOutUpRight', 'rotateOutUpRight'];
//Loop through elements and update UI with timer function:
$.each(elementArray, function(index, value) {
//Increments the delay of the element updates:
var delaytimer = index * eventDuration + eventDuration;
//Adds animation css classes to onpage elements:
$('#' + value).delay(delaytimer).queue(function() {
$(this).addClass('animated ' + animationArray[index]).dequeue();
});
//Once complete redirect to the home page:
if (index === 3) {
$(this).delay(delaytimer + 500).queue(function() {
window.location.replace('/').dequeue;
});
}
});
});
Your if statement is being executed immediately because it isn't inside the delay function. Try moving it in there.
$('#' + value).delay(delaytimer).queue(function() {
$(this).addClass('animated ' + animationArray[index]).dequeue();
//Once complete redirect to the home page:
if (index === 3) {
$(this).delay(delaytimer + 500).queue(function() {
window.location.replace('/').dequeue;
});
}
});
Hi guys this might be a really stupid error but im using jquery to add a formset to a page it also does other things such as updating the number of forms but that does not seem to be a issue.
http://jsfiddle.net/b5Y8f/
$(document).ready(function () {
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '_set-\\d+-)');
var replacement = prefix + '_set-' + ndx + '-';
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function changeDeleteForms(el, prefix, formid) {
var idstring = 'id_' + prefix + '_set-' + formid + '-DELETE';
//$('<input>').attr({type: 'hidden', id: 'id_' + idstring, name: idstring}).appendTo('.command-delete');
$('#' + idstring).prop('checked', true);
}
function deleteForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '_set-TOTAL_FORMS').val());
if (formCount > 1) {
// Delete the item/form
$(btn).parents('.command').hide();
$(btn).parents('.command').attr('class', 'command-delete');
var dc = $(".command-delete");
$(dc).children().children().children().each(function () {
var formid = this.id.match(/\d+/g);
changeDeleteForms(this, prefix, formid);
//$(this).val("");
});
var forms = $('.command'); // Get all the forms
var formsdelete = $('.command-delete'); // Get all the forms
var fl = parseInt(forms.length);
var fdl = parseInt(formsdelete.length);
var finalcount = fl + fdl
// Update the total number of forms (1 less than before)
//$('#id_' + prefix + '_set-TOTAL_FORMS').val(forms.length);
var i = 0;
} // End if
else {
alert("Please enter atleast 1 command for this item.");
}
return false;
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '_set-TOTAL_FORMS').val());
var maxCount = parseInt($('#id_' + prefix + '_set-MAX_NUM_FORMS').val());
var forms = parseInt($('.command-delete').length); // Get all the forms
var newcount = formCount + forms;
// You can only submit a maximum of 10 todo items
if (newcount < maxCount) {
// Clone a form (without event handlers) from the first form
var row = $(".command:first").clone(false).get(0);
// Insert it after the last form
$(row).removeAttr('id').hide().insertAfter(".command:last").slideDown(300);
// Remove the bits we don't want in the new row/form
// e.g. error messages
$(".errorlist", row).remove();
$(row).children().removeClass("error");
// Relabel or rename all the relevant bits
$(row).children().children().children().children().each(function () {
updateElementIndex(this, prefix, newcount);
$(this).val("");
});
// Add an event handler for the delete item/form link
$(row).find(".delete").click(function () {
return deleteForm(this, prefix);
});
// Update the total form count
$("#id_" + prefix + "_set-TOTAL_FORMS").val(newcount + 1);
} // End if
else {
alert("Sorry, you can only enter a maximum of 1000 items.");
}
return false;
}
// Register the click event handlers
$("#add").click(function () {
return addForm(this, "itemcommands");
});
$(".delete").click(function () {
return deleteForm(this, "itemcommands");
});
$('.command input:checkbox').hide();
});
If you go to the link above you can see the code works perfectly fine it update the form count and add the new form with the new number in the id and everything however in production when you click the add command button for the first 3 times it does not show however the code has been enter into the page and the form is technically there but not shown.
on the fourth time you press the button it works and the row has been added after the last ('.command') in the element.
What could be causing it to work on JSFiddle but not on production?
-------------------UPDATE--------------------------
It seems if i remove the overflow hidden from the 3 that dont show when you press the button the first 3 times it will show them in the correct place.
Why would overflow no be removed from the first 3 form rows but the rest after fine?
----------------------UPDATE--------------------------
Think i have found the issue and its nothing to do with the JQUERY at all it seems to be bootstraps responsive layout hiding the forms i think if i add them specifically to their own rows i can fix this.
Thanks for the help though guys.
I don't see a src="*jQuery source*" in your file. Since JSFiddle already adds the source to the file, you may have forgotten to put it in.
I have built a dropdown menu system, everything works when tested independently, the problem I have is in the code below. I use the jQuery ready function to build the menu bar from an external array (menubar[]). Here I am trying to get the mouseover event to call the dropdown() function, but using a different argument for each anchor tag.
So rolling over the first should call dropdown(0), the second dropdown(1) and so on.
$(document).ready(function () {
for (i in menubar) {
var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
'" class="menutitle">' + menubar[i].name + '</a>';
var a = $(declaration).mouseover(function () {
dropdown(i);
}).mouseout(function () {
activeTimer = setTimeout("removedropdowns()", 100);
});
$("#menu").append(a);
}
});
The code is calling dropdown(6); on each rollover. How can I pass the loop variable (i) into the mouseover function as a literal/static value!
I got this working fine in FF by using
.attr('onMouseOver','javascript:dropdown('+i+');')
but that wasn't firing for some versions of IE, so I switched to the jQuery mouseover, which fires, but I have the issue above :(
Your actual problem is that each of your mouseover callbacks uses the same i you increase i all the way up to 6, the callbacks still point to the same i and therefore all use 6 as the value.
You need to make a copy of the value of i, you can do this by using an anonymous function.
$(document).ready(function () {
// you should use (for(var i = 0, l = menubar.length; i < l; i++) here in case menubar is an array
for (var i in menubar) {
var declaration = '<a href="' + baseurl + '/' + menubar[i].url +
'" class="menutitle">' + menubar[i].name + '</a>';
(function(e) { // e is a new local variable for each callback
var a = $(declaration).mouseover(function () {
dropdown(e);
}).mouseout(function () {
activeTimer = setTimeout(removedropdowns, 100); // don't use strings for setTimeout, since that calls eval
});
$("#menu").append(a);
})(i); // pass in the value of i
}
});
$(function() {
$(menubar).each(function(i){
$("#menu").append('' + menubar[i].name + '');
});
$("#menu a").hover(
function(){
dropdown($(this).index());
},
function(){
activeTimer = setTimeout("removedropdowns()", 100);
}
);
});
First, don't use for..in but rather ordinary loop.
Second, I would just append the links first then apply the events later:
$(document).ready(function() {
for (var i = 0; i < menubar.length; i++) {
$("#menu").append('' + menubar[i].name + '');
}
$("#menu a").each(function(index) {
$(this).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
});
});
Have a look here and here.
To capture the current value of i, you need to pass it as a parameter to another function where it can be captured as a local variable:
Try using jQuery's each() function:
jQuery(function() {
jQuery.each(menubar, function(index, element) {
var declaration = '' + element.name + '';
var a = $(declaration).mouseover(function() { dropdown(index); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
$("#menu").append(a);
});
});
In JavaScript, if you don't declare your variable, it is defined globally. To fix this, add "var" in front of your i looping variable like this. UPDATE: As Sime noticed (see comment), you also need to pass the variable into the function, otherwise you form a closure on the i.
$(document).ready(function() {
for(var i in menubar) {
var declaration = '' + menubar[i].name + '';
var a = $(declaration).mouseover(function(i) { dropdown(i); }).mouseout(function() { activeTimer = setTimeout("removedropdowns()", 100); });
$("#menu").append(a);
}
});