How to pass a variable to a function inside JQuery - javascript

I have something like this:
for (var i = 1; i <= numPages; i++)
{
buttons.append($("<button onclick='getJSON(i)'>"+i+"</button>"));
}
Now, passing i inside getJSON() function doesn't seem to work.
Any ideas how to solve this?

Other answerers already have described how you can do this.
However, I would recommend another way:
for (var i=1; i<=numPages;i++)
{
$("<button/>")
.addClass('myClass')
.attr('data-my-id', i)
.text(i)
.appendTo(buttons);
}
$(document).on('click', '.myClass', function() {
getJSON($(this).attr('data-my-id'));
});
It will generate the following HTML:
<button class='myClass' data-my-id='1'>1</button>
<button class='myClass' data-my-id='2'>2</button>
<button class='myClass' data-my-id='3'>3</button>
<button class='myClass' data-my-id='4'>4</button>
etc.
Why is this approach better?
Button is now generated using jQuery, but not from a string, which decreases a chance of error
It uses jQuery events instead of onclick attribute
Event delegation for convenient work with dynamically created elements
Element HTML doesn't contain behaviour (event) - it stores data (id)
jQuery is slower than a native JavaScript, but it is important only if we talk about thousands of elements. Otherwise, it is more important that code can be easily written, read and supported.
Also, here is a good article which describes why you shouldn't use onclick attribute`:
jQuery.click() vs onClick

buttons.append($("<button onclick='getJSON("+i+")'>"+i+"</button>"));
You need to concatenate is properly, the way you did for another i

Pass i to the getJSON method as a variable. You have sent it as a string by mistakenly.
for (var i=1;i<=numPages;i++)
{
buttons.append($("<button onclick='getJSON("+i+")'>"+i+"</button>"));
}

Related

Calling a function onclick in Svelte

I began using svelte for a recent project, and although I like the workflow of the framework so far, I've yet to get a single function to work successfully.
Currently, I'm trying to change the innerHTML of a series of objects using functions.
Below is my code:
<head>
<script>
export let question1() {
document.getElementByClass(questionBox).innerHTML = "True or False?";
document.getElementById(ans_1).innerHTML = "True";
document.getElementById(ans_2).innerHTML = "False";}
</script>
</head>
<body>
<div class="container">
<button on:click={question1} class="startButton">Start Game</button>
<div class="box"><span id="questionBox">...</span></div>
</div>
<div class="option-container">
<button class="option" id="ans_1">option1</button>
<button class="option" id="ans_2">option2</button>
</div>
</body>
There is an error marked beneath my function when I call it on:click in the button, and that error reads as follows:
'question1' is not defined. Consider adding a <script> block with 'export let question1' to declare a propsvelte(missing-declaration)
I am quite new to svelte and it's entirely possible I misunderstood something structurally within my code, but I've checked all over and can't seem to find anything that quite addresses my problem.
Any help would be quite appreciated. Perhaps I just need some new eyes on this.
Thank you.
Here's the list of things you might have gotten wrong.
Function declaration
This is valid:
function question1() {
//dosomething
}
This is valid too (arrow function):
let question1 = () => {
//dosomething
}
But this is not a correct way:
let question1() {
//dosomething
}
getElementByClass is not a correct method. You probably meant getElementsByClassName.
document.getElementByClassName("questionBox").innerHTML = "something"
Note that if you have more than one element with that class name, only the first item will be affected.
Easiest way to get a single element is to use:
//by class name
document.querySelector(".classname")
//by id
document.querySelector("#id")
//by element type
document.querySelector("div")
You dont need to add <head> tag in your code. Each svelte file can have a <script> and <style> element in the component at top level.
You are trying to change text in elements in a Vanilla JS way. You should probably populate the DOM using data so that you are taking advantage of Svelte's amazing reactivity. Look at this REPL to see a replication of what you are trying to do in a more Svelty way. Basically, use data to dynamically render the DOM elements. That way, you will never directly manipulate the DOM Elements. Just change your data and Svelte takes care of changing the DOM.
https://svelte.dev/repl/8316ae63d83b443aaef5aa7b29c36dc1?version=3.53.1
Use betternames for your functions. question1 as a function name is not descriptive of what you are doing inside.
If you still want to modify the DOM elements directly, you can bind them to variables like so and change text like so:
https://svelte.dev/tutorial/bind-this

