Two array types into one function - javascript

I have a form where you click a button and a collection of elements need the opacity changed and the radio or checkbox selected. I have a bunch of these in the form so I need assistance with creating this type of array. Some of the IDs are dp001, dp002 …. dp050 so there needs to be a condition appending the prefix to it when it gets to dp010. This collection of elements I want to change the opacity. The other collection of elements isn't in any particular order but I want to collect them and make them checked. Somewhere I created a FUBAR :)
Fiddle won't work … really pi$$ing me off don't know why jsfiddle refuses to load javascript for me. Is This Fiddle FUBAR?
On my web server the alert works fine the doesn't do what I want.
Javscript works on my server check it out.
HTML
<div id="dp001">Item #1 <input type="radio" id="abc005"></div>
<div id="dp002">Item #2 <input type="radio" id="abc008"></div>
<div id="dp003">Item #3 <input type="checkbox" id="abc010"></div>
<div id="dp004">Item #4 <input type="checkbox" id="abc020"></div>
<div id="dp005">Item #5</div>
<div id="dp006">Item #6</div>
<div id="dp007">Item #7</div>
<div id="dp008">Item #8</div>
<div id="dp009">Item #9</div>
<div id="dp010">Item #10</div>
<div id="dp011">Item #11</div>
<button type="button" onclick="DoStuff();">Click</button>
JAVASCRIPT
function DoStuff() {
var items = null;
var checkMe = ["abc005" , "abc0008" , "abc010" , "abc020"];
for (i=1 ; i < 12 ; i++) {
if (i < 10) {
items = 'dp00' + i;
} else {
items = 'dp0' + i;
}
}
alert("ding");
document.getElementById("items").style.opacity="0.5";
document.getElementById("checkMe").checked = true;
}

I think you need
function DoStuff() {
var checkMe = ["abc005" , "abc0008" , "abc010" , "abc020"];
for (var i=1; i < 12; i++) {
var items = 'dp0' + (i<10 ? '0' : '') + i;
document.getElementById(items).style.opacity = 0.5;
}
for (var i=0, l=checkMe.length; i<l; ++i)
document.getElementById(checkMe[i]).checked = true;
}
Problems with your code:
"items" is a literal string, not the variable items. Same for "checkMe".
You must change each element inside the loop, not outside.
You don't declare variable i
You can use the ternary conditional to simplify code (optional)

Related

getElementsByClassName is not working in if condition

I'm Trying to get all the classnames with "items" and checking if innerHTML of each className by for loop and with given string. But even though the condition is true, nothing is happening in if condition.
I've implemented with the javascript and everything is working except the getElementsByClassName is not working
function clearAndAdd(){
var texter = document.getElementById("textBox").value;
if (texter != ""){
var allList = [];
document.getElementById("textBox").value = "";
created = 'deleteCurrent("'+texter+'")';
document.getElementById("lister").innerHTML = document.getElementById("lister").innerHTML+"<li class='items' onclick='"+created+"'>"+texter+"<span></span></li>";
document.getElementById("textBox").focus();
}
}
function deleteCurrent(text){
var allList = [];
var list = document.getElementsByClassName("items");
for(var i=0; i<list.length; i++){
var value = list[i].innerHTML;
if (value == text){
document.getElementById("output").innerHTML = value;
break;
}
}
}
<!-- HTML code -->
<body>
<div class="input-categories">
<ul id="lister">
</ul>
<input type="text" id="textBox" onblur="clearAndAdd();" />
</div>
<div id="output">
</div>
</body>
When I'm running the code with passing the string in text... even the value and the text are same, if condition is not executed. Can anyone help me with this
The content returned by list[i].innerHTML contains a <span> tag, so obviously it will never match the text you look for.
Instead of innerHTML use the textContent property: that will just return the text content:
var value = list[i].textContent;

Loop through checkboxes and conditionally disable unchecked

