best way to format multiple onclick buttons - javascript

Back again! I always get such great responses here!
I currently have a HTML site with multiple onclick buttons calling up a js function allowing users to "opt-in" to certain notification services. If the user wants to op-in to multiple groups, they are required to hit each button one at a time.
It technically works, but as you can imagine it certainly doesn't look pretty. Additionally, the way it's set up now, the user doesn't get any feedback that they have successfully subscribed to said group (not a huge concern though).
Here's a snip of the code right now:
<button onclick="_pcq.push(['addSubscriberToSegment', '50cc']);">
50cc
</button>
<button onclick="_pcq.push(['addSubscriberToSegment', '65a']);">
65A
</button>
<button onclick="_pcq.push(['addSubscriberToSegment', '65b']);">
65B
</button>
<button onclick="_pcq.push(['addSubscriberToSegment', '85a']);">
85A
</button>
<button onclick="_pcq.push(['addSubscriberToSegment', '85b']);">
85B
</button>
I should also note that although I only listed 5 buttons here, the website actually has more than 20...which is pretty overwhelming.
Does anyone have an elegant way (open to suggestions) to format this?
I thought of doing bullets, but I struggled with getting the form to run 'addSubscriberToSegment' with different values off of one submit button.
Surely it's just my lack of expertise that has got me stumped. Perhaps some of you will have a nicer solution for me?
Thanks!

I would do nested checkboxes for something like this. Each option has a checkbox, but there are also general sections that you can check on or off to enable/disable a group of options. Take a look at this codepen by lonekorean for an idea how to style them, you can add a little bit of javascript to make parent checkboxes enable/disable their children items.

The best way, probably, is to replace your buttons with checkboxes, as mentioned by u_mulder.
In any case it is better to create a function where you can handle the subscription and the notification instead of pushing things on the fly into an array.
for example:
function subscribeAnything(codeVariable){
_pcq.push(codeVariable);
alert("Great you have subscribed to " + codeVariable);
}
Then you add an eventlistener as commented by Jordan Davis to link this function.
If you decide to effectively replace the buttons by checkboxes, you could set the subscription code into the name or id of each checkbox and then loop trough your checkboxes to push them into your array.
var myChbxArray = [];
var btn = document.getElementById("pushCheckBoxes");
btn.addEventListener("click", pushAllChbxIntoArray, false);
function pushAllChbxIntoArray(){
myChbxArray = []; // clear content of array
var inputs = document.getElementsByTagName("input");
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].type == "checkbox" && inputs[i].checked == true) {
myChbxArray.push(inputs[i].name);
}
}
notification();
}
function notification(){
var myDiv = document.getElementById("result");
myDiv.innerHTML = "You have checked the following checkboxes:<br>";
for(var i = 0; i < myChbxArray.length; i++) {
myDiv.innerHTML = myDiv.innerHTML + myChbxArray[i] + "<br>";
}
}
ul{
list-style-type: none;
}
<div id="checkboxList">
<ul>
<li><label for="chk1"><input type="checkbox" name="chk1" id="chk1">Chk1</label></li>
<li><label for="chk2"><input type="checkbox" name="chk2" id="chk2">Chk2</label></li>
<li><label for="chk3"><input type="checkbox" name="chk3" id="chk3">Chk3</label></li>
<li><label for="chk4"><input type="checkbox" name="chk4" id="chk4">Chk4</label></li>
</ul>
<button id="pushCheckBoxes">ClickMe</button>
</div>
<div id="result">
</div>

Related

How to create a clickable list with multiple values in an element?

