Switch Div value with class attribute - javascript

I want to switch value from div to input and submit.
This's my codes so far
HTML
<form id="forms" action="content.php" method="post">
<input id="foo" type="hidden" value"">
</form>
<div class="btn" value="1" width="40" height="40"></div>
<div class="btn" value="2" width="40" height="40"></div>
Javascript
function $(v) {
return document.getElementById(v);
}
var btn = document.getElementsByClassName('btn');
for(i=0; i<btn.length; i++) {
btn[i].addEventListener('click', function() {
btn.getAttribute('value') = $('foo').value;
$('forms').submit();
}, false);
}
Why it dont work? can't be clicked? thx

I think you are doing the assignment wrong. You need to assign the value of the div button to your hidden foo field. Also, btn is the array of all buttons, you can use this inside event handler callback to reference the button that was clicked since this context is bound to the element that has the attached event. I think the following is what you want:
(function() {
function $(v) {
return document.getElementById(v);
}
var btn = document.getElementsByClassName('btn');
for (var i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', function() {
// assign what was clicked (this) to the foo hidden value
$('foo').value = this.getAttribute('value');
// now submit
$('forms').submit();
}, false);
}
}());
Edit: Example using Array's forEach instead (which I assume would be available in your execution environment since you are using getElementsByClassName method.
(function() {
function $(v) {
return document.getElementById(v);
}
var buttons = document.getElementsByClassName('btn');
// each element of the array is passed to the provided callback
buttons.forEach(function (button) {
button.addEventListener('click', function() {
// assign what was clicked (this) to the foo hidden value
$('foo').value = this.getAttribute('value');
// now submit
$('forms').submit();
}, false);
});
}());

im not sure what the purpose of this is,
but if you insist on using divs as radio buttons or w.e
use data attributes,
like so
<div id="div1" data-value="1"></div>
and you can use jquery to get the attribute like this:
var div1 = $('#div1').data('value')
or
var div1 = $('#div1').attr('data-value');
on click listeners also with jquery
$('#div1').on('click', function(){
// do your thing here
...
})

Firstly, I don't think divs should have a value attribute. Maybe you should switch it to data-value, which can be used easily in jQuery:
<form id="forms" action="content.php" method="post">
<input id="foo" type="hidden" value"">
</form>
<div class="btn" data-value="1" width="40" height="40"></div>
<div class="btn" data-value="2" width="40" height="40"></div>
As for the javascript:
$('.btn').on('click', function() {
$(this).data('value', $('#foo').val());
$('#forms').submit();
});

Related

How to detect classname with onclick event

I want to be able to click on an element and then depending on whether it has a specific class name, do something.
Here is what I have so far:
<div class="my-class" onclick="myFunction()"/>
function myFunction() {
if (element.classList.contains("my-class")) {
//do something
}
}
where am I going wrong?
You need to pass the click event then get the target element which in this case is the clicked element.
function myFunction(event) {
if (event.target.classList.contains("my-class")) {
alert("I Do things becuase i have (my-class)")
}
}
<button class="my-class" onclick="myFunction(event)">Click me</button>
<br/>
<br/>
<br/>
<br/>
<button onclick="myFunction(event)">I Do nothing</button>
As #collapsar mentioned in comment, element is't set. I recommand you to use addEventListener and event.target.
document.getElementById("your-element").addEventListener("click", () =>{
if (event.target.classList.contains("my-class")) {
console.log("your-element has \"my-class\" class")
}
})
<div id="your-element" class="my-class">Click</div>
When the HTML element rendered statically you should consider two things:
Wait for the DOM ready event in order to make modifications on the element.
Attach the event dynamically, making sure that you bind the event handler to new elements after adding them to the DOM.
HTML
<div class="my-class" />
Javascript
function myFunction(event) {
var element = event.target;
if (element.classList.contains("my-class")) {
//do something
}
}
document.addEventListener("DOMContentLoaded", function(event) {
// DOM is ready
const elements = document.getElementsByClassName("my-class");
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction);
}
});

Event delegation with bind? (Javascript)

