Get list of all available <button> elements in component html - javascript

Say my component is simple, like:
<div>
<button id="one" #one>one</button>
<button id="two" #two>two</button>
<button id="three" #three>three</button>
</div>
Would it be possible to return a list of all of the buttons?
ie.
constructor() {
let buttonList = findByElement('button');
}

Use document.querySelectorAll()
var div=document.getElementById("div");
var a=div.querySelectorAll('button');
console.log(Object.values(a))
<div id="div">
<button id="one" #one>one</button>
<button id="two" #two>two</button>
<button id="three" #three>three</button>
</div>

If you add Renderer and ElementRef to your component, you should then be able to access the element in question:
constructor(private renderer: Renderer, private elem: ElementRef){}
I believe from within your component you can call:
const elements = this.elem.nativeElement.querySelectorAll('button');
Which would give you the elements you need. It's important when using this method to ensure that you're running your code at some point after the component is initialised, not in the constructor as was the case with your original code, as we need to ensure we have access to the DOM for this component. This question has more detail.

Related

Trying to return a different color div after selecting option in form submit using React and Typescript

I am working on a to do list using React and Typescript. I am trying to return a different colored div when selecting a priority in the option select dropdown (prioritySelect). I have tucked in a function within the ToDoItem JSX Element. What I want to happen is for the prioritySelect component to change the background color of the div it is in "to-do-item" to signify importance.
I tried to add handleOptionsChange function and call it within the div return at the bottom but I keep running into errors when trying to add handleOptionsChange, I am not sure why.
//TODOITEM TO RETURN TO DO COMPONENT
`function ToDoItem(props: { toDo: ToDo; onDeleteToDo: any; prioritySelect: any;}) {`
///TRYING TO CREATE FUNCTION EXPRESSION THAT CALLS EVENT SET STATE FOR PRIORITY BELOW
`handleOptionsChange:any; setState:any;}) {
handleOptionsChange = (event: any) => {
props.setState({
option: event.target.value
});
}`
`return (
<div className="to-do-item" id="to-do-item">
<div className="checkbox-title-container">
<div className="check-title-div">
{Checkbox()}
<h2 className="to-do-title">{props.toDo.title}</h2>
</div>
<div id="delete-div">`
//PRIORITY OPTION SELECT BELOW
`<select name="Priority" className="select-field" value={props.prioritySelect.option} onChange={props.handleOptionsChange}>
<option className="important" value='1'>Important</option>
<option selected value='2'>Normal</option>
</select>
<button id="delete" onClick={props.onDeleteToDo}>
Delete
</button>
</div>
</div>
<div className="description-box">
<span className="description">{props.toDo.description}</span>
</div>
<br />
<span className="to-do-date">
{/* {props.toDo.duedate.toLocaleDateString()} */}
</span>
</div>
);
}`
I am trying to call handleOptionsChange when returning a JSX component below, I have taken out the rest of the components within the to-do-item div for the sake of readability
`<div className="to-do-item" id="to-do-item">
{prioritySelect={handleOptionsChange}} </div>
<div>`

How to remove current node of clicked inline element?