I am trying to create a list of names an user could chose from to select a object with multiple hidden values. I work with a PHP backend.
The code I wrote works but I think it is probably not the right way to approach the problem and could be written alot better, but I can't seem to find a better way.
Right now I print a <div> for every object which are clients in my case. Within the div I have four checkboxes that are hidden, which I check and uncheck on the background with a javascript function. The values of those checkboxes is what I need in javascript for an API call after the user choses the client.
I select and deselect the with a javascript function.
foreach($clients as $client) {
echo '<div class="'.$client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="checkbox" class="'.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="checkbox" class="'.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="checkbox" class="'.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="checkbox" " class="'.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
For every element I create an on click event handler
for (var i = 0; i < clientList.length; i++) {
const {name, id} = clientList[i];
$(`.${name}-${id}`).on('click', function() {
selectClientFromList({name, id});
});
}
I am trying to get a list of clickable "names". When a "name" is clicked, you want to get the "name" but also "id", "facebook", "instagram", "website".
Might be useful to use the <select> tag with multiple values like this but I don't want a dropdown. I need a scrollable list, because I also have use searchbar for this list.
With a lot of clients the html would grow fast. How do I clean my php code and keep the information about a client that the user selected?
Thanks in advance!
A good approach can be to use a hidden input. Give your div a class and then
foreach($clients as $client) {
echo '
<div class="'. $client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
And then instead of creating a click handler everytime. One works too.
$(`.aclass`).on('click', function() {
let type = $(this).attr('name'); // client_id or client_fb
let client_id = $(this).attr('class').replace("aclass",""); // $client->id's value is here
let value = $(this).val(); // credentials
});

Javascript: script for menu not reacting when menu is dynamically created

I have this menu, statically, it is as follows:
<div class="dropdown col-sm-3">
<button type="button"
class="btn btn-select btn-block"
data-toggle="dropdown">Plane <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-select" id="plane">
<li><label class="dropdown-radio"> <input type="radio" value="3" name="plane"> Plane: A360 </label></li>
<li><label class="dropdown-radio"> <input type="radio" value="2" name="plane"> Plane: AR45 </label></li>
<li><label class="dropdown-radio"> <input type="radio" value="1" name="plane"> Plane: A380 </label></li>
</ul>
</div>
...
<script>
$('.dropdown-radio').find('input').change(function() {
var dropdown = $(this).closest('.dropdown');
var radioname = $(this).attr('name');
var checked = 'input[name=' + radioname + ']:checked';
//update the text
var checkedtext = $(checked).closest('.dropdown-radio').text();
dropdown.find('button').text( checkedtext );
//retrieve the checked value, if needed in page
var thisvalue = dropdown.find( checked ).val();
console.log( thisvalue );
});
</script>
This version worked: the user could select one (and only one) option, and the option would then be displayed in the main button. I have now created this same menu dynamically with data from a MySQL database.
<script>
var socket = io.connect('http://localhost:3000');
socket.on('sess', function(message) {
if(message == 0){
alert('No planes associated.');
}else{
for(var i = 0; i < message.length; i++){
$('#session').prepend( '<li><label class="dropdown-radio" > <input type="radio" value="'
+ message[i].idSession + '" name="session"> Session: '
+ message[i].idSession + ' </label></li>');
}
}
});
</script>
Here the menu still drops down but now the user can check as many radios as they want and the first script isn't activated (nothing appears in the console). I have tried putting the second script both before and after the previous one, both give the same results.
Is there a workaround for this? I'm new to Javascript (jQuery) and its sensibilities.
Thanks
What you want is to bind the change event to a higher on hierarchy element rather then directly at the inputs that didn't exist yet:
$('#plane').on('change', 'input', function() {
var dropdown = $(this).closest('.dropdown');
var radioname = $(this).attr('name');
var checked = 'input[name=' + radioname + ']:checked';
//update the text
var checkedtext = $(checked).closest('.dropdown-radio').text();
dropdown.find('button').text( checkedtext );
//retrieve the checked value, if needed in page
var thisvalue = dropdown.find( checked ).val();
console.log( thisvalue );
});
Doing so, you are binding the change event to the parent div, so doesn't matter how you modify its children on a later moment, it will always fire an event for it if the target element was an input (second function argument).
You don't need to execute this script AFTER the inputs were loaded, just go with your initial approach on dynamically loading content but tweak that change with the on('change' version.
I've combined my comments to an answer for easier reading/for anyone else looking at this.
The first script runs once inline of the page load and due to the asynchronous call to your database, that means it doesn't find anything to bind change to and then the script is never run again. You'll need to update your script so that it is run again after the new radio buttons have all been loaded into the DOM (this is after in time, not on the page).
Consider saving your first script to a function and calling it from your database call success, post rendering your radio buttons. You may need to use .off('change') also to remove any existing change bindings before creating new ones.
With regards to your radio buttons allowing multiple selected, as long as they share a name then they shouldn't allow multiple as per the documentation.

Show Selected Items Before Removing from Database

I've been researching how to do this and I can't find any helpful links so I'm asking here.
I have table on my website with data from my database. Each item has a delete checkbox next to it. If the user checks these boxes then hits the delete button, they are prompted with a message asking them if they are sure they want to delete the items. If they say yes, then the items are removed. I'd like to show what they selected in the confirmation box.
Example: Let's say they selected item4, item8, and item9, then clicked on delete. I'd want the prompt to say:
"Are you sure you want to delete the selected items?
item4
item8
item9"
I'm not sure how to even start this. Here's my current delete button:
<input type="submit" value="Delete" onclick="return confirm('Are you sure you want to delete the selected item(s)?');"/>
You could use javascript for this, something like below will work (pseudo code);
<!-- Add the onclick handler -->
<input type="submit" onclick="submitOnClick();" value="Delete" />
// Javascript function
function submitOnClick() {
var ret = "";
var table = getTable();
for (int i = 0; i < table.length; i++) {
if (row.checked) {
ret += row.innerText + " ";
}
}
alert('Are you sure you want to delete the selected items of " + ret);
}
Depending how your HTML is setup/structured you may have to change things to get it working properly.
Hoped this helped.

Using NG-repeat to make a form with mutiple radio buttons: want to reset the value of all the radio buttons

I've got an issue with Angular; I have mutiple actors and every actor renders a radiobox form with 3 options: victim, causer and both.
Relevant template:
<div class="actor" ng-repeat="activeActor in activeActors">
<p class="category">{{activeActor}}</p>
<form name="radioButtonForm">
<div class="causerRadioForm">
<input type="radio" name="causerRadio" value="victum" ng-model="defaultRadioButton" ng-click="setActorCauser(activeActor, 'victum')">
</div>
<div class="causerRadioForm">
<input type="radio" name="causerRadio" value="causer" ng-model="defaultRadioButton" ng-click="setActorCauser(activeActor, 'causer')">
</div>
<div class="causerRadioForm">
<input type="radio" name="causerRadio" value="both" ng-model="defaultRadioButton" ng-click="setActorCauser(activeActor, 'both')">
</div>
</form>
</div>
This works fine however I have a button where if I click on it multiple actors (called fastActors) get rendered and have a default value of victum.
The problem is when I select a single actor and for example put it to causer and then click on fastActors, the radio box stays on causer while the radio button should reset to victum.
Relevant JS
$scope.toggleFastTraffic = function(actor){
//erase all actors
$scope.actors = [];
$scope.report.traffic_players = [];
//default value for radio boxes
$scope.defaultRadioButton = "victum";
$scope.SlowTraffic = false;
$scope.FastTraffic = true;
$scope.formOptionsExpanded = true;
$scope.activeActors = [];
var i = $scope.activeActors.indexOf(actor);
console.log($scope.activeActors.indexOf(actor));
if ($scope.counter === -1){
//do more here
}
Basically the moment I press toggleFastActor I wish to make all radio buttons victum.
Friendly greetings,
T
P.S. I am aware of the victum typo I am under orders to keep that tho :P
Here's a quick codepen, it's not done yet but it does contain the bug: if you press on car and make it a causer, and then toggle fast traffic the car goes to victim in the report (which is good) but the radio buttons don't change.
P.s the codepen has some other bugs too no need to pay attention to those.
http://codepen.io/CMD-Thomas/pen/yNbNaZ?editors=101
This happens because the ng-model value is same. Once you set the value of 'defaultRadioButton' to 'causer' it will remain causer for all. Remember MVVM pattern

How to Uncheck A radio button

I have two forms, one with a radio button that users must select to edit.
[form name="A"]
<li>[input type="radio" name="BookItem" value="1" /]</li>
<li>[input type="radio" name="BookItem" value="2" /]</li>
<li>[input type="radio" name="BookItem" value="3" /]</li>
[form]<p>
After "BookItem" is selected from form (A) I call the $("#EditFormWrapper").load("callEditData.cfm? ID="+ID); function to load the second form (B)
<div id="EditFormWrapper"><div></p>
<!---// begin dynamic form generated by external file callEditData.cfm //--->
[form id="editForm" name="B"]
<ul class="hourswrapper">
<li><input type="checkbox" id="TOR2Hours" class="TOR2Hours" name="TOR2Hours" value="AM2Hrs1" /> 2 Hours AM</li>
<li><input type="checkbox" id="TOR2Hours" class="TOR2Hours" name="TOR2Hours" value="PM2Hrs1" /> 2 Hours PM</li>
<li><input type="checkbox" id="TOR2Hours" class="TOR2Hours" name="TOR2Hours" value="AM2Hrs2" /> 2 Hours AM</li>
<li><input type="checkbox" id="TOR2Hours" class="TOR2Hours" name="TOR2Hours" value="PM2Hrs2" /> 2 Hours PM</li>
</ul>
[input type="image" src="images/submit-btn.gif" id="addBTN" name="addBTN" class="buttons" alt="SubmitRrequest" /]
[input type="image" src="images/cancel-btn.gif" id="editBTNcancel" name="editBTNcancel" class="buttons" alt="Cancel Request" /]
[/form]
<!---// end dynamic form from external file //--->
I want to uncheck the radio button on form (A) when user click on cancel button (editBTNcancel) in form(B).
Here's my script:
$("#editBTNcancel").live("click", function(event){
event.preventDefault();
$("#EditFormWrapper").slideUp("fast").empty();
//$('.TOR2Hours').removeAttr('checked');
$('.TOR2Hours').attr('checked', false);
});
I hope I clearly state my problem, any suggestion would be greatly appreciated!
you can access form like so ...
var exampleForm = document.forms['form_name'];
then loop through the form
for( var i=0; i<exampleForm.length; i++ ){
alert( exampleForm[i].type );
}
you can test for checked like so ...
if( exampleForm[i].checked )
to deselect the checked radio button try ...
exampleForm[i].checked=false;
the final code would look like this ...
var exampleForm = document.forms['form_name'];
for( var i=0; i<exampleForm.length; i++ ){
if( exampleForm[i].type ) == 'radio' && exampleForm[i].checked == true ){
exampleForm[i].checked = false;
}
}
I'm not sure exactly what you want but you might try using a reset input.
<input type='reset' />
Seeing as this is pretty much the easiest DOM task there is and works in every scriptable browser, I suggest not using the jQuery methods for it:
$(".TOR2Hours")[0].checked = false;
The other thing that ocurs to me is whether your selector is correct. Did you mean to select a set of elements by class or should it be an ID selector?
Your selector is simply wrong.
If you want to uncheck the radio button from first form you should use $('input[name="BookItem"]') and not $('.TOR2Hours') :
$("#editBTNcancel").on("click", function(event){
$("#EditFormWrapper").slideUp("fast").empty();
$('input[name="BookItem"]').attr('checked', false);
});
As far as which method to use to uncheck radio buttons, The following 3 methods should all work:
$('input[name="BookItem"]').attr('checked', false);
$('input[name="BookItem"]').removeAttr('checked');
$('input[name="BookItem"]').prop('checked', false);
However, check out jQuery's docs on jQuery prop() for the difference between attr() and prop().
I just discovered a great solution to this problem.
Assuming you have two radios that need to be able to be checked/unchecked, implement this code and change what's necessary:
var gift_click = 0;
function HandleGiftClick() {
if (document.getElementById('LeftPanelContent_giftDeed2').checked == true) {
gift_click++;
memorial_click = 0;
}
if (gift_click % 2 == 0) {document.getElementById('LeftPanelContent_giftDeed2').checked = false; }
}
var memorial_click = 0;
function HandleMemorialClick() {
if (document.getElementById('LeftPanelContent_memorialDeed2').checked == true) {
memorial_click++;
gift_click = 0;
}
if (memorial_click % 2 == 0) { document.getElementById('LeftPanelContent_memorialDeed2').checked = false; }
}
:) your welcome
I use this way to solve your problem in ASP.net, check this..
radioButton.InputAttributes["show"] = "false";
string clickJs = " if(this.show =='true'){this.show ='false'; this.checked = false;}else{this.show='true'; this.checked = true;};";
radioButton.Attributes["onClick"] = clickJs;
In asp.net, you can use this way to add an attribute. And you can also to add an attribute manually to the radioButton, and do the function(clickJs) to change the ckecked attributes!!!

Categories