Is it possible to declare Javascript function variables in html? - javascript

Sorry, I am just very new in this and had a previous experience in C++, and the question is it possible to do in javascript/html.
I want to make a function in JavaScript which replaces image on click using an array of image locations. Is it possible somehow to declare the needed variable (position number in the array) in the html? So I don't have to create a separate function for each individual image.
In the c++ you make a function and then declare a variable inside the brackets. Is it possible here, and if not, is there any close solution?
JavaScript:
var imgArray = ["images/2.jpg","images/3.jpg"]
function newImage() {
document.getElementById('pic').src = imgArray[1];
}
HTML:
<div class="project" id="ba">
<p onclick="newImage()">Poster</p>
</div>
Is it possible to insert the number in html "newImage(NUMBER)"?

You can send the index number from HTML and receive that in the javascript function as a parameter:
function newImage(index) {
document.getElementById('pic').src = imgArray[index];
}
// in the html
<div class="project" id="ba">
<p onclick="newImage(1)">Poster</p>
</div>

If you plan on using only one <p>, you can initialize a counter variable which gets incremented every time you click on "poster" label and mod it to the length of the images array. It would loop the available images.
var imgArray = ["images/2.jpg","images/3.jpg"]
var counter = 0;
function newImage() {
document.getElementById('pic').src = imgArray[counter];
counter = ++counter % imgArray.length;
}
<div class="project" id="ba">
<p onclick="newImage()">Poster</p>
</div>
<img id="pic" src="#"/>
Else, update your newImage() function to have an argument newImage(index) and pass the needed index in your <p onclick="newImage(1)">poster</p>

You can't really declare variables in HTML. So it's impossible to do something like onclick="newImage(variable);", with exclusively HTML. If you're using a framework like ASP.NET you can do things like onclick="newImage(#variable);" using Razor. I believe Angular, React, etc. all provide similar functionality.
However, there are other ways to achieve something similar in a "vanilla" setup.
If it's just a static number you can pass it with no variable. Something like onclick="newImage(3);"
You can also set a value attribute which can be accessed in JavaScript as well. something like <p id="poster" value="3" onclick="newImage();">Poster</p>.
Then in JS:
function newImage(){
value = document.getElementById("poster").value;
/* do something with the value */
}
If you're using PHP you can also pass PHP variables to JavaScript through the onclick function as demonstrated here. I would recommend this route if you're dynamically generating your HTML (e.g. within a PHP loop) and might not want to hard code each individual value.

Related

Creating dynamic divs

Trying to make a dynamic div but i don't know how. Wrote a solidity smart contract that accepts an array of struct. In the smart contract i can use a get function to display the data inside. Data in the array is treated like a history, it consists of amount (making a crowdfund site), date, currency used, etc. Since the get function in the smart contract can only extract one part of the array, i thought of putting the get function into the while loop and extract the whole history array..
<div id=set>
<a>value1</a>
<a>value2</a>
</div>
I'm trying to dynamically create another div with the same amount of < a > in the div. If i had 10 sets of data to display in that div, i wish to create only 10 sets of that div. Can createElement() be used to do that? Couldn't find any solution that works. Totally have no idea on how to create it. Can someone please help.
Would it be rational to extract the data from the array using a while loop and putting it in a div to display or would it use too much gas for this to work?
I don't get why would you want to do this, but you can do like this:
$('#set a').each(function(){
$('#set').after( "<div></div>");
});
It selects all of the <a>...</a> inside the <div id="set">...</div> element, and for each one of those inserts a <div></div> element. It inserts the element right next to #set but you can change that to any other element you could select.
I'm supplying jQuery code since you tagged the question as jQuery.
Hope it helps,
You can get the number of anchor tags by using this function getElementsByTagName('a').length from the hosting div. Then use that number to create new divs. This solution is done using vanilla JS.
function createDynamicDivs(){
var newDiv = document.createElement("div");
var noOfAnchors = document.getElementById('set').getElementsByTagName('a').length;
for(var i=0;i<noOfAnchors;i++){
var newContent = document.createElement("a");
newContent.textContent= "Test ";
newDiv.appendChild(newContent);
}
document.getElementById('new').appendChild(newDiv);
}
<div id=set>
<a>value1</a>
<a>value2</a>
</div>
<div id="new"></div>
<button onclick="createDynamicDivs()">Generate</button>

