getElementsByTagName of all siblings - getelementsbytagname

UPDATE:
Let me rephrase.
I have multiple divs that all contain, among other things, an img element with the class="yes". But they're not all the same siblings.
Two examples:
<div id="div1" onclick="function(this)">
<img src="image1" />
<div>
<img src="image2" class="yes" />
</div>
</div>
<div id="div2" onclick="function(this)">
<img src="image3" class="yes" />
</div>
Now I'm trying to formulate one function for both divs that would change the source of the image with class yes.
getElementsByTagName doesn't seem to do the trick, nor does getElementsbyClassName.
Any thoughts? Thanks again!

getElementsByTagname is the wrong function.
There is no easy way to do what you're trying to do, unless you resort to third party libraries such as jQuery.
With jquery, you use this code:
$('img.yes').each(function() {
console.log(this);
});
Here is a working example of what you're trying to do: http://jsfiddle.net/ZYBp6/

You can use jQuery like this:
function some_function(x)
{
var arr = $("#" + x.id + " .yes"); // Gets all children of the class "yes"
}
Or if you only want to get img elements, you can do this instead:
function some_function(x)
{
var arr = $("#" + x.id + "img.yes");
}
In both of these examples, arr would contain DOM elements, and not the kind of "element" produced by jQuery normally.

This seems to work:
function function(x) {
$(x).find('.yes').attr('src','differentimage.png');
}

Related

How to include Handlebars partial in a string? (add it to the innerHTML of a DOM Element)