I'm trying to write a basic function in pure JS that simply checks the number of checked checkboxes, and if that number exceeds a certain amount, disables the rest. I can achieve this easily in jQuery, but trying to get it working in pure JS. I have a CodePen set up here and I'm including my working JS below. Thanks for any insight here.
(function() {
var checkboxes = document.querySelectorAll('input[id^="mktoCheckbox"]');
var active = document.querySelectorAll('input[id^="mktoCheckbox"]:checked');
var numActive = active.length;
console.log(numActive);
if (numActive > 1) {
for(var i = 0; i < checkboxes.length; i++){
if (checkboxes[i].checked == true) {
return;
} else {
checkboxes[i].disabled == true;
}
}
}
})();
There are two problems in your code:
You're returning from the if condition, which causes the loop to terminate.
You're not assigning true to disabled attribute, instead you're comparing with ==.
Change the related snippet to the following to make it work:
if (numActive > 1) {
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked != true) {
checkboxes[i].disabled = true;
}
}
}
You can find a working fork of your pen here. Following is a working SO snippet:
(function() {
var checkboxes = document.querySelectorAll('input[id^="mktoCheckbox"]');
var active = document.querySelectorAll('input[id^="mktoCheckbox"]:checked');
var numActive = active.length;
console.log(numActive);
if (numActive > 1) {
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked != true) {
checkboxes[i].disabled = true;
}
}
}
})();
<fieldset>
<legend>Choose some monster features</legend>
<div>
<input type="checkbox" id="mktoCheckbox_1" name="feature" value="scales" checked />
<label for="scales">Scales</label>
</div>
<div>
<input type="checkbox" id="mktoCheckbox_2" name="feature" value="horns" />
<label for="horns">Horns</label>
</div>
<div>
<input type="checkbox" id="mktoCheckbox_3" name="feature" value="claws" />
<label for="claws">Claws</label>
</div>
<div>
<input type="checkbox" id="mktoCheckbox_4" name="feature" value="tails" checked />
<label for="tails">Tails</label>
</div>
</fieldset>
Here's a working pen.
First of all, imo, you should use getAttribute and setAttribute on DOM elements. HTMLInputElement.checked afaik only reflects the checked attribute (and converts it to boolean) for convenience.
With that in mind, you need to now test against strings with the strict comparison operator ===. E.g.
if(checkbox.getAttribute('checked') === 'true') {...}
since using == would evaluate to false
true == 'true' // false
Also, instead of the for loop you can make use the for-of loop on DOM collections. I.e. this works:
const checkboxes = document.querySelectorAll('...');
for(const checkbox of checkboxes) {
...
}
Keep in mind that you use continue and break to control the loop and not return.

How to register order of checkboxes in AngularJS?

I currently have a list of checkboxes in my webapp. I want to show the order in which the checkboxes have been checked. So I wrote the code below.
$scope.updateNumbers = function(id, checked, inputs) {
if (checked === true) {
$scope.count += 1;
var span = angular.element('#'+id+'-'+id);
span.html($scope.count);
} else {
if ($scope.count != 0) {
$scope.count -= 1;
}
for (index = 0; index < inputs.length; ++index) {
var input = inputs[index];
var span = angular.element('#'+test.id+'-'+test.id);
if (span.html() > $scope.count || span.html() == $scope.count) {
span.html(span.html()-1);
}
}
var span = angular.element('#'+id+'-'+id);
span.html($scope.count);
}
}
And this HTML
<div class="list-view__body__row" ng-repeat="restaurant in restaurants">
<div class="list-view__body__cell">
<input type="checkbox" id="<% restaurant.id %>" value=""
class="input-field__checkbox--input"
ng-model="restaurant.checked"
ng-change="updateNumbers(restaurant.id, restaurant.checked, restaurants)">
<label for="<% restaurant.id %>"
class="input-field__checkbox--label"
ng-bind-html="restaurant.name|html"></label>
</div>
<div class="list-view__body__cell">
<div class="order__wrapper" ng-show="restaurant.checked">
<span id="<% restaurant.id %>-<% restaurant.id %>">0</span>
</div>
</div>
</div>
In the current implementation, though, sometimes the number will go down to 0 or numbers will appear twice. It's not working correctly, so how can I improve on this code?
With angular you always want your data model to drive the view. Note that the following solution requires no dom manipulation code and angular manages the dom based on the data. It also requires very little code.
All you need for this is an array of the checked restaurants in your data model.
Then the order is determined by the index within this array and the count is the length of the array.
Controller:
// array to store selections
$scope.checkedItems=[];
$scope.updateSelections = function(rest){
if(rest.checked){
// add to array if item is checked
$scope.checkedItems.push(rest)
}else{
// remove from array if not checked
$scope.checkedItems.splice($scope.checkedItems.indexOf(rest),1)
}
}
View:
<div ng-repeat="restaurant in restaurants">
<div>
<input type="checkbox" ng-model="restaurant.checked"
ng-change="updateSelections(restaurant)">
<label ng-bind="restaurant.name"></label>
</div>
<div ng-show="restaurant.checked">
<!-- Use index to display order -->
Order: <span>{{checkedItems.indexOf(restaurant) +1}}</span>
</div>
</div>
<h3>Count of checked items: {{checkedItems.length}}</h3>
DEMO

When "check-all" box checked, check others