You know how there are times when you want to use one eventlistener for multiple elements? Like this:
divWithManyLinks.addEventListener("click", function(event) {
console.log(event.target.textContent);
}
//--> text content of the clicked link
And you know how there are times when you want to use bind with an eventlistener to change the scope of the eventhandler? For instance, you might need to reference 'this' and point to something specific.
What if you want to have one eventlistener for multiple elements and use bind at the same time, is that possible?
In my case, I want to be able to go from one method (Example.prototype.methodA) to one of two other methods in the same object (Example.prototype.methodB or Example.prototype.methodC) based on what button is clicked. Because the eventlistener is placed inside of methodA the other methods will be referenced with this.methodB and this.methodC. I could possibly implement two eventlisteners with bind separately, but is it possible to have just one eventlistener?
Example.prototype.methodA = function() {
// addEventListener that listens on both buttons and executes either this.methodB or this.methodC based on what button is clicked.
}
Example.prototype.methodB = function() {
// do stuff
}
Example.prototype.methodC = function() {
// do stuff
}
If this is bad practise or if there is a better way to do it, please let me know.
You can do that, yes. Here's an example:
Example.prototype.methodA = function() {
someContainerElement.addEventListener("click", function() {
if (/* `event.target` is a match for the first button*/) {
this.methodB();
} else {
this.methodC();
}
}.bind(this), false);
};
Of course, it doesn't have to be an if, could be a switch or a map lookup or...
Live Example:
function Example(element, name) {
this.name = name;
this.element = element;
this.output = element.querySelector(".output");
}
Example.prototype.methodA = function() {
this.element.addEventListener("click", function() {
if (event.target.name == "B") {
this.methodB();
} else {
this.methodC();
}
}.bind(this), false);
}
Example.prototype.methodB = function() {
this.output.innerHTML =
prep(this.name).toLowerCase();
};
Example.prototype.methodC = function() {
this.output.innerHTML =
prep(this.name).toUpperCase();
};
function prep(text) {
return text.replace(/&/g, "&").replace(/</g, "<");
}
new Example(document.getElementById("one"), "one").methodA();
new Example(document.getElementById("two"), "two").methodA();
<div id="one">
The "one" element:
<br>
<input type="button" name="B" value="Lower">
<input type="button" name="C" value="Upper">
<span class="output"></span>
</div>
<div id="two">
The "two" element:
<br>
<input type="button" name="B" value="Lower">
<input type="button" name="C" value="Upper">
<span class="output"></span>
</div>

Getting the collection in a jQuery plugin

Basically, what I am trying to do is create a bbcode editor with a textbox, some buttons and jQuery. Here is my form:
<div class="form-group">
<div class="btn-group btn-group-sm">
<button type="button" class="btn glyphicon bbcode" rel="bold"><b>B</b></button>
<button type="button" class="btn glyphicon bbcode" rel="italic"><i>I</i></button>
</div>
</div>
<div class="form-group">
<textarea class="bbcode" rel="editor" cols="100" rows="12"></textarea>
</div>
and my plugin is called using:
<script>
$('document').ready(function() {
$('.bbcode').bbcode();
});
</script>
and the plugin itself, I am just trying to get the basics done at the minute to update the textbox data when a button is clicked:
(function($) {
"use strict";
$.fn.bbcode = function() {
this.click(function() {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$('.bbcode[rel=editor]').val('test');
return this;
}
});
}
} (jQuery));
This seems to be the only way I can pick up the textbox, I don't really want to hardcode the class I want like that. I think what I am looking for is a way to get the collection from the function call in the script tags.
This is more than likely something stupid/obvious I have overlooked.
The value of this in the immediate function refers to the collection. However, it is shadowed by the this inside your click handler (which refers to the element being clicked) so you cannot access it.
Create a variable to store this and that'll be your collection.
(function ($) {
"use strict";
$.fn.bbcode = function () {
var $editors = this;
this.click(function () {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$editors.val('test');
return this;
}
});
}
}(jQuery));

Public property bound to button outside of class doesn't have the same value as button bound internally when object is instantiated