Is there a way to get the "string version" of a handlebars partial to include it in the innerHTML of an HTML element?
For instance, imagine I have a ToDo list, and I want to add a task everytime I click the button "Add Task", like this:
todo_list.hbs
<div id="todo-list">
</div>
<button onclick="addTask">Add Task</button>
And that I have a handlebars partial in the file "task.hbs":
task.hbs
<h1 class="task-title">The task is: {{title}}</h1>
<button id="delete-task">Delete task</button>
<script>
const button_delete_task = document.getElementById('delete-task');
button_delete_task.addEventListener('click', deleteTask);
function deleteTask () {
// delete task code here
}
</script>
My question is: How could I create a Task partial everytime the button "Add Task" is clicked? Something like this:
<div id="todo-list">
</div>
<button onclick="addTask">Add Task</button>
<script>
function addTask() {
const todo_list = document.getElementById('todo_list');
todo_list.innerHTML += {{> Task title="A new task"}};
// More code here...
}
</script>
I have also tried enclosing the partial with backticks (`{{> Task title="A new task"}}`), and quotes ("{{> Task title='A new task'}}") as well as read many posts on this subject, but all of them use handlebars.js, not express-handlebars.
I am using express.js for the backend, and therefore, express-handlebars as the view engine. In advance, thanks a lot for your help!
I managed to solve the issue!
It turns out that enclosing the partial with backticks works! The problem was that my partial had <script></script> tags.
Imagine my task.hbs looked like this:
<div>
<script></script>
</div>
then, the processed version of todo_list.hbs would look like this:
<div id="todo-list">
</div>
<button onclick="addTask">Add Task</button>
<script>
function addTask() {
const todo_list = document.getElementById('todo_list');
todo_list.innerHTML += `<div>
<script></script>
</div>`;
// More code here...
}
</script>
This would be valid in a normal HTML file, but it looks like handlebars process the closing script tag that is inside the string (</script>) as a normal tag, and with it, closes the <script> tag of todo_list.hbs.
The solution I found was to not use <script> tags into my partial (not a beautiful solution, but works for me!) and instead, declare the javascript code in another file, and import it into todo_list.hbs using <script> tags with the src parameter like this:
todo_list.hbs
<div id="todo-list">
</div>
<button onclick="addTask">Add Task</button>
<script>
function addTask() {
const todo_list = document.getElementById('todo_list');
todo_list.innerHTML += `{{> Task title="New task!"}}`;
// More code here...
}
</script>
<!-- JAVASCRIPT CODE REQUIRED BY TASK PARTIAL -->
<script src="/foo/bar/partials/Task.js"></script>
Where Task.js is the file containing the javascript of the Task.hbs partial:
Task.js
const button_delete_task = document.getElementById('delete-task');
button_delete_task.addEventListener('click', deleteTask);
function deleteTask () {
// delete task code here
}
And with this changes, Task.hbs would look like this:
Task.hbs
<h1 class="task-title">The task is: {{title}}</h1>
<button id="delete-task">Delete task</button>
You are very close to getting this to work.
As you have noted, your Handlebars is executing on the server-side. In the case of your partial, you are trying to have it render within a script block. In order for the result to be valid JavaScript, you would need have quotes around the output of the partial so that it will be a valid JavaScript string. Therefore:
todo_list.innerHTML += "{{>Task title='A new task'}}";
Which, when rendered, would result in:
todo_list.innerHTML += "<h1>The task is: A new task</h1>";
It should be noted that quotes in your partial could be problematic. For example, if the <h1> in your partial had a class <h1 class="task">, the resultant JavaScript would now be invalid because the quote after the = would be interpreted as the closing quote of the JavaScript string. Therefore, you would need to be sure to either escape the quotes in your partial or ensure they are different from those used to wrap your partial call (a single-quote ('), in this case.
todo_list.innerHTML += "<h1 class=\"task\">The task is: A new task</h1>";
Additionally, you have an inconsistency with the id of your <div>. The tag has id="todo-list" (with a dash); but your JavaScript has document.getElementById('todo_list') (with an underscore). Those will need to be consistent.
Update
As #Sharif Velásquez Alzate noted in comments, the quotes will not work when the partial contains line-breaks because JavaScript strings cannot span multiple lines (unless each line ends with a \ to signify that the text continues to the next line. However, a template literal, using back-ticks, will support text with line-breaks.
Therefore, a better solution is:
todo_list.innerHTML += `{{>Task title='A new task'}}`;

Creating div in vue for loop

I'd like to do v-for loop for creating a div. I'm doing a minesweeper game and here is my code :
<div class="grid">
<div class="square"
v-for="(square, index) in squares"
:id="index"
:key="index"
:class="squares[index]"
#click="clicked(square, index)"
>
</div>
</div>
'Squares' in this code is an array with shuffled classes 'bomb' or 'empty'. I know that it's wrong because after I click on random square I get only this class from te 'squares' array. What should be there instead of this 'squares' array in v-for. I want to get whole with classes, attributes etc. because later I have to use 'classList' 'contains' etc.
Sorry, maybe I'm completly wrong and talking bullshit, but I started with vue 3 weeks ago.
Here is the method clicked which I want to use
clicked(square) {
if(this.isGameOver) return;
if(square.classList.contains('chechked') || square.classList.contains('flag')) return
if(square.classList.contains('bomb')) {
this.gameOver(square);
} else {
let total = square.getAttribute('data');
if(total != 0) {
square.classList.add('checked');
square.innerHTML = total;
return
}
}
square.classList.add('checked');
}
You want to access the div element but you are passing the object in the method and you are asking for classList into the object (that does not have it). You should query the element instead.
Change the #click handler in your component to:
#click="clicked"
and your method to:
clicked(event) {
let square = event.target;
console.log(square);
console.log(square.classList);
...

Possible to pass a data value from a kendoSwitch

Is it possible to pass a data value from a kendoSwitch?
Simple dojo here: https://dojo.telerik.com/eCUVitEC/2
Code as follows:
<input type="checkbox" id="theSwitch" data-id="MyId" />
<script>
$(function () {
$("#theSwitch").kendoSwitch({
change: function (e) {
alert("checked: " + e.checked);
}
});
});
</script>
This works but what I really want is to pass the data-id, not the checked value. I have tried a number of ways but can't seem to find the right syntax.
Thanks.
-Dan
Sure.
On change event find attribute in that element:
this.element.attr("data-id");
Example: Get element attribute

Vuejs same function on multiple divs need to run seperately

Alright, I have these two divs with a mouseover and they have the same function. Now the problem is that if I mouse over one of them then BOTH shines. How to solve this? So shines one by one when I hover them.
DIVS:
<div class="latestItemBody" #mouseover="shineItemIcon"
#mouseout="shineOff" :style="{background: activeCardBg}">
<div class="latestItemBody" #mouseover="shineItemIcon"
#mouseout="shineOff" :style="{background: activeCardBg}">
Functions:
methods: {
shineItemIcon() {
this.activeCardBg = '#7a00ff';
this.bounce = 'animated bounceIn';
},
shineOff() {
this.activeCardBg = '';
this.bounce = '';
}
The reason why they both "shine" is because you have activeCardBg bound to both of them, which changes the background.
You could add the shine effect with pure CSS like this instead.
// CSS
.latestItemBody:hover {
background-color: #7a00ff
}
If you want to do this with JS, it could be done like this.
// Template
<div
class="latestItemBody"
#mouseover="shineItemIcon"
#mouseout="shineOff">
</div>
<div
class="latestItemBody"
#mouseover="shineItemIcon"
#mouseout="shineOff">
</div>
// Methods
shineItemIcon(e) {
e.target.style.backgroundColor = '#7a00ff';
this.bounce = 'animated bounceIn';
},
shineOff(e) {
e.target.style.backgroundColor = '';
this.bounce = '';
}
pass the div id as parameter to the shineitemicon and shineoff function. depending upon the condition set 'activeCardBg' value. give activecardBg1 to first div and activeCardBg2 to second div.

JAVASCRIPT removeRow() function

i would like to know the syntax for removing a row which was added by appendchild.
There is also a removechild, but I am not sure how to operate.
<input type="button" id='submitlink' value="ADD_AGENDA" onClick="generateRowAgenda()" name="AGENDA"/>
<input type="button" id='submitlink' value="" onClick="removeRow()" name="AGENDA"/>
<script language="">
function generateRowAgenda() {
var temp ="<p><input type='text' class='textinputagenda' name='MM_AGENDA[]'></p>";
var newdiv = document.createElement('AGENDA');
newdiv.innerHTML = temp;
var yourDiv = document.getElementById('AGENDA');
yourDiv.appendChild(newdiv);
}
function removeRow(){
yourDiv.appendChild.deleteRow(newdiv);
}
</script>
<br>
<div id="AGENDA" align="center"></div>
That would be:
function removeRow(element){
element.parentNode.removeChild(element);
}
removeRow(newDiv);
That is, the removeChild method actually belongs to the element's parent, so you need to reference the parent first (by using parentNode) and then call the method removeChild over the newDiv element.
Also, you have two elements with the same id: submitlink. And that is not good.
If you rename your element, you could add a listener that call the removeRow function.
<input type="button" id='doremove' value="" onClick="removeRow()" name="AGENDA"/>
(Now the id is doremove)
Now do something like this to make the removeRow function to be executed on click:
document.getElementById('doremove').addEventListener('click', function(e) {
removeRow(newDiv);
});
Here is an example on jsfiddle: http://jsfiddle.net/5TmQC/
You'll notice that remove only works with one agenda item. You want to work with several agendas?
Try this then: http://jsfiddle.net/5TmQC/1/
Almost same code, but this one can delete several, in order by using pop()