First of all I'm adding a button via js:
let newTextArea = "<div class='row mt-4'><div class='col'><button type='button' class='btn btn-light rimuovi' onclick='removeIt()'>Rimuovi</button></div</div>";
Once on the page, I might want to remove it so I'm calling that function on a click:
function removeIt(e) {
e.closest(".row").remove();
}
but I'm getting
Cannot read properties of undefined (reading 'closest') at removeIt
You just forgot to pass your element (e) in the paramters in your JS fonction on the HTML.
So, try with :
onclick = 'removeIt(this)';
Working example:
function removeIt(e) {
e.closest(".row").remove();
}
<div class="row">
<button onclick='removeIt(this)'>Rimuovi</button>
</div>
Hope this helps you.
As others mentioned, you forgot to pass "this" as a parameter to your removeIt() method. The "this" keywords refers to, in this case, the element in which the click listener is used (your button). With the "this" keyword set as a parameter, JS can now look for a "closest" element with the class "row". It starts from the button and goes up the dom-tree until it finds an element with a className "row" or until it reaches the root.
Working example:
<!DOCTYPE html>
<html>
<body>
<div class="row mt-4">
<div class="col">
<button
type="button"
class="btn btn-light rimuovi"
onclick="removeIt(this)"
>
Rimuovi
</button>
</div>
</div>
<script>
function removeIt(element) {
closest = element.closest('.row');
closest.remove();
}
</script>
</body>
</html>
The main issue is because you aren't providing the e argument when you call the removeIt() function in the onclick attribute.
However you should note that using an inline onclick attribute is not good practice. A better way to achieve what you need is to attach an unobtrusive delegated event handler which accepts the Event object as an argument. You can then use that Event to retrieve the Element object which triggered the handler. Something like this:
const rowTemplate = document.querySelector('#row-template');
const container = document.querySelector('.container');
const addBtn = document.querySelector('.add');
addBtn.addEventListener('click', () => {
container.innerHTML += rowTemplate.innerHTML;
});
container.addEventListener('click', e => {
if (e.target.matches('.rimuovi'))
e.target.closest('.row').remove();
});
<button class="add">Add</button>
<div class="container"></div>
<template id="row-template">
<div class="row mt-4">
<div class="col">
<button type="button" class="btn btn-light rimuovi">Rimuovi</button>
</div>
</div>
</template>

How to fix <!--bindings={ "ng-reflect-ng-for-of": "" }-->

Im new to Angular. I am creating a button inside game-control component and using event binding and property binding. When i click the button numbers will be entered into an array continuously using setInterval method. I am passing the data between one component to another. The game-control component's selector is called inside the app component. The button worked fine with the click event but when i used the ngFor in order to iterate through the array and display the buttons also did not appear in the dom. Thanks in advance
game-control.component.html
<div class="row">
<div class="col-md-12">
<button
class="btn btn-primary"
type="button"
(click)="gameStart()">Start</button>
<button
class="btn btn-danger"
type="button"
(click)="gameStop()">Stop</button>
<br>
<p>{{element}}</p>
</div>
</div>
game-control.component.ts
export class GameControlComponent implements OnInit {
#Input() element:number;
#Output() createNumber= new EventEmitter<number>();
constructor() { }
ngOnInit() {
}
gameStart()
{
this.createNumber.emit(this.element);
}
}
app.component.html
<div class="container">
<div class="row">
<div class="col-md-12">
<app-game-control
(createNumber)='onStart()'
*ngFor="let myElement of myHoldings"
[element]="myElement"
>
</app-game-control>
</div>
</div>
</div>
app.component.ts
export class AppComponent {
myHoldings=[];
onStart()
{
setInterval(()=>{
this.myHoldings.push(this.myHoldings.length+1);
console.log("hello");
},1000);
}
}
The solution is to have an internal variable in the component that is assigned from the Input() variable
#Input() element:number;
internalNumber : number ;
ngOnInit() {
this.internalNumber = this.number;
}
And then use that variable to do bindings or emit events
For a similar question that might help
Click function not being called for a mat-menu with items generated with ngFor

Hide div onclick in Vue.js