Overall, I have an object that keeps track of selected checkbox IDs. The way it does this is by pushing/slicing the IDs into/out of an array, $Grid.selectedRows. This object also binds a 'refresh' method to a refresh button. I have a class that I created that object from, KendoGridSelection.
My issue is the button bound inside of the class shows the correct array values, while the button bound outside of the class with the public selectedRows property no longer updates after the refresh button is clicked.
For testing purposes, I have two seeSelectedRowsArray buttons:
seeSelectedRowsArray button (Bound internally)
seeSelectedRowsArray2 button (Bound outside of class)
I am testing in Chrome Version 28.0.1500.95 m
Here is my code:
JS
var KendoGridSelection = function (gridID, pagerSelector) {
var $Grid = this;
$Grid.selectedRows = [];
$Grid.gridID = gridID;
$Grid.pagerSelector = pagerSelector;
$Grid.grid = $($Grid.gridID).data('kendoGrid');
$Grid.pager = $($Grid.pagerSelector).data('kendoPager');
$Grid.gridCheckboxes = $('input[type=checkbox]', $Grid.gridID);
$Grid.gridRows = $('table tbody tr', $Grid.gridID);
$Grid.refreshButton = $('.refreshButton', $Grid.gridID);
$Grid.bindUIEvents = function () {
$Grid.gridCheckboxes = $('input[type=checkbox]', $Grid.gridID);
$Grid.gridRows = $('.row', $Grid.gridID);
// Row click event
/*$($Grid.gridRows).click(function (e) {
if (!$(e.target).parent().hasClass('k-hierarchy-cell')) $(this).find('input[type=checkbox]').click();
});*/
// Checkbock click event
$($Grid.gridCheckboxes).click(function (e) {
console.log('checkbox clicked!');
e.stopPropagation();
var $t = $(this);
var checkboxID = $t.attr('id');
var thisRow = $t.closest('tr');
if ($t.is(':checked')) {
thisRow.addClass('k-state-selected');
// add to selected[]
if ($.inArray(checkboxID, $Grid.selectedRows) === -1) $Grid.selectedRows.push(checkboxID);
} else {
thisRow.removeClass('k-state-selected');
// remove from selected[]
$Grid.selectedRows.splice($.inArray(checkboxID, $Grid.selectedRows), 1);
}
});
}
$Grid.gridPersistSelected = function () {
$.each($Grid.selectedRows, function () {
var $t = $('#' + this);
if ($t) $t.click();
});
}
$Grid.pagerChange = function () {
$Grid.bindUIEvents();
$Grid.gridPersistSelected();
}
$Grid.refresh = function () {
$Grid.selectedRows = [];
$Grid.gridCheckboxes.attr('checked', false);
console.log('Refresh clicked.');
console.log('$Grid.selectedRows: '+$Grid.selectedRows);
}
// Init
$Grid.pagerChange();
// $Grid.pager.bind("change", $Grid.pagerChange);
// Unbind refresh button, then rebind
// Refresh button
$Grid.refreshButton.click(function(){
console.log('reset!');
$Grid.refresh();
});
$('.seeSelectedRowsArray').click(function(){
console.log($Grid.selectedRows);
});
return {
selectedRows: $Grid.selectedRows,
refresh: $Grid.refresh,
}
}
$(function(){
window.activeThreatsGrid = new KendoGridSelection('.grid', '.pager');
$('.seeSelectedRowsArray2').click(function(){
console.log(activeThreatsGrid.selectedRows);
});
});
HTML
<div class='grid'>
<div class='row'>
<label><input type="checkbox" id="item1"> </label>
</div>
<div class='row'>
<label><input type="checkbox" id="item2"> </label>
</div>
<div class='row'>
<label><input type="checkbox" id="item3"> </label>
</div>
<div class='row'>
<label><input type="checkbox" id="item4"> </label>
</div>
<div class='row'>
<label><input type="checkbox" id="item5"> </label>
</div>
<div class='pager'>
<input type="button" value="refresh" class="refreshButton">
</div>
<div><input type="button" value="seeSelectedRowsArray" class="seeSelectedRowsArray"></div>
<div><input type="button" value="seeSelectedRowsArray2" class="seeSelectedRowsArray2"></div>
</div>
CSS
.row{background:blue; height:20px; width:100px; margin-bottom:5px;}
JSFiddle
Demo
What is happening:
When I click on multiple checkboxes, then click the seeSelectedRowsArray, I get the correct values in the array. I can do this however many times and still get the correct values.
When I hit the refresh button, my console.logs tell me my selectedRows array is empty. Then when I click the seeSelectedRowsArray, the array is empty (expected). When I click the seeSelectedRowsArray2, the array still has values in it.
UPDATE 1
What I have found is if I bind $Grid.selectedRows to a button click from within my class, it always gets the most current values, even after refresh. If I bind the public selectedRows to a button click outside of my class, after the refresh button is clicked, selectedRows no longer updates and gets stuck at the value just before the refresh.
Why does the button bound internally show the correct array values, while the button bound outside of the class with the public selectedRows property no longer updates after the refresh button is clicked?
Any help would be appreciated!
Your problem lies in how you are returning/tracking references to the object.
In your constructor, you set $Grid = this
However, you return a new object as a result of the function:
return {
selectedRows: $Grid.selectedRows,
refresh: $Grid.refresh,
}
That returned object now only holds a reference to the current value of $Grid.selectedRows
When your refresh method sets $Grid.selectedRows to a new array it breaks the associated value from the returned object which remains set to the original array.
Change your refresh from:
$Grid.selectedRows = []
to:
$Grid.selectedRows.length = 0;
Demo