Javascript can't apply an existing function to onkeyup

I have a bunch of HTML number inputs, and I have grabbed them by
x=document.querySelectorAll('input[type="number"]');
I then try and iterate through this with a for-loop, and apply an onkeyup function. The function is this:
t=function(elem){
elem.onkeyup=function(e) {
if(!/[\d\.]/.test(String.fromCharCode(e.which))) {
elem.value='';
}
};
};
Basically, what it does is clear the value of the input if there is a letter typed in. I know I can apply it via HTML:
<input type='number' onkeyup='t(this)'/>
But how can I do it with Javascript? I tried iterating through it with:
x=document.querySelectorAll('input[type="number"]');
for(i=0; i<x.length; i++){
x[i].onkeyup=t(this);
}
but it doesn't work. What am I doing wrong? How can I do this? Please regular JavaScript answers only, no jQuery or other frameworks/libraries.
change
x[i].onkeyup=t(this);
to
x[i].onkeyup=t(x[i]);
because this isn't what you want it to be
Apologies, all. I found my answer. Agreeing with Jaromanda X, I needed to change
x[i].onkeyup=t(this);
to
x[i].onkeyup=t(x[i]);
This (pun intended ;)was part of the problem, but the main problem was that the valid property name is
keyup=function();
and not
onkeyup=function(){}'

innerHTML not working properly when used on a jQuery object

