Function that modifys object its being called on though parent not name - javascript

I'd like to have one function that I can call to modify the text colour of the object (Textarea) that its being called on.
Instead of making 5 functions that have the name of the object its changing in each separate function.
For example
textarea1.addEventListener('keydown', () => {
selectTextAreaWithioutName.style.color = red
});
So where it says selectTextAreaWithioutName id like it to grab textarea1 even if its called textarea2 or textarea3 etc. without the name being explicitly stated.

If I got you right you can use event.target to grab the element.
For example:
textarea1.addEventListener('keydown', (event) => {
event.target.style.color = red; // event.target is equal to textarea1
});

Related

How to click a button to add a value to an array and display it

I am currently stuck on trying to use an onclick button to push a value into an array.
let display = document.getElementById('screen');
let results = [];
display.innerHTML = results[0];
$(document).ready(() => {
$('.one').click(function() {
results.push(1);
});
})
I am trying to push 1 into the array when the button is pushed, then display it. However, my current code does not push the function.
It does work, but the line that shows the results must be inside of the click callback. As it is now, the display gets updated just once, before the click happens.
Also, JQuery deprecated "shortcut" event methods (.click()) a while back and recommends the use of .on().
Lastly, innerHTML has performance and security implications, so don't use innerHTML when the string in question doesn't contain any HTML. Instead, use .textContent. But, because you are already using JQuery, you can use .text().
// If you are going to use JQuery, then use it.
// Here, we can get the element with an id of "screen"
// into a JQuery wrapped set object very easily.
// Naming the variable that will hold that JQuery object
// with a $ is a standard convention to remind you that
// the variable holds a JQuery object and not a standard
// DOM object.
let $display = $('#screen');
let results = [];
// And, with JQuery, if you just pass a function directly
// to JQuery, that function is automatically understood to
// be a document.ready callback
$(() => {
$('.one').on("click" ,function() {
results.push(1);
$display.text(results[0]); // This must be in the callback to show the most up to date information
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="one" value="push">
<div id="screen"></div>

'this' and click handler doesn't seem to go well together for me

I am having some trouble with my jQuery code. I am building a solution with pagination, I have one 'paginate' function (line 87) that I want to use on whatever array is needed to be manipulated.
This is the paginate function that has two parameters. It's the "selected" argument that seems to mess things up because when I call it in the next code sample (the button click function) the $(this) keyword is referring to the button. Not the selected anchor as intended.
function paginate(list, selected) {
// Removes all the items from the document. But because we are storing
// the items in an array, nothing is really lost.
removeStudents();
// Declaring the array that is to be filled with the students needed
// based on which pagination anchor element is clicked.
var arrToShow = [];
// Variable that decides where the counting of the students should start
// based on which pagination anchor element has the class of 'active'.
var headIndex = selected * maxStudents;
// Variable that goes together with the headIndex.
var tailIndex = headIndex - 10;
// Pushes the students, that have been chosen by the parameters of the function,
// to the arrToShow array.
for ( var i = tailIndex; i < headIndex; i++ ) {
arrToShow.push(list[i]);
}
// Displays all of the objects within the arrToShow array.
for ( i = 0; i < arrToShow.length; i++ ) {
$(".student-list").append(arrToShow[i]);
}
I have two parameters in the function: the list itself and which pagination anchor element that is currently active, or clicked. The issue seems to be that the $(this) refers to the button (line 57) when I implement the pagination function inside of another function (I am referring to the button click function on line 57).
This is the button function. It only works right now because I put a '1' for the second argument. I'd like for it to be like a global variable there that specifies which anchor argument that's selected.
function buttonClicked() {
removeStudents();
// Store what's typed in to the search input in a variable.
var userSearch = $("input").val();
// Creating an array for the successfully searched array objects.
var userSearchArr = [];
// Iterating through every single student, looking for a match, if a match
// is found, push it to the userSearchArr, then appending the objects
// within that array to the student list container.
$.each(allStudentsArr, function() {
var studentName = $(this).find("h3").text();
var filterThrough = studentName.indexOf(userSearch);
console.log(filterThrough);
if (filterThrough !== -1) {
userSearchArr.push($(this));
}
});
constructPagPages(userSearchArr.length);
paginate(userSearchArr, 1);
}
Is there some way of making the $(this) keyword within the click handler global, so that it refers to the click handlers $(this) and not to the $(this) that belongs to the function in which I'm calling the paginate function?
This is the paginationClicked function. The culprit. It works fine to call the pagination function inside of that since the $(this) keyword refers to the anchor element. However, it does not when I call the pagination function within the buttonClicked function.
function paginationClicked() {
// Removes all the sibling anchor elements classes.
$(this).parent().parent().children().children().removeClass("active");
// Adds the class active to the selected anchor.
currentPagPage = $(this).text();
console.log(currentPagPage);
paginate(allStudentsArr, $(this).text());
}
This is the event handlers:
// Event click handler that targets the pagination buttons.
$(".pagination a").click(paginationClicked);
$("button").click(buttonClicked);
Please feel free to ask if something seems unclear. I have been on this for hours and I can't seem to find a solution.
Some guidelines would be hugely appreciated. Cheers.
Here is my code:
https://github.com/SebastianPeterAndersson/Pagination-And-Content-Filter/blob/master/js/pagination-content-filter.js
Your problem is that you construct totally new list of anchor when someone searches for something.
When you remove the old pagination, all anchor would be gone, along with their event handlers. You need to move the event registration into your constructPagPages function
move this:
// Event click handler that targets the pagination buttons.
$(".pagination a").click(paginationClicked);
into your constructPagPages function, after you construct the pagination.
Have a look here: http://codepen.io/mrducnguyen/pen/xOoLPV

Writing sections of javascript dynamically

When the input gets blurred, I want to get the value of the input and replace the word "action" in the script, with the value of the input. So for example, if I type "hide" in the input, the word "action" would be replaced with "hide". Or something to that effect.
I'll then be using this logic to define the trigger (#elementA) and target (#elementB) also.
HTML
<input type="text" id="define-action">
<script id="interactions">
$('#elementA').click(function() {
$('#elementB').action();
)};
</script>
JS
$('#define-action').blur(function() {
var action = $(this).val();
// Replace "action" with action
)};
Use object [] notation
$(selector).hide(); can be written as $(selector)['hide']()
So you could pass in variable instead of hard code string
$(selector)[action]()
Beware you will get errors thrown if method represnted by variable doesn't exist, so you should probably create an array of valid methods you will accept and make sure value is in the array before calling the method
Example of testing values in array:
var allowedMethods=['hide','show','slideUp'];
if( $.inArray( action, allowedMethods) >-1){
$(selector)[action]()
}else{
alert( action +' is not a valid method')
}
Instead of dot notation use bracket notation
Also I don't think you need to use the blur handler, in the click handler you can read the value of the input filed
$('#elementA').click(function () {
var action = $('#define-action').val();
$('#elementB')[action]();
});
or if you want to use the blur method then you need to define the variable action is a shared scope of both the click and blur handlers
$('#elementA').click(function () {
$('#elementB')[action]();
});
var action;
$('#define-action').blur(function () {
action = $(this).val();
});

Array of HTML buttons with on click event to return an attribute

I am trying to create an array of buttons with an onclick event alerting an attribute.
the buttons are created with no problem and every time I create a problem I set up an alert of the attribute. this works perfect.
Every time you press a button, the right function is called, and it works great, but for some reason I get the second alert to say "undefined"
Just look at the code, it explains it self better then I can.
var i = 0
var insertframe = function () {
savebutton[i].index = i
//this works!
alert(savebutton[i].index)
savebutton[i].click(function (event) {
//this returns "undefined"
alert(savebutton[i].index)
})
i++
}
Solution:
instead of naming the object, I had to use "this" instead so, instead of:
savebutton[i].index
use:
this.index

traverse of tree in javascript

I have a javascript variable like below:
var treeNode= [{"id":"T1"},{"id":"T2","children":[{"id":"T3"},{"id":"T4"},{"id":"T5","children":[{"id":"T6"}, {"id":"T7"},{"id":"T8"}]},{"id":"T9"},{"id":"T10"}]},{"id":"T11"},{"id":"T12"}];
node t3,t4,t5,t6,t7,t8,t9,t10 are the child of node t2
i have a link of deactivate on each node.on click on deactivate link make active and delete link .mentioned in image.
now i want to make same active and delete link on all child node of parent node.
for example T3,T4,T5,T6,T7,T8,T9,T10 are the child of T2.
if i click on T5 then this will work on T6,T7,T8.
I tried below recursive code.may be my approach is not right.please advice.
var objTreeNode = eval(treeNode);
trav(objTreeNode);
function trav(TreeNodeObj){
var i=0;
for (i=0;i<TreeNodeObj.length;i++){
if(!TreeNodeObj[i].children){
if(objID==TreeNodeObj[i].id){ // will get T2 if click on deactivate link of Item T2
document.getElementById('span_'+TreeNodeObj[i].id).innerHTML = 'Activate <a href="javascript:deleteNode(\'' + objID
+'\');">Delete</a>';
}
}
else{
childObj = TreeNodeObj[i].children;
trav(childObj)
}
}
}
There are a few silly things in your code, let me fix them:
1. "Eval is evil!"
var treeNode= [{"id":"T1"},{"id":"T2","children":[{"id":"T3"}]}];
var objTreeNode = eval(treeNode);
trav(objTreeNode);
Why would you call eval()?
Let's see what MDN has to say about this:
Don't use eval! It's dangerous and slow. There are safe (and fast!) alternatives to eval() for common use-cases.
So what is your "use-case"? Why do you call eval here? What is the "better" solution? If you read the whole documentation on MDN you can read that:
If the argument of eval() is not a string, eval() returns the argument unchanged.
So unless treeNode is a string var objTreeNode = eval(treeNode); basically equals to var objTreeNode = treeNode;
You can drop that whole eval() line and just use treeNode. It's already an object.
2. camelCase
function trav(TreeNodeObj) {
This is not an error just a convention: In JavaScript (and also in most languages with C-like syntax) the parameters of a function are written with lower camel case (first letter is lowercase, and every other word's first letter is uppercase).
function trav(treeNodeObj) {
3. objID is undefined
There is no objID variable defined in your code. Although it is possible that you have a global defined elsewhere at the given time, it is much safer to introduce it as a parameter in your function.
function trav(treeNodeObj, objID) {
4. What your code does with what and when
Let me just figure out what your code currently does:
Iterates over a given object's children property (which is hopefully an array).
If an element has no children
Check if the array item has a desired ID property, and change it's innerHTML
Else
Call the function on the children
So what it does: Changes the element with the given ID if it has no children.
What you need is: Change the element with the given ID and also it's children.
I just modified your function like this:
function trav(treeNodeObj, objID, activate) {
var i = 0;
for (i = 0; i < treeNodeObj.length; i++) {
var childrenActive = false;
if (objID === treeNodeObj[i].id || activate) { // will get T2 if click on deactivate link of Item T2
childrenActive = true;
document.getElementById('span_' + treeNodeObj[i].id).innerHTML = 'Activate Delete';
}
if (treeNodeObj[i].children) {
childObj = treeNodeObj[i].children;
trav(childObj, objID, childrenActive);
}
}
}
Since you need to change all the child elements I needed to introduce a cut. This is the activate parameter. If the activate parameter is true you don't need to check the ID anymore you know that we are iterating over the subelements of the element with the given ID, and therefore change the element anyway.
Also you need to change the elements even if they have child nodes, so I restructured the if-s.
I have also made a jsfiddle for you to test: http://jsfiddle.net/JZ52g/3/
You can change the id parameter at the function call.

Categories

Resources