making HTML id a variable in javascript

i am trying to make an image named id='pr' a variable like this.
my HTML code is
<div id="main">
<img id ='pr' style="width: 500px;height: 600px;"src="https://i.redd.it/2u0y0z5i12py.png">
</div>
My javascript code:
<script type="text/javascript">
var getElementById('pr') = 1
if (getElementById('pr' = 1)) {alert ('im pickle rick bitch')}
</script>
So what i am trying to do is make a variable for pr and give it a value of one so it triggers the alert if pr is the image in the gallery.Hopefully i explained it good cause my english is not the best!(im also a noob)TY!
Your main issue is that if you make a variable for pr and then you set that variable to 1, you'll lose the reference to pr.
In other words:
var document.getElementById("pr") = 1;
is not valid code because you didn't specify a variable name. But, even if you did:
var x = document.getElementById("pr") = 1;
x would, at first hold a reference to pr and then immediately lose that value and instead be set to 1.
You also have a problem with your if condition because the single equal sign (=) is for setting a value, not comparing two values. So, your condition will always return true. JavaScript uses == and === for comparisons.
If you need a way to keep track of the element, you can give each element a data-* attribute as shown below:
var element = document.getElementById('pr');
// We can extract the data-count attribute value (a string)
// with the .dataset.count property:
if (element.dataset.count === "1") {
alert ('im pickle rick bitch');
}
<div id="main">
<!-- The data-* attributes are designed to allow you to store meaningfull data with an element. -->
<img id ='pr' data-count="1"
style="width: 500px;height: 600px;" src="https://i.redd.it/2u0y0z5i12py.png">
</div>
Try this:
var foo = document.getElementById('pr');
if (foo) {alert ('im pickle rick bitch')}
This will fix your issue with running the code and will only show if your id exists. But I suggest you have a look at some javascript tutorials. This will help you understand Suren Srapyan's answer better.
You can set a value for img, but as I understand you need to add some extra info on the img tag. You can do it via setAttribute and getAttribute methods.
In your code you have some errors. Your variable declaring is wrong. You need to give to your variable a name, in my case it's myPr and assign to it the vlaue which return document.getElementById not just getElementById. Then use setAttribute method to set some HTML5 constraint attribute called dataId. After it you can use getAttribute method to get that value and use in your logic.
const myPr = document.getElementById('pr');
myPr.setAttribute('dataId', 1);
if(Number.parseInt(myPr.getAttribute('dataId')) === 1) {
alert ('im pickle rick *****');
}
<div id="main">
<img id ='pr' style="width: 500px;height: 600px;"src="https://i.redd.it/2u0y0z5i12py.png">
</div>

Add new AngularJS variables with JavaScript