This code isn't working as expected. It is not showing any text inside of span.day where it should be showing today's day (Tuesday at the time of writing). It is also not properly adding the class "currentDay" inside of the $.each callback.
$('#showLess span.day').innerHTML=weekday[today];
$.each($('#showMore p span.day'), function(index, item) {
if(typeof item.innerHTML != 'undefined')
{
alert('item.text:' +item.innerHTML);
alert('weekday[today]'+item.innerHTML.indexOf(weekday[today]));
if(item.innerHTML.indexOf(weekday[today])!=-1) {
alert("check which element has added class currentDay:");
item.addClass('currentDay');
}else{
if(item.hasClass('currentDay')) {
item.removeClass('currentDay');
}
}
}
});
.innerHTML is not changing the HTML, additional class is not getting added as expected.
<p id="showLess" class="less">
<span class="day">**Tuesday**</span>
</p>
Why isn't the day showing?
Why is the show/hide not working?
$('.less').on('click', function(e) {
$('#showMore').show();
$('#showLess').hide();
});
$('.more').bind('click', function(e) {
$('#showLess').show();
$('#showMore').hide();
});
You are trying to invoke JS properties on jQuery objects.
For example innerHTML
And you are trying to invoke that on a jQuery object.
$('#showLessHours span.day').innerHTML
Should be
$('#showLessHours span.day')[0].innerHTML
or
$('#showLessHours span.day').html(weekday[today]);
And in your each loop item is a JS object and you are trying to add a class using jQuery. Convert that to jQuery object first .
item.addClass('currentDay');
item.removeClass('currentDay');
should be
$(item).addClass('currentDay'); or $(this).addClass('currentDay');
$(item).removeClass('currentDay'); or $(this).removeClass('currentDay')
Instead you can use the $(this) as well instead of $(item) object inside the callback as both refer to the same objects.
Another small suggestion is why do you want to mix vanilla JS and jQuery when jQuery is included and you want to use that in your application.
jsFiddle
Because .innerHTML isn't a jquery function. You can use .html() to achieve what you are trying to do. Alternatively, if you REALLY want to use .innerHTML, you can use .get() to get the actual DOM element, and then use .innerHTML but... I wouldn't recommend it.
I believe this edited fiddle solves your problem. Relevant code:
$('#showLessHours span.day').html(weekday[today]);
//...
if(item.html() != '') {
alert('item.text:' +item.text());
alert('weekday[today]'+item.text().indexOf(weekday[today]));
if(item.html().indexOf(weekday[today])!=-1) {
//...
In addition to what Sushanth said, you are also trying to invoke jQuery methods on javascript objects.
item.addClass
should by
$(item).addClass

Finding $(this) after a function

So here's my problem: I'm using a function and I need the function to be specific to each tr with the class "middleone". It's supposed to change the insides of a div inside of the the tr with the class "middleone". But it's not working!
I know the recursive portion of it is working, and the "navigation" should be spot on, because even when i'm using just $(this) it doesn't do anything. When using document.getElementById it works fine but of course that only targets the first div and the full version of the code has to "Go here, pull from here, put it here, go to the next area, pull from here.. etc" Here's the testing code.
$('.middleone').each(function() {
var tripleeagain = $(this).find('div')
tripleeagain.innerHTML = "$";
});
Thanks for any help
tripleeagain is a jquery object collection upon which you should use html() instead of innerHTML
Basically you could just write:
$('.middleone').find('div').html("$");
If you are doing specific stuff inside the loop then:
$('.middleone').each(function() {
//Some specific logic
var tripleeagain = $(this).find('div').html("$");
});
The problem is you are trying to access native API from a jQuery object.
var tripleeagain = $(this).find('div');// this will return a jQuery object
So you should use the jQuery API for setting the html contents
tripleeagain.html("$");
jQuery html API documentaion

jQuery equivalent to [function].parameters from javascript

I've had this javascript function that I've used many many times over ...
function showHideObjects()
{
var args;
args = showHideObjects.arguments;
for(var i=0;i<args.length;i++)
{
if(document.getElementById(args[i]))
{
if(args[i+1] == 'flip')
{
if(document.getElementById(args[i]).style.display == '')
{ document.getElementById(args[i]).style.display = 'none';}
else
{ document.getElementById(args[i]).style.display = '';}
}
else
{
document.getElementById(args[i]).style.display = args[i+1];
}
}
i++;
}
}
Now I'm working with ASP.NET and need that same function but in jQuery but I can't find any information about dynamic parameters in jQuery. Is there a way to do this in jQuery?
To provide a little more background ... you could call the above code with a line like ... showHideObjects('div1','none') and it'd hide div1. Or you could call ... showHideObjects('div1','none','div2','','div3','flip') and it'd hide div1, show div2 and switch div3 from either hidden or shown.
jQuery is just JavaScript. Your code will work fine with jQuery.
It is purely a javascript feature. Jquery do not have any special feature for this.
As some have already said, jQuery is Javascript and your code will work just fine. BUT you can do the same thing with jQuery that you are now doing with your function. You are getting elements which you change to have either display none or nothing.
jQuery has Selectors, which you can use to select the elements from the DOM to which you want to do something to. You can forexample use selectors to select the element you want and then just cast .toggle(). It does the exactly same thing as your function but with just 1 line of code.
EDIT: Added an example:
If you have a div, which has a class hideNseek, you can use this to toggle it to show or hide:
$(".hideNseek").toggle();
$(".hideNseek") is selectors which selects all classes that have that name.
Like others have said, your function will work just fine. You don't NEED jQuery to do what you are doing. If you wanted to use jQuery you could do something like:
function showHideObjects() {
var args = arguments,
l=args.length;
for ( var i=0; i<l; i++ ) {
var elem = $( "#"+args[i] ),
type = args[i+1];
if ( elem.length ) {
if ( type == "flip" ) {
elem.toggle();
} else {
elem.css("display", type);
}
}
i++
}
}
You can't call different actions on a group in JQuery. However, you can perform the same action (hide, show, toggle) on a group of elements by using the appropriate selector to get the group. Here's a quick example that has buttons to toggle all the div elements and all the span elements on the page with the JQuery toggle function, along with a fiddle for testing:
HTML:
<div>div 1</div>
<span>span 1</span>
<div>div 2</div>
<span>span 1</span>
<input id="toggleSpans" type="button" value="toggle spans"/>
<input id="toggleDivs" type="button" value="toggle divs"/>
JavaScript:
$('#toggleDivs').click(function(){
$('div').toggle();
});
$('#toggleSpans').click(function(){
$('span').toggle();
});
If that is not good enough, you can easily group and call these methods in a custom function as you do in your old JavaScript function, or just keep your old method.
UPDATE:
Check out the different selectors you can use. In your specific case, you'd need to use ID Selector along with Multiple Selector, but you could make your function much more powerful if you allowed passing in any JQuery selector rather than just the ids. For example:
showHideObjects('#div1, <otherSelectorsToHide>','none',
'#div2, <otherSelectorsToShow>','',
'#div3, <otherSelectorsToToggle>','flip');

Categories