I have a form located on my html page with a bunch of checkboxes as options. One of the options is "check-all" and I want all the other check boxes to be checked, if unchecked, as soon as the "check-all" box is checked. My code looks something like this:
<form method = "post" class = "notification-options">
<input type = "checkbox" name = "notification-option" id = "all-post" onClick = "javascript:checkALL(this
);"> All Posts <br/>
<input type = "checkbox" name = "notification-option" id = "others-post"> Other's Posts <br/>
<input type = "checkbox" name = "notification-option" id = "client-post"> Cilent's Post <br/>
<input type = "checkbox" name = "notification-option" id = "assign-post"> Task Assigned </form>
java script:
<script type = "text/javascript">
var $check-all = document.getElementbyId("all-post");
function checkALL($check-all){
if ($check-all.checked == true){
document.getElementByName("notification-option").checked = true;
}
}
</script>
nothing happens when I run my code
Here are some guidelines.
type attribute is not needed and can be omitted.
JS variable names can't contain hyphens, a typo in
getElementById()
You're using a global variable name as an argument, in the same time
you're passing this from online handler. The passed argument shadows the
global within the function.
if (checkAll.checked) does the job
Typo in getElementsByName(), gEBN() returns an HTMLCollection,
which is an array-like object. You've to iterate through the
collection, and set checked to every element separately.
Fixed code:
<script>
var checkAll = document.getElementById("all-post");
function checkALL(){
var n, checkboxes;
if (checkAll.checked){
checkboxes = document.getElementsByName("notification-option");
for (n = 0; n < checkboxes.length; n++) {
checkboxes[n].checked = true;
}
}
}
</script>
You can also omit the javascript: pseudo-protocol and the argument from online handler.
You can do it like this using jQuery:
$("#all-post").change(function(){
$('input:checkbox').not(this).prop('checked', this.checked);
});
Here is a JSfiddle
if all post check box is checked it will set check=true of others-post and client-post check boxes
$("input[id$=all-post]").click(function (e) {
if ($("input[id$=all-post]").is(':checked')) {
$("input[id$=others-post]").prop('checked', true);
$("input[id$=client-post]").prop('checked', true);
}
});
Check to see if any of the checkboxes are not checked first.
If so, then loop through them and check any that aren't.
Else, loop through them and uncheck any that are checked
I have an example at http://jsbin.com/witotibe/1/edit?html,output
http://jsfiddle.net/AX3Uj/
<form method="post" id="notification-options">
<input type="checkbox" name="notification-option" id="all-post"> All Posts<br>
<input type="checkbox" name="notification-option" id="others-post"> Other's Posts<br>
<input type="checkbox" name="notification-option" id="client-post"> Cilent's Post<br>
<input type="checkbox" name="notification-option" id="assign-post"> Task Assigned
</form>
function checkAll(ev) {
checkboxes = document.getElementById('notification-options').querySelectorAll("input[type='checkbox']");
if (ev.target.checked === true) {
for (var i = 0; i < checkboxes.length; ++i) {
checkboxes[i].checked = true;
}
} else {
for (var i = 0; i < checkboxes.length; ++i) {
checkboxes[i].checked = false;
}
}
}

Replacing a sub-string in JavaScript innerHTML

I have an HTML page which contains table rows like
<tr id="tp1">
<input type="checkbox" id="tc_">
</tr>
<tr id="tp2">
<input type="checkbox" id="tc_">
</tr>
The page contains input elements other than checkboxes as well
I have to change the values of all checkbox's id from tc_ to tc_1 ,tc_2 and so on.
I have thought of doing it as below
function startup(){
for(var i=0;i<3;i++)
{
var elem=document.getElementById("tp"+i);
var str=elem.innerHTML;
str.replace(/tc_,'tc_'+i); // how do I correctly use the arguments here?
elem.innerHTML=str;
//alert (""+str);
}
}
Thanks.
It isn't valid to have non-unique IDs in the first place. Any chance you can fix how the checkboxes are rendered so you don't have to do this?
That being said, I wouldn't do this by manipulating the HTML attributes. I would instead do this by manipulating the DOM properties of those input checkboxes:
// keep track of the current "new" checkbox ID suffix
var checkBoxIndex = 0;
for (var i = 0; i < 3; i++) {
// find the table row
var elem = document.getElementById("tp" + i);
// get the input elements within that row
var inputs = elem.getElementsByTagName("input");
// for each of the input elements...
for (var j = 0, k = inputs.length; j < k; j++) {
// if it's not a checkbox, skip it
if (inputs[j].type.toLowerCase() !== 'checkbox') {
continue;
}
// Alas, give the checkbox a new, unique ID
inputs[j].id = "tc_" + (checkBoxIndex++);
}
}
Also, hopefully you get an answer for your other question. This is a terrible workaround and I would hate to see it in production code.
The trick here is to select all the input elements of your rows using the appropriate CSS selector, then modify their ids:
function startup() {
for (var i = 0; i < 3;i++) {
var elem = document.getElementById("tp" + i);
var l = elem.querySelectorAll('td > input'); // Select "input"s in "td"s
Array.prototype.forEach.call(l, function (e, j) { // Apply to each element obtained
e.id = 'tc_' + j; // Modify the id
});
}
}
There's several good answers above but if you still want to change the id from tc_ to tc_ + i then you can do it like this.
<body>
<button id="tc_">1</button>
<button id="tc_">2</button>
<button id="tc_">3</button>
<script type="text/javascript">
for(var i=0;i<3;i++)
{
document.getElementById("tc_").id="tc_"+i;
}
</script>
</body>
Honestly though you shouldn't be doing it like this despite the fact this code works as other users have said it isn't valid to have non-unique id's.

Categories