I'm trying to make a dynamic form with AngularJS and JavaScript. The objective is to add how many inputs the user need and transform all those inputs in AngularJS variables that print it on body. So I got that code:
$(function(){
var number = 1;
$('a.add').click(function(e){
e.preventDefault();
$('#this_div_contains_settings').append('<input type="text" name="example'+number+'" ng-model="example'+number+'" placeholder="Anything">');
number++;
});
$('#this_div_contains_settings').on('click','a.design_button', function(e){
e.preventDefault();
$(this).parent().remove();
});
});
This function add a INPUT on my DIV with the different ng-model every time it run.
The problem is, it just work's if the {{example1}} is already on my BODY, if I add it later with another function, it just doesn't work.
I'm new with AngularJS, so I didn't understand if I need to "refresh" the AngularJS everytime I add new variable or something like that.
Any help will be appreciated :)
Using jQuery is the wrong way to solve this problem. Instead, create an array inside of your controller that will hold the models for all of these inputs.
Depending on how you define/create your controllers, $scope may be replaced with this
$scope.examples = [];
Next, create a function that will add a new example to the array:
$scope.addExample = function () {
$scope.examples.push("");
}
Now, in your template, create the inputs using an ng-repeat:
<div id="this_div_contains_settings">
<input ng-repeat="example in examples" type="text" name="example" ng-model="example" placeholder="Anything">
</div>
and have your "add" button call your addExample function on click:
<a class="add" ng-click="addExample()">Add Example</a>
Finally, remove all of the code that was included in your question.
And for your .design_button that removes all the examples, that's easy too:
<a class="design_button" ng-click="examples = []">remove all examples!</a>
by that same concept, you could even remove the need for the addExample function, however i tend to keep logic in the controller (well, actually in the services, but that's another topic) anyway rather than putting it in the template.

Passing Values from a JSP page to a javascript function

I have a jsp page that updates what is listed based on the selection in a box.
<form:select path="Value" id="select" onchange="update()" items="${Values}" />
And in another file the corresponding update function that populates based on what you selected and the item. This works for one box, but I need to have multiple boxes, but copying the code into a for loop generates multiple boxes, but the update function only points to the id of the object "select". I want to create a way to have select to be variable, so that it generates multiple objects with different values so that they don't point to the same thing.
My thought was to just create a var and then have it count, so that at id="select" can force it to create different objects... but the update function reads from the jsp with
var Val = $('#select option:selected').val();
In order to make them match, I need to pass parameters into the update() function, but when I fill in update method with parameters, the JSP can no longer call it. I tried
Update(var n) { //code here}
and
Update(int n) {//Code here}
But when the JSP statement runs update(//ValueIwant), it always throws the error of not finding the method.
So my question is , how can I pass a parameter from a jsp page to the javascript function dynamically without hardcoding all the values.
i figured it out. It's pretty simple. Just call the function(Parameters) from JSP, but in the javascript, the method is just declared with the parameter not having a type.
Function Myfunction (N)
{
//code
}
In this specific situation, the javascript keyword this can be used to pass along the reference of the element.
Staying as close as possible with provided code (including jQuery use), this would be:
<form:select path="Value" id="select" onchange="update(this)" items="${Values}" />
<!-- 3 more times; id should be changed and kept unique -->
<!-- ... -->
<script type="text/javascript">
function update(srcElement) {
var Val = $(srcElement).find('option:selected').val();
// want to make sure it's OK so far?
console.log(Val);
}
</script>
Now, in the general case, as others have mentioned, it's essentially a question of how you use the JSP tags so as to generate HTML (and here embedded javascript) that does what you want it to do.
I haven't practiced Spring MVC (I assume that's what is being used here), but in pseudo-code, this could look like:
<!-- remember? this is *pseudo-code*,
for I ignore the form:select capabilities,
specifically towards runtime expressions like ${i}
-->
<% for(int i= 0; i<4 ; i++) { %>
<%-- maybe the following line is not 100% OK;
fix it according to your taglib documentation --%>
<form:select path="Value" id="select${i}"
onchange="update(${i})" items="${Values}" />
<% } %>
<script type="text/javascript">
function update(index) {
var Val = $('#select' + index + ' option:selected').val();
// want to make sure it's OK so far?
console.log(Val);
}
</script>

What's wrong with this jquery loop?

To summarise briefly what I'm trying to do: I'm providing the facility for a user to view a gallery of thumbnail images, each with a corresponding download link. When the download link is clicked, I present the user with a confirmation div, and assuming the user clicks 'agree', they'll be able to proceed with the download of the full size version of the thumbnail.
To do this, I'm using a repeater to generate the thumbnails. I'm creating a unique id for each link within the 'ItemCreated' event, along with a unique hidden field that stores the relative path for the destination file for that thumbnail.
When the user clicks on the 'Download' link for the appropriate thumbnail, my code should select the 'agree' link, and update it's target path with the hidden field value of the item that was clicked (I hope that made sense?). This basically means whenever a 'Download' button is clicked, the 'agree' link is updated to direct you to the correct file.
The problem that I'm having however is that my 'agree' link never gets updated - it seems to point to the same file for every thumbnail.
Here's a snippet of the rendered thumbnail list:
<div class="download-listing">
<div class="download">
<img src="/img/thumb0.jpg" alt="" />
<div id="downloadLink0" class="dl">Download</div>
<input type="hidden" id="hf0" value="/GetImage.ashx?path=/img/0.jpg" class="hf" />
</div>
<div class="download">
<img src="/img/thumb1.jpg" alt="" />
<div id="downloadLink1" class="dl">Download</div>
<input type="hidden" id="hf1" value="/GetImage.ashx?path=/img/1.jpg" class="hf" />
</div>
<div class="download">
<img src="/img/thumb2.jpg" alt="" />
<div id="downloadLink2" class="dl">Download</div>
<input type="hidden" id="hf2" value="/GetImage.ashx?path=/img/2.jpg" class="hf" />
</div>
</div>
<input id="count" type="hidden" value="3" />
<!-- Hidden popup -->
<div id="popup">
<p><a id="close" class="bClose action">I disagree</a><a id="file-link" class="action" href="#">I agree</a></p>
</div>
Hopefully you can see from the above code that I'm trying to extract the hidden field path from the download that's clicked, and then update the #file-link 'href' with this value.
The Javascript/Jquery I'm using (and this is where the problem seems to be) is the following:
<script type="text/javascript">
$(document).ready(function () {
for (var i = 0; i < $("#count").val(); i++) {
var index = i;
$("#downloadLink" + index).click(function () {
$('#file-link').attr('href', $('#hf' + index).val());
$('#popup').bPopup();
});
}
});
</script>
However, none of this is working! What seems to be happening is that every download link points to the same path - the last one in the list. I can't figure out where I'm going wrong. Is there something obvious I'm missing?
I appreciate any help given!
Thanks
Isn't it easier to do this:
$(function(){
$(".download .dl").click(function(){
$('#file-link').attr('href', $(this).next("input").val());
$('#popup').bPopup();
});
});
Try Something like this...
$("div[id*='downloadLink']").click(function () {
$('#file-link').attr('href',$(this).siblings('img').attr('src'));
$('#popup').bPopup();
});
After a click on any download link, this code will pass the associated image href path to the file-link element.
here is the working fiddle
I'd recommend against using all those input fields. It just creates a bunch of unnecessary markup. Why not store the #count value simply in a JavaScript variable? And the inputs that contain the image paths could be removed as well. You could store that info in an attribute on each download link, named something like "data-path". For example:
<div id="downloadLink0" class="dl" data-path="/GetImage.ashx?path=/img/0.jpg">Download</div>
Now, going back to your original problem, the above markup would solve the issue quite easily:
$('.dl').click(function(){
$('#file-link').attr('href', $(this).attr('data-path')); //could also do $(this).data('path') if using jQuery 1.6 or later
$('#popup').bPopup();
});
Other people have already suggested different ways to achieve what you want, but nobody explained why your current code doesn't work.
The reason it currently doesn't work is because of how scope works in Javascript. There is no block scope* and so your index variable is defined once, and updated every time the loop runs, until in the end it has the maximum (last) value. Then whenever your event handler is run, index still has this value, and the last item will be used.
So, in JS, the easiest way to get a new scope is to use a closure. Here's an example adapted from your code:
$(document).ready(function () {
for (var i = 0; i < $("#count").val(); i++) {
var fn = (function(index) {
return function () {
$('#file-link').attr('href', $('#hf' + index).val());
$('#popup').bPopup();
};
})(i);
$("#downloadLink" + i).click(fn);
}
});
This is not as good a way to solve your actual problem as some of the other answers. However, it demonstrates the concept of creating a scope: you're calling a function that takes one parameter, index, for which you pass the loop iterator variable i. This means that the function inside it (which it returns) can now always access the value of this parameter. The inner function gets stored in fn, which then gets passed as the click handler.
If this looks really tricky, here's a more in-depth look at function and scope in Javascript.
*Note that proposed new versions of Javascript/Ecmascript may add block scoped variables. It is not currently implemented in a cross-browser fashion, however.
You should probably calculate it from the event source (#downloadLinkn), by getting n from the end of the string.

Categories

Resources