How can I use one event handler for multiple radio buttons? - javascript

I want mutliple radio buttons (number unknown, because they get created dynamcially) to have the same onClick or onChange event, whichever fits the best. I found examples for jQuery but not pure Javascript. Should i just loop trought all radio buttons on the form?
They get created in php like so:
//DB Connection already established
$sql = "SELECT * FROM users";
$results = $dbConnection->query($sql);
if($result->num_rows > 0){
while($row = $result->fetch-assoc()){
echo "<li><input type=radio name=all_users[] value='". $row['E-Mail'] . "'/>" . $row['Name'] . " " . $row['Lastname'] . "</li>";
}
}
else
{
echo "<p>No users found</p>";
}
How can i do that loop? Or is there any more common way of doing that?
If one of them get's clicked i want their value as a parameter for the event, in only one function.
Or Should i just add onclick=myfunction(this) into the php file?

I want multiple radio buttons (number unknown, because they get created dynamically) to have the same onClick or onChange event.
If one of them get's clicked i want their value as a parameter for the event, in only one function.
Let's assume that your PHP has rendered the list items and you have a common function called myFunction() which you want to use to log it's parameter to your console:
function myFunction(val){
console.log("The value is " + val);
};
Now if I understand you correctly, you want to run the above function whenever one of the rendered radio buttons are clicked and to pass the value of the value attribute of the radio button that was clicked as a parameter for the above function.
Firstly, you need to assigned all the rendered radio button in your list to a variable:
var x = document.querySelectorAll("li input");
Secondly, since x is a collection of objects (here, all the radio buttons rendered), you will now have to map through each item on x using forEach and assign a click listener on each radio button which runs the ClickItem()function passing it the item's defaultValue as a parameter val like this:
x.forEach(function(radio) {
radio.addEventListener('click', function() {
var val = this.defaultValue;
myFunction(val);
});
});
jsFiddle: http://jsfiddle.net/AndrewL64/2y6eqhb0/56/
However, if by value, you mean the content after the input tag but still inside the respective li tag, then you just need to make slight changes to the above code like this:
Firstly, to prevent the selector from querying li elements from other parts of the page, you need to wrapped your list items with a div or a ul having a unique ID like this:
<ul id="someList">
//create your list items here
</ul>
Secondly, you need to assigned all the rendered list items to a variable:
var x = document.querySelectorAll("#someList li");
Thirdly, similarly to what we did above, since x is a collection of objects (here, all the list items rendered), you will now have to map through each item on x using forEach and assign a click listener on each list item which runs the ClickItem()function passing it the item's innerText as a parameter val like this:
x.forEach(function(radio) {
radio.addEventListener('click', function() {
var val = this.innerText;
myFunction(val);
});
});
jsFiddle: http://jsfiddle.net/AndrewL64/2y6eqhb0/58/

Actually the JQuery make it easier, but you can do the same with pure JS.
the real concept is to capture the event bubbling, try this:
fatherElement => element that is not dynamic
fatherElement.addEventListener("click", function(event){
if(event.target.type == 'radio'){
//do something
}
});

Use this echo line instead yours:
echo "<li><input onchange='yourOnChange(event)' type=radio name=all_users[] value='". $row['E-Mail'] . "'/>" . $row['Name'] . " " . $row['Lastname'] . "</li>";
I add onchange='yourOnChange(event)' there. And of course remember to add proper js function e.g function yourOnChange(e) { console.log(e); } to your web page.

Or Should i just add onclick=myfunction(this) into the php file?
Yes, you can do that. In that case code will be;
<li><input onclick='myclick('". $row['E-Mail'] ."')' type=radio name=all_users[] value='". $row['E-Mail'] . "'/>" . $row['Name'] . " " . $row['Lastname'] . "</li>"
Now in JS code myclick(email) function can handle anything with email argument.
Pure JS solution:
var inputs = document.getElementsByTagName('input');
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].type.toLowerCase() == 'radio') {
if(inputs[i].checked)
{
//if radio button is checked
myClick(inputs[i].id, 'checked') //you can get anything apart from id also
}
else
{
//if radio button is not checked
myClick(inputs[i].id, 'unchecked') //you can get anything apart from id also
}
}
}
myClick(id, stat)
{
//YAY!! I have got the id
}