What is the Vue.js equivalent of the following jQuery?
$('.btn').click(function(){ $('.hideMe').hide() });
jQuery works out of the box, Vue.js does not. To initialize Vue.js component or App you must bind that component with its data to one specific HTML tag inside your template.
In this example the specified element is <div id="app"></div> and is targeted through el: #app. This you will know from jQuery.
After you declare some variable that holds the toggle state, in this case been isHidden, the initial state is false and has to be declared inside the data object.
The rest is Vue-specific code like v-on:click="" and v-if="". For better understand please read the documentation of Vue.js:
The Vue Instance
Template Syntax
Event Handling
Conditionals
Note: consider reading the whole or at least longer parts of the documentation for better understanding.
var app = new Vue({
el: '#app',
data: {
isHidden: false
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.js"></script>
<div id="app">
<button v-on:click="isHidden = true">Hide the text below</button>
<button v-on:click="isHidden = !isHidden">Toggle hide and show</button>
<h1 v-if="!isHidden">Hide me on click event!</h1>
</div>
This is a very basic Vue question. I suggest your read the guide, even the first page will answer your question.
However, if you still need the answer this is how you hide/show elements in Vue.
new Vue({
el: '#app',
data () {
return {
toggle: true
}
},
})
<script src="https://unpkg.com/vue#2.5.3/dist/vue.js"></script>
<div id="app">
<button #click='toggle = !toggle'> click here </button>
<div v-show='toggle'>showing</div>
</div>
<div>
<div>
<button v-on:click="isHidden = !isHidden">Toggle hide and show</button>
<h1 v-if="!isHidden">Hide me on click event!</h1>
</div>
</div>
name: "Modal",
data () {
return {
isHidden: false
}
}
The up-voted answer is definitely a way to do it, but when I was trying to do this it was with a dynamic array instead of a single Div, so a single static Vue variable wouldn't quite cut it.
As #samayo mentions, there isn't a difference between the hide action from jQuery vs Vue, so another way to do this is to trigger the jQuery through the #click function.
The Vue Dev kit will tell you not to mix JS inline with #click events and I had the same problem as #user9046370 trying to put the jQuery command inline with #click, so anyway,
Here's another way to do this:
<tr v-for="Obj1,index in Array1">
<td >{{index}}</td>
<td >
<a #click="ToggleDiv('THEDiv-'+index)">Show/Hide List</a><BR>
<div style='display:none;' :id="'THEDiv-'+index" >
<ul><li v-for="Obj2 in Array2">{{Obj2}}</li></ul>
</div>
</td>
</tr>
Method:
ToggleDiv: function(txtDivID)
{
$("#"+txtDivID).toggle(400);
},
The other perk of this is that if you want to use fancy jQuery transitions you can with this method.
<template>
<button class="btn btn-outline-secondary" type="button"><i class="fas fa-filter" #click="showFilter = !showFilter"></i></button>
</template>
<script>
export default {
methods:{
showFilter() {
eventHub.$emit('show-guest-advanced-filter');
}
}
}
</script>
But it's not worked this method.
<template>
<button class="btn btn-outline-secondary" type="button"><i class="fas fa-filter" #click="filtersMethod"></i></button>
</template>
<script>
export default {
data: () => ({
filter: true,
}),
methods: {
showFilter() {
eventHub.$emit('show-guest-advanced-filter');
this.filter = false;
},
hideFilter() {
eventHub.$emit('hide-guest-advanced-filter');
this.filter = true;
},
filtersMethod() {
return this.filter ? this.showFilter() : this.hideFilter();
}
}
}
</script>
This is worked.

angular, can't find element in html

For some reason I can't get the value of the list element in the html despite using document.getElementByID and it has the same id. It claims that the element is undefined. Here is the code:
fileupload.component.ts:
ngOnInit() {
var x = document.getElementById('lemons');
if(x){
console.log('it does exits')
x.addEventListener('click', function(e:any){
console.log(x.innerHTML);
});
}
}
fileupload.component.html:
<div class="row" id="filesDisplay">
<div class="col-md-4" id="files">
<li *ngFor="let child of tree" id="lemons">
{{child}}
</li>
</div>
The *ngFor directive is processed after the OnInit hook, so if you want to get an element generated with the *ngFor you should use:
ngAfterViewInit() { }
Also you are duplicating the id, this means it only will select the first element.
lifecycle-hooks angular's guide
Edit: added angular guide
You can not repeat same html id for all the li's. You need to add index to id to diffrentiate.
<div class="row" id="filesDisplay">
<div class="col-md-4" id="files">
<li *ngFor="let child of tree" (click)="test(child)">
{{child}}
</li>
</div>
and in javascript you need to pull the id accordingly.
ngOnInit() {
test(res) {
// perform your logic here..
}
}
You no need to use jquery here where angular is providing all your need in DOM manipulation.

Categories

Resources