How can I add a link to dynamically created button? - javascript

Once the buttons are created, is there anyway I can add a link or use window.location method like this: `window.location = 'nextpage.html?foo=number'. I currently have this
var typeValue = location.search;
var typeStringValue= typeValue.replace("?type=","");
var containers = typeValue.replace("?type=multi","");
var containersValue = parseInt(containers);
var sampleLetter = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
function createButton(buttonName){
var buttonDivBlock = document.getElementById("sampleSets");
var buttonElement = document.createElement("input");
buttonElement.setAttribute("type","button");
buttonElement.setAttribute("name",buttonName);
buttonElement.setAttribute("value","Sample Set"+" "+buttonName);
buttonElement.setAttribute("id",buttonName);
buttonDivBlock.appendChild(buttonElement);
// document.getElementById(sampleLetter[i]).setAttribute('onclick',window.location='SampleInfo.html'+typeStringValue+bottonName);<!--add the button link -->
}
function setButtons(numberOfContainers){
for(i=0;i<numberOfContainers;i++){
createButton(sampleLetter[i]);
}
}
window.onload = function(){
setButtons(containersValue);
}
But document.getElementById("'"+sampleLetter[i]+"'").setAttribute('onclick',window.location='SampleInfo.html'+typeStringValue+bottonName);<!--add the button link -->
returns a null value.

Well, maybe I can help you along with an example:
function getFive() { return 5;}
callOtherFunction("stringArgument", getFive());
The second argument to callOtherFunction is going to be 5, not the getFive function. In many cases, like adding event listeners and AJAX code, you actually want to pass the function itself as an argument, so it can be called later. But if you don't want to bother declaring that function seperately, it looks like this:
callOtherFunction("stringArgument", function() { return 5; });
To make code look cleaner, you can press Enter after the { and make a multi-line function.
Now, all that in mind, take another look at the line you've commented out. Do you see what's missing? (PS. Apologies for the "egging-on" format - I find people get much better at figuring things out if I help them find the solution, rather than just showing it to them)

The sampleLetter variable is not defined where you are trying to use it (judging by commented code). Use the value you had just set to the id attribute a few lines earlier.
document.getElementById(buttonName).setAttribute( /* ... */ );
Or if you are trying to set it in the loop instead of in the createButton function, do not add the single quotes
document.getElementById(sampleLetter[i]).setAttribute( /* ... */ );

Related

Qualtrics API functions not working within custom function called in EventListener

I defined a custom function in the header section that checks, alerts the user, and resets the value of a particular slider bar when it fails certain restrictions.
This function works beautifully when called on question clicks:
this.questionclick = chkVals;
I would like to also run the function when the user are exiting the text input field (as some users are using the keyboard to do the survey). I implemented an Event Listener for each sliders' text input field that runs the function when the focus is out of the text input field.
// choices is an array of choice ids
for (i = 0; i < choices.length; i++) {
var x = document.getElementById(choices[i]);
x.addEventListener("blur", chkVals, true);
};
I know that the event listener works, because the correct alerts are popping up. It is just not able to reset the values as this.setChoiceValue is not a function within the environment. I have tried setting var that = this; and calling that.setChoiceValue in the function, but it still does not work.
Any help will be greatly appreciated!
You haven't shown all your code, so I'm making some assumptions.
this is the Qualtrics question object in the addOnload function. Since chkVals is outside the addOnload function, this (or that) is undefined. So, you need to pass it in your function call (function chkVals(qobj)) then use qobj.setChoiceValue in the chkVals function. Then your function calls become:
this.questionClick = chkVals(this);
and
x.addEventListener("blur", chkVals(this), true);
#T. Gibbons 's answer helped me get to this point. As suggested I needed to add a parameter to chkVals() to be able to reference the this object. However,
this.questionClick = chkVals(this);
does not work due to this being a reserved object, so the whole header script will not run. I ended up changing all reference of this to that in my custom function and adding the parameter that as suggested:
function chkVals(that) {
...
... that.setChoiceValue(x, y)
}
To call the function with a parameter, I had to explicitly defined an anonymous function that called chkVals, otherwise it will not work (I am not sure why):
var that = this;
this.questionclick = function() {chkVals(that);}
for (i = 0; i < choices.length; i++) {
var x = document.getElementById(choices[i]);
x.addEventListener("blur", function() {chkVals(that);}, true);
};
The above works!

Variable not working on div created in jQuery

This is simple code which works fine, but I want to figure it out how to set a variable for novy.fadeIn(2000).
For example one day will my js file had 300 lines and I want to change variable from one place -> fadeIn to fadeOut or something like that.
var novy = $('<div/>', {id:'namaste'});
var text = {textAlign : 'center', color : '#fff', fontSize: 'xx-large'}
// var example = novy.fadeIn(2000) this is not working
novy.appendTo('body').text('this code is .ITCHI.').css(text).hide();
$(document).on('click', function(){
novy.fadeIn(2000); // example;
})
For better view please look here: https://jsfiddle.net/t305qap2/
The example you give is a little far-fetched for me, but to achieve what you are asking, you can do one of two things:
Wrap common code in a dedicated function
var fade = function (element, duration) {
element.fadeIn(duration);
}
This will let you call fade(novy, 2000) and exchange the underlying animation call as you need it.
Store the function, not the result, in a variable
You see, the reason why var example = novy.fadeIn(2000) isn't working is because it stores the result of calling fadeIn on that element, which is the element itself. fadeIn merely has the side-effect of animation. If you want to store a reference to the function instead of the result, JS allows this. See here:
var novyFader = novy.fadeIn // typeof novyFader === 'function' => true
novyFader.call(novy, 2000)
You want to assign the line to a function and store it as a variable. you can then change the function to a different value in the future
so create a clickFunction like this that returns a function
var clickFunction = function() { return function(){novy.fadeIn(2000);} }
Now change your on click to this
$(document).on('click', clickFunction);
At this time your code should work the same.
In the future you can assign clickFunction to some other function like
clickFunction = function() { return function() {novy.fadeOut(2000);} }
But you might also have to set the document.on callback again
HTH

Change onclick function in javascript

the code below is used to change the onclick event when pressed, however it only alters the function of the parameter, which it simply will not do.
function addWhere(nameID)
{
document.getElementById('addWhereButton').setAttribute("onclick",addWhere(nameID++), false);
document.getElementById('addWhereButton').onclick = function () {addWhere(nameID++)};
}
neither code works and no one else seems to have asked this specific questions before.
Thanks
EDIT
Further testing shows something complete bizarre, a bit of code to display the nameID like so
document.getElementById('Testing').innerHTML = nameID++;
shows that nameID is actually getting incremented, but the number passed by the onclick never changes.
Like:
function addWhere(nameID) {
console.log(nameID);
};
let nameID = 1;
document.getElementById('addWhereButton').onclick = function () {addWhere(nameID++)};
<button id="addWhereButton">click to increment nameID</button>

Creating javascript objects using jQuery's each() method

Im curious about what might be a larger question than I think.
I am using the following code to listen for 'keyup' on a group of text input fields. If the user stops typing for a given amount of time, I send the data to a controller using AJAX.
I decided to try my hand at OOP in javascript to accomplish this. This is because I want a new instance of the timer method for each input field. (To be absolutely clear, Im very new to OOP in javascript so this might be dreadful. Let me know.)
Here is the main class with its methods:
function FieldListener(entity){
t = this;
t.typingTimer; // Timer identifier
t.doneTypingInterval = 1000; // Time in ms. e.g.; 5000 = 5secs
t.entity = entity;
entity.bind("keyup", function(){t.setTimer();});
}
FieldListener.prototype.setTimer = function(){
t = this;
// User is still typing, so clear the timer.
clearTimeout(t.typingTimer);
// Get the field name, e.g.; 'username'
t.entityType = t.entity.attr("name");
// If the value is empty, set it to a single space.
if(!(t.val = t.entity.val())){
t.val = ' ';
}
t.noticeSpan = t.entity.siblings("span");
// Display 'waiting' notice to user.
t.noticeSpan.html('...')
t.typingTimer = setTimeout(function(){t.doneTyping();},t.doneTypingInterval);
}
FieldListener.prototype.doneTyping = function(){
// Encode for passing to ajax route.
t = this;
valueType = encodeURIComponent(t.entityType);
value = encodeURIComponent(t.val);
$.ajax({
url: '/check/'+valueType+'/'+value,
type: 'GET',
processData: false
})
.done(function(validationMessage){
t.noticeSpan.html(validationMessage);
})
.fail(function(){
t.noticeSpan.html("Something went wrong. Please try again.");
});
}
So from here I'd like to be able to create an object of the FieldListener class for every input field.
I know I can do it easily if I have an id for each like so:
var fieldListener = new FieldListener($("#someFieldID"));
But I'd like to iterate over every field with a given class name. Something close to this perhaps?:
i = 0;
$(".info-field").each(function(){
i = new FieldListener($(this));
});
But that doesn't work (and doesn't look very nice).
Any thoughts? (Im also curious about critiques/improvements to the class/methods code as well.)
edit: As per #ChrisHerring's question: The issue is that it seems to create the object but only for the last element in the each() method. So the span associated with the last input field with the class '.info-field' displays the validationMessage returned from AJAX regardless of which field I am typing in.
UPDATE:
It seems like something is wrong with the creation of new objects. For example, if, rather than iterating through the each() method, I simply follow one class initiation with another, like so:
var fieldListener1 = new FieldListener($("#someFieldID"));
var fieldListener2 = new FieldListener($("#someOtherFieldID"));
that fieldListener2 overwrites variables being saved when initiating fieldListener1. This means that when I type into the input field with id "#someFieldID", it behaves as if I am typing into the input field with id "#someOtherFieldID". Thoughts?
UPDATE #2 (solved for now):
It seems that I have solved the issue for now. I needed to add 'var' before 't = this;' in the FieldListener class. Any comments/critiques are still welcome of course. ;)
The t variable is global. The function for the "keyup" event is evaluated dynamically which means it picks up the last value of t.
Change
t = this;
to
var t = this;
I think you want an array of FieldListener objects.
var myListeners = [];
i = 0;
$(".info-field").each(function(){
myListeners[i] = new FieldListener($(this));
i++
});
This'll give you a list of FieldListeners, where myListeners[0] is the listener for the first .info-field on the page, myListeners[1] is the listener for the second, etc.
Edit: It would appear you have solved the problem. This answer may still come in handy later on, though, so I won't delete it. =)
I think you should be using jquery's .on() to handle the binding.
$(body).on({
keyup: function () { HandleKeyUpEvent($(this)); },
keydown: function () { HandleKeyDownEvent($(this)); }
}, ".info-field");
I realize this is a departure from your original coding idea (using prototypes) but it will still be OOP, if that's what you intented to do.

how to pass Id to javascript dynamically

function jsarea3() { document.getElementById("Txtarea3").title = document.getElementById("Txtarea3").value; }
function jsarea4() { document.getElementById("Txtarea4").title = document.getElementById("Txtarea4").value; }
function jsarea5() { document.getElementById("Txtarea5").title = document.getElementById("Txtarea5").value; }
The code above is to show data in a textbox area on mouse hover.
as you can see the code that run is same for all the 3 function the difference is only the ID
How can I pass ID dynamically
Like I can use the inner code as function as well for all the 3 and how to use it
and what about code like this the code given below
$('#button1').focus(function () {
$('#button1', window.parent.document).css("background-color", "#fcc63b");
}
});
if you are using jquery you can select your textareas like this
$("textarea").focus(function(){
this.title = $(this).val();
});
you can specify the selector to be more specific to the items that you want to manipulate
the function will be running when your textarea gain focus
take a look at jquery it's simplify your code
Since you use the same elements title and value you can store a reference instead of searching for it twice..
function jsarea(anId) {
var elem = document.getElementById(anId);
elem.title = elem.value;
}
and you can call it with jsarea('Txtarea3');
For the second code, it is jQuery code and it seems to change the background color of a button with the same id as the one that gets the focus in the parent window (when you use iframes)
You can use a single function which takes a parameter representing the id of the the element you wish to reference:
function jsarea(elementId) {
document.getElementById(elementId).title = document.getElementById(elementId).value;
}
You can call this like jsarea("Txtarea3"); if you want to affect the element with id "Txtarea3".
Use a parameter.
In addition, you should take a look at jQuery - it can really simplify DOM-manipulating code.
function jsarea(number) { document.getElementById("Txtarea" + number).title = document.getElementById("Txtarea" + number).value; }

Categories

Resources