Javascript: Changing variable on button click

I have a javascript file linked to index.html like below:
<script src='game.js' type='text/javascript'>
</script>
Assume that game.js contains:
var speed = ...;
Along with some other content.
I have 3 buttons on the HTML page that when clicked I want to change the variable speed in the javascript. Once clicked I want all 3 buttons to be disabled or hidden until the reset button is clicked. Any idea how I go about this?
Using pure HTML/JavaScript, here's what I would do:
<form name="form1">
<span id="buttons">
<input type="button" name="button1" value="Speed1"/>
<input type="button" name="button2" value="Speed2"/>
<input type="button" name="button3" value="Speed3"/>
</span>
<input name="reset" type="reset"/>
</form>
<script type="text/javascript">
var speed, buttonsDiv=document.getElementById("buttons");
for (var i=1; i<=3; i++) {
var button = document.form1["button" + i];
button.onclick = function() {
speed = this.value;
alert("OK: speed=" + speed);
buttonsDiv.style.display = 'none';
};
}
document.form1.reset.onclick = function() {
speed = null;
alert("Speed reset!");
buttonsDiv.style.display = 'inline';
return true;
};
</script>
Here is a working example: http://jsfiddle.net/maerics/TnTuD/
Create functions within your javascript files that attach to the click events of each button.
The functions would change the variable you want.
aButtonelement.addEventListener('click',functionToChangeVariable,false)
Include the following in your Javascript file:
function DisableButtons() {
speed = 100;
document.getElementById("btn_1").disabled = true;
document.getElementById("btn_2").disabled = true;
document.getElementById("btn_3").disabled = true;
}
function EnableButtons() {
document.getElementById("btn_1").disabled = false;
document.getElementById("btn_2").disabled = false;
document.getElementById("btn_3").disabled = false;
}
In your HTML, assign the following onClick events:
<button onClick="DisableButtons();">Button 1</button>
<button onClick="DisableButtons();">Button 2</button>
<button onClick="DisableButtons();">Button 3</button>
<button onClick="EnableButtons();">Reset</button>
something like this? http://jsfiddle.net/qMRmn/
Basically, speed is a global variable, and clicking a button with the class set-speed class will set the speed to a new value, and disable all of the set-speed buttons. Clicking the reset button will re-enable them.
The code should be fairly self explanatory.
Easiest way, use jQuery.
$("#idofbutton").click(function () {
// change variables here
});
Or you could register an event:
document.getElementById("idofbutton").addEventListener('click', function () {
// change variables here
}, false);
Source

Categories

Resources