You can do a for of loop if you have querySelectorAll.
Here is an example:
const radios = document.querySelectorAll('input[type=radio]');
for (const element of radios ) {element.addEventListener('click', function(event) {
console.log(event.currentTarget)
})
}

Using pure JS you can select your radio buttons and add event listeners like so:
const radios = document.querySelectorAll('input[type=radio]');
radios.forEach(radio => radio.addEventListener('change', e => {
// radio is your radio button element
});
Same with jQuery:
$('input[type=radio]').change(() => {
//your code goes here
});

Related

Change a button's class using js when php is displaying the buttons in a while loop

`<?php
$i = 0;
$testcount = 0;
while($testcount < 8) {
if($i == 0) {
?>
<input id="info" type="hidden" value="hi">
<?php
} else if ($ == 1) {
?>
<input id="info" type="hidden" value="test">
<?php
}
?>
<button onclick="test()" class="btnT">Hello</button>
<?php
$testcount++;
}
?>
<style>
.test1 {
background-color: cyan;
color: black;
}
</style>
<script type="text/javascript">
function test () {
$(".btnT").addClass("test1");
}
</script>`
Ignore the if statement, I have not yet implemented it to the js
I am displaying buttons using php while loop without any text nor class. A class is determined using an if statement using php where they will hold a hidden input value which will then be pushed to javascript which will then add a class depending on the value of the hidden input, I am then trying to remove and add another class to only one individual button displayed in the while loop. I either get the first button to get the change, or it changes all of the buttons, and not the individual button that I clicked. Please help, Thank you!
My biggest question is how to make each button inside the while loop to have the event occur individually, instead of all of them. I know that it is because I have the code to add a class to the button class, I tried replacing the button class with an id, but that way, only the first button will get the new class added and not the rest of the buttons. Hopefully there is a solution for each button to act separately
When you create your while loop you can append the $testcount to the end of an ID for the button, this way each button will have its own unique ID, but still have a 'template' name that you can use in javascript.
<?php
$i = 0;
$testcount = 0;
while($testcount < 8) {
echo '<button id="btn'.$testcount.'" onclick="test('.$testcount.')" class="btnT">Hello</button>';
$testcount++;
}
?>
Afterwards you should get 7 buttons with ID's btn1, btn2, btn3, btn4... etc
Then in Javascript you can run a function based off each button like this:
function test(x) {
var myButton = document.getElementById('btn' + x);
myButton.classList.add("test1");
// Any more JS logic you have
}
When you click, for example, button #2, the ID of that button should be 'btn2'. The onclick of the button will send the number '2' as an argument to the JS function. The variable myButton will get the element by the ID of the btn + the number you gave it to create a string like 'btn2', then based off that you now know which button was pressed, and you are able to run actions based off that. Using your example you added the class 'test1' to that button.

Unable to get element id dynamically in javascript

I have a list of students that I am looping through and adding to my page. Each student has a unique ID, and when getStudentInfo is invoked, it does something with the id. The problem is that whichever student I click, I get back the same id, belonging to student1.
Where am I going wrong?
foreach ($students as $student) {
echo '<tr>';
echo '<td>
'.$student[student_permalink].'
<input type="submit"
value="info"
onclick="getStudentInfo()"
class="student-name-btn"
id="'.$student[student_permalink].'"
/>
</td>';
}
js:
function getStudentInfo() {
var studentLink = $('.student-name-btn').attr('id');
console.log(studentLink);
}
Your code is selecting all the buttons on the page with that class and than reads the id of the first one in the list. You are not limiting it to the one that was clicked.
What most people would do is add events with jQuery and not inline.
//needs to be loaded after the element or document ready
$(".student-name-btn").on("click", function() {
console.log(this.id);
});
For yours to work, you would need to pass a reference to the button that was clicked.
onclick="getStudentInfo(this)"
and than change it to use the node passed in
function getStudentInfo(btn) {
var studentLink = $(btn).attr('id');
console.log(studentLink);
}
You can pass the reference to the element being clicked on the onclick event
foreach ($students as $student) {
echo '<tr>';
echo '<td>
'.$student[student_permalink].'
<input type="submit"
value="info"
onclick="getStudentInfo(this)" // << added this which refers to the input
class="student-name-btn"
id="'.$student[student_permalink].'"
/>
</td>';
}
And then use that to fetch the id in the js
function getStudentInfo(el) {
var studentLink = $(el).attr('id');
console.log(studentLink);
}
Don't use inline events - there's no need to clutter up the HTML with that. You have a common class on your element, so just make a jQuery handler and use an instance of this
$('.student-name-btn').click(function() {
var id = this.id;
});
Like #epascarello alluded to, you are not selecting the button that was actually clicked. What you should do is have your event handling in your JS, not in the HTML so you can see better how it works and use the this keyword within the closure to reference the clicked button.
$(document).on('click', '.student-name-btn', function(evt) {
// Prevent default if trying to do your own logic
evt.preventDefault();
// Need to use the "this" keyword to reference the clicked element
var studentId = $(this).attr('id');
console.log(studentId);
});
You can do this without inline JavaScript and since you're using jQuery drop the onClick() and the form element:
echo '<tr>';
echo '<td id="'.$student['student_permalink'].'" >
'.$student['student_permalink'].'
</td>';
You also need to quote the identifier in the array variable, 'student_permalink'.
The jQuery will be this:
$('td').click(function() {
var studentLink = this.id;
console.log(studentLink);
});

how to dynamically render multiple form elements using for loop

i want to display a certain number of input tags for a form; this should depend on how many items a user dynamically selects that they want.
for example, if a user says they want 3 items. i want to display 3 input bars.
i am not clear of the best way to proceed with this. for example, i am able to determine how many items they select from the select options:
$(".howmany").change(function(){
var value = $(this).val();
}
but what is the correct way to proceed thereafter; do i dynamically render the exact number of input tags selected using a for each: or pre-display (but hide) all of the input tags and only show the exact number of input tags requested.
i would appreciate an example of how its been done . at the moment i am only able to hide the entire area. eg:
var requests = $("#howmany").val();
if (reqeusts < 1){
$('#reqeusts').hide();
}
else {
$('#reqeusts').show();
}
but i obviously need to be able to show individual form tags accordingly to the number the user selected.
hi again, i want to thank everyone for their answers.
i deeply sorry, but i forgot to mention that the reason for the confusion is that the values for the imput are dynamically fed from an array function.
public function arrayValues()
{
return $selection = array(
'0' => 'none' ,' 1' => '1 item' ,' 2' => '2 item' ,' 3' =>' 3 item' );
}
i then need to render one of the below imput select tags for each number of items selected.
<?php echo '
<select id="howmany" name="items[howmany]" />';
foreach ($arrayValues as $key => $value)
{
echo '<option value="' . $key .'">' . $value . '</option>';
}
echo'</select>';
?>
$(".howmany").change(function(){
var value = $(this).val(); // get the number of inputs
value = parseInt(value); // make sure it's an integer
htmlStr = "";
for (var i = 0; i < value; i++)
{
htmlStr += "Label " + i +" <input type='text'>";
}
$('.container').empty();
$('.container').append(htmlStr);
}
You need something like this:
$('button').click(function () {
$('div').empty().append(new Array(+$('input[type=number]').val()+1)
.join("<input type='text' placeholder='Type Something'/>"));
});
I hope this gives you an idea of how to solve your problem.
DEMO

How to populate a dropdown list based on values of the another list?

I want to implement a search box same as this, at first, just first dropdown list is active once user selects an option from the first dropbox, the second dropdown box will be activated and its list will be populated.
<s:select id="country" name="country" label="Country" list="%{country} onchange="findCities(this.value)"/>
<s:select id="city" name="city" label="Location" list=""/>
Jquery chained plugin will serve your purpose,
https://plugins.jquery.com/chained/
usage link - http://www.appelsiini.net/projects/chained
this plugin will chain your textboxes.
Try this code where based on your needs you have to populate it with your options:
var x;
$('#pu-country').on('change', function () {
if (this.value != '0') {
$('#pu-city').prop('disabled', false);
$('#pu-city').find("option").not(":first").remove();
$('#pu-location').prop('disabled', true);
$('#pu-location').val("Choose");
switch (this.value) {
case 'A':
x = '<option value="A.1">A.1</option><option value="A.2">A.2</option><option value="A.3">A.3</option>'
}
$('#pu-city').append(x)
} else {
$('#pu-location').prop('disabled', true);
$('#pu-location').val("Choose");
$('#pu-city').prop('disabled', true);
$('#pu-city').val("Choose");
}
});
$('#pu-city').on('change', function () {
if (this.value != '0') {
$('#pu-location').prop('disabled', false);
$('#pu-location').find("option").not(":first").remove();
switch (this.value) {
case 'A.1':
x = '<option value="A.1.1">A.1.1</option><option value="A.1.2">A.1.2</option><option value="A.1.3">A.1.3</option>'
break;
case 'A.2':
x = '<option value="A.2.1">A.2.1</option><option value="A.2.2">A.2.2</option><option value="A.2.3">A.2.3</option>'
break;
case 'A.3':
x = '<option value="A.3.1">A.3.1</option><option value="A.3.2">A.3.2</option><option value="A.3.3">A.3.3</option>'
break;
}
$('#pu-location').append(x)
} else {
$('#pu-location').prop('disabled', true);
$('#pu-location').val("Choose");
}
});
I have also set up and a demo to see the functionallity with more options.
FIDDLE
Your code should be something like this:
$(country).change(function(){
var l=Document.getElementByID("country");
for(i=0;i<=l.length;i++)
{
if(l.options[i].selected?)
{
text_array=[HERE YOU NEED TO ADD THE CITIES OF l.options[i].text];
val_array=[HERE YOU NEED TO ADD THE VALUES OF THECITIES OF l.options[i].text];
}
}
var c=Document.getElementByID("city");
c.options.text=[];
c.options.value=[];
//You now should have an empty select.
c.options.text=text_array ;
c.options.value=val_array ;
});
As I don't know, what kind of DB you use, to have the cities connected to their countrys, I can't tell you, what to put into the uppercase text...
Ciao j888, in this fiddle i tried to reconstruct the same system as the site you provided the link
the number of states cityes and locality is less but the concept remains the same
If you want to add a new state you must enter a new html options in select#paese with an id.
Then you have add in obj.citta a property with this id name and an array of cityes for a value.
The same thing for obj.localita where you will create an array of arrays.
The jQuery code you need is
<script type="text/javascript">
$(document).ready(function(){
var obj={
citta:{ //value is the same of option id
albania:['Durres','Tirana'],
austria:['Vienna','innsbruck','Graz'],
},
localita:{//for every city create a sub array of places
albania:[['località Durres1','località Durres 2'],['località Tirana','località Tirana 2']],
austria:[['località Vienna','località Vienna 2'],['località innsbruck','località innsbruck 2'],['località Graz','località Graz 2','località Graz 3']],
}
}
$('#paese').on('change',function(){
$('#località').attr('disabled','disabled').find('option').remove()
var quale=$(this).find('option:selected').attr('id')
var arr=obj.citta[quale]
if(arr){
$('#citta').removeAttr('disabled')
$('#citta option.added').remove()
for(i=0;i<arr.length;i++){
$('<option class="added">'+arr[i]+'</option>').appendTo('#citta')
}
}
})
$('#citta').on('change',function(){
var ind=($(this).find('option:selected').index())-1
var quale=$('#paese').find('option:selected').attr('id')
var arr=obj.localita[quale][ind]
if(arr){
$('#località').removeAttr('disabled')
$('#località option.added').remove()
for(i=0;i<arr.length;i++){
$('<option class="added">'+arr[i]+'</option>').appendTo('#località')
}
}
})
})
</script>
If this solution does not suit your needs, i apologize for making you lose time.
Hi i have done this for license and its dependent subject in yii 1.
The license dropdown
//php code
foreach($subject as $v) {
$subj .= $v['licenseId'] . ":" . $v['subjectId'] . ":" . $v['displayName'] . ";";
}
Yii::app()->clientScript->registerScript('variables', 'var subj = "' . $subj . '";', CClientScript::POS_HEAD);
?>
//javascript code
jQuery(document).ready(function($) {
//subject. dependent dropdown list based on licnse
var ty, subjs = subj.split(';'), subjSel = []; //subj register this varible from php it is
for(var i=0; i<subjs.length -1; i++) { //-1 caters for the last ";"
ty = subjs[i].split(":");
subjSel[i] = {licId:ty[0], subjId:ty[1], subjName:ty[2]};
}
//dropdown license
jQuery('#license#').change(function() {
$('#add').html(''); //clear the radios if any
val = $('input[name="license"]:checked').val();
var selectVals = "";
selectVals += '<select>';
for(var i=0; i<subjSel.length; i++) {
if(subjSel[i].licId == val) {
if(subjSel[i].subjId *1 == 9) continue;
selectVals += '<option value="'+subjSel[i].subjId+'">'+subjSel[i].subjName+'</option>';
}
}
selectVals += '</select>';
$("#subject").html(selectVals);
});
});
You seem to be asking two questions:
QUESTION 1. How to have a disabled select box (the second and third select boxes in the case of your example) which is activated upon the selection of an option from the first select box.
ANSWER 1:
simply use the disabled=true/false as below...
<select id="country" name="country" label="Country" onchange="document.getElementById('city').disabled=false; findCities(this.value)"/>
<select id="city" name="city" label="Location" disabled=true/>
NOTE: I changed "s:select" to "select" on the basis that your question does not make reference or tag the Struts framework that uses this syntax.
QUESTION 2: How to populate the second select box when a selection is made in the first.
ANSWER 2: There are many ways to do this, and the choice depends on where you have the data to populate the lists with. In the case of your Rentalcars example, if you chose Barbados, the browser sends an ajax GET request to "http://www.rentalcars.com/AjaxDroplists.do;jsessionid=5DCBF81333A88F37BC7AE15D21E10C41.node012a?country=Barbados&wrapNonAirports=true" -try clicking on this link and you will see what that request is sending back. This '.do' address is a server side file of a type used with the Struts framework I mentioned above.
A more conventional approach, which would be included in your function findCities(country)would be to send an AJAX request to a PHP script which queries a database and sends back an array of place names to the browser. The AJAX javascript code includes instructions as to what to do with the response. Without knowing more about where you want to store your list, giving an example of this would most likely not be useful.
Alternatively, the whole list of places could be included in the javascript script as an array (as demonstarated by Devima, above), in a text document on the server as comma separated values, or you could save it to a browser database like WebSQL or IndexedDB if offline use would be useful.
When you have got your list, probably as an array of values, you could save the array as a variable eg. var cities=result (in the case of a simple ajax request). You will then need to iterate through cities, for example
for (var i = 0; i < cities.length; i++){
var place=cities[i];//an individual city name
document.getElementById("city").innerHTML+="<option value='" + place + "'>" + place + "</option>";//adds an 'option' with the value being the city name and the text you see being the city name
}
IMO this is the base case AngularJS was designed to completely alleviate. Check it out!

Trying to use Javascript to populate a hidden input

I have this code:
while($row = mysql_fetch_array($res)) {
$name = $row['advertiser'];
$id = $row['id'];
if($row['id'] % 4 == 1 || $row['id'] == 1)
{
echo "<tr>";
}
if($row['availability'] == 0)
{
$td = "<td id='green'>";
}
if($row['availability'] == 1)
{
$td = "<td id='grey'>";
}
if($row['price'] == 0)
{
mysql_query("UPDATE booklet SET availability = 0 WHERE id = '$id'");
}
echo $td . $row['id'] . "<br/><p style='font-size: 6pt;'>" . $name[0] . "<p><img src=" . $row['image'] . "></td>";
if($row['id'] % 4 == 0)
{
echo "</tr>";
}
}
It creates a table. What I want to do is this: if you click on a td, I want to pass the value of that td, for example - the number one (1), if you clicked on the first td - I want to pass this value over to a hidden input so I may later use it elsewhere.
The table looks fine. I know what to do when I have the value in a hidden input. I just need to be able to have the table, when I click on a td, to pass the value over. Or to do anything. onClick doesn't work. Even the absolute simplest isolated JQuery statements don't even come close to parsing. The most complex Javascript that actually has worked on this page is a document.write(). Everything else stumps any known browser.
So, using absolutely any methods, is it a possibility, within the realm of current technology, to have code that does what I want?
Again, I need to have a table cell, when clicked on, pass a variable to a hidden input. I've tried everything.
You'll need to add the click event with JQuery and then use Jquery to set the value... Something like this should work.
$(function() {
$("table#mytable td").mouseover(function() {
//The onmouseover code
}).click(function() {
//The onclick code
$("#hiddenInputID").val(text);
});
});
<td onclick="document.forms[0]['nameofhiddenfield'].value = this.id"> ... </td>
Try to validate your html, you might have mismatched quotes/square brackets somewhere, which breaks Javascript.

Categories

Resources