I have an ObjectHtmlInputElement:
for($array as $a){
echo '<input type="checkbox" name="check[]" value="'.$a.'">';
}
Javascript:
function myForm(){
var theForm=document.getElementById("myCheck");
var a = theForm.elements['check[]'];
for( var i=0; i<a.length; i++){
if(a[i].checked){
alert( a[i].value );
return true;
}
}
}
This script checks if atleast one checkbox is checked then return true(there can also be more checkboxeses checked).What i need is to output in the alert() , each checkbox that have been checked(each object value that passes 'a[i].checked'). a[i].value , outputs only the first value, so i need something else.
Based on 'dec' and 'vijay' s answer i managed to find a solution:
var checkedCheckboxes="";
for( var i=0; i<a.length; i++){
if(a[i].checked){
checkedCheckboxes += a[i].value;
}
}
for( var i=0; i<a.length; i++){
if(a[i].checked){
alert('Checked: ' + checkedCheckboxes);
return true;
}
}
Indeed the loop was stopped because of return true as dec said.And the solution was to make another loop,and insert all values in a variable so i can use it in the alert.
The first value seems to match a[i].checked and then you return and no other element is tested. So remove return true.
Try this:
function myForm() {
var theForm = document.getElementById("myCheck");
var a = theForm.elements['check[]'];
var checkedCheckboxes = "";
for (var i = 0; i < a.length; i++) {
if (a[i].checked) {
checkedCheckboxes += a[i].value + ", ";
}
}
if (checkedCheckboxes.length > 0) alert(checkedCheckboxes);
return checkedCheckboxes.length > 0;
}
http://jsfiddle.net/p5upLprk/1/
with jquery you can do:
function isThereAtLeastOneCheckActive() {
var res = false
$(':checkbox').each(function() {
if (this.checked) {
res = true
alert(this.val())
// .text() can also be used
}
})
return res
}
As you are beggining, maybe you find strange the absense of ;
There is no need for them in js: https://mislav.net/2010/05/semicolons/
Related
Here is the code I am trying to remove the redundant code and move the code to separate function.
//Adding Infotypes to filter and checks whether any infotype option is selected
if(this.$infoOptions.val() != null){
var infotypelength = this.$infoOptions.val().length;
var l=0,j;
//Condition to check empty input type
if( infotypelength > 0){
var infotypeList = this.$infoOptions.val();
for(j = 0; j < infotypelength; j++) {
//It checks whether already option is selected and prevents adding to filter if its duplicate.
if(($.inArray( $('#infoOptions').select2('data')[j].text, filterList)) == -1 ){
this.filter.push($('#infoOptions').select2('data')[j].text);
if(infotypeList[j].contains('_subgroup')){
var res = infotypeList[j].split("_");
this.aSubinfotype[l]=res[0];
l=l+1;
}
else
this.aInfotypes.push(infotypeList[j]);
}
}
}
}
//Adding Countries to filter
if(this.$countryOptions.val() != null){
var geoLength = this.$countryOptions.val().length;
//Condition to check empty input type
if( geoLength > 0){
var geoList = this.$countryOptions.val();
var l=0;
for(var j = 0; j < geoLength; j++) {
if(($.inArray( $('#countryOptions').select2('data')[j].text, filterList)) == -1 ){
this.filter.push($('#countryOptions').select2('data')[j].text);
if(geoList[j].contains('_subgroup')){
var res = geoList[j].split("_");
this.aSubgeotype[l]=res[0];
l=l+1;
}
else
this.aGeography.push(geoList[j]);
}
}
}
}
But I am facing problem in passing the variable and cached selectors in to other function. Can anyone help me with this?
I don't know how is done your implementation but I really think that you can improve it, by the way, you can reduce your code in two way bit different :
var myFunction = function(option, filter, array, selector, subType) {
if(option && option.val()){
var optList = option.val();
var optLength = optList.length;
//Condition to check empty input type
if( optLength > 0) {
var l = 0;
for(var j = 0; j < optLength; j++) {
if( ($.inArray( selector.select2('data')[j].text, filterList)) == -1 ){
filter.push(selector.select2('data')[j].text);
if(optList[j].contains('_subgroup')){
var res = optList[j].split("_");
subType[l]=res[0];
l=l+1;
} else {
array.push(optList[j]);
}
}
}
}
}
}
call : myFunction(this.$countryOptions, this.filter, this.aGeography, $('#countryOptions'), this.aSubgeotype)
// data = {option, filter, array, selector, subType}
var myFunction = function(data) {
if(data.option && data.option.val()){
var optList = data.option.val();
var optLength = optList.length;
//Condition to check empty input type
if( optLength > 0) {
var l = 0;
for(var j = 0; j < optLength; j++) {
if( ($.inArray( data.selector.select2('data')[j].text, filterList)) == -1 ){
data.filter.push(data.selector.select2('data')[j].text);
if(optList[j].contains('_subgroup')){
var res = optList[j].split("_");
data.subType[l]=res[0];
l=l+1;
} else {
data.array.push(optList[j]);
}
}
}
}
}
}
call :
myFunction({
option: this.$countryOptions,
filter: this.filter,
array: this.aGeography,
selector: $('#countryOptions'),
subType: this.aSubgeotype
});
or
var data = {
option: this.$countryOptions,
filter: this.filter,
array: this.aGeography,
selector: $('#countryOptions'),
subType: this.aSubgeotype
}
myFunction(data);
The first way is to pass your data one by one, the second you pass your data into an json object.
I am having troubles trying to check if the date exists in the array.
for(var i = 0; i< crisislist.length; i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}
The sample data for the date is:
["01-02-2017", "22-03-2017", "22-03-2017", "07-08-2017"]
And the expected output for hazelabel, hazedata should be:
hazelabel: ["01-02-2017", "22-03-2017", "07-08-2017"]
hazedata: [1,2,1]
With the code above, when I check until the last element in the array and trying to make a comparison, it throw me an error message:
Uncaught TypeError: Cannot read property 'date' of undefined
I think this is because when I reach the last element of array, and I try to find crisislist[I+1].date, it could not found and thus the error message.
Any idea how to fix this? Thanks in advance!
You must access crisislist[i+1].date only when i doesn't point to the last element.
Also notice that to get the desired result, you need to move the hazedata.push inside the if block and put the initialisation of hazecounter in front of the loop.
var hazecounter = 1;
for (var i = 0; i< crisislist.length; i++) {
if (crisislist[i].category == 1) {
if (i == crisislist.length-1 || crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
hazedata.push(hazecounter);
hazeCounter = 1;
} else {
hazecounter++;
}
}
}
Your if statement is going to be a problem.
if(crisislist[i].date != crisislist[i+1].date) {
You are accessing crisislist[i+1] in a loop that goes to < crisislist.length. That means that if you have an array of size 4, your loop will go until i = 3, but you are accessing i+1 from the array (crisislist[4]), which will be undefined.
Try changing your for loop to go to crisis.length-1
You just need to check till second last :
for(var i = 0; i< (crisislist.length-1); i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
if (crisislist.length-2 == i)
{
hazelabel.push(crisislist[i+1].date);
}
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}
Check that code. If you have any questions, add a comment :) In my solution dates dont have to be sorted.
</head>
<BODY>
<script>
function Something(date)
{
this.date = date;
this.category = 1;
}
var crisislist = [];
var hazelabel = [];
var hazedata = [];
crisislist[0] = new Something("01-02-2017");
crisislist[1] = new Something("22-03-2017");
crisislist[2] = new Something("22-03-2017");
crisislist[3] = new Something("07-08-2017");
for(var i = 0; i< crisislist.length; i++){
if(crisislist[i].category == 1)
{
if(!hazelabel[crisislist[i].date])
{
hazelabel[crisislist[i].date] = crisislist[i].date;
hazedata[crisislist[i].date] = 1;
}
else
{
hazedata[crisislist[i].date]++;
}
}
}
for(var key in hazelabel)
{
console.log(hazelabel[key]);
console.log(hazedata[key]);
}
</script>
</BODY>
</HTML>
I have an array of 10 checkboxes. onclick of checkbox i want to get the value of that particular checkbox. That I am able to achieve using my code.When I click in serial order it is working fine. When I click on checkbox 5 after clicking on checkbox 7 the value of checkbox 5 ie..5 is getting added befor 7. I dont want in that order. I want the values to displayed in whatever order I click. My js file is as follows
var selected = new Array();
$(document).ready(function(){
checkBoxTest();
});
function checkBoxTest() {
alert("checkbox test");
for(i = 0; i < 10; i++){
$("#catalog_table").append('<tr><td>Checkbox<input type="checkbox" name ="chkbox" value="' +i+' "/><td></tr>');
test();
}
}
function test() {
$('#catalog_table input:checkbox').change(function() {
var emails = [];
$('#catalog_table input:checkbox:checked').each(function() {
emails.push($(this).val());
});
var textField = document.getElementById("root");
textField.value = emails;
});
}
My HTML code is something like this
<table id="catalog_table"> </table>
<textarea id="root"></textarea>
Can any one please tell me how to do this?
Demo
Its messy, but it works:
http://jsfiddle.net/za7m8/1/
var selected = new Array();
$(document).ready(function(){
$("input[type='checkbox']").on('change', function() {
// check if we are adding, or removing a selected item
if ($(this).is(":checked")) {
selected.push($(this).val());
} else {
for(var i = 0; i<selected.length;i++) {
if (selected[i] == $(this).val()) {
// remove the item from the array
selected.splice(i, 1);
}
}
}
// output selected
var output = "";
for (var o = 0; o<selected.length; o++) {
if (output.length) {
output += ", " + selected[o];
} else {
output += selected[o];
}
}
$("#root").val(output);
});
});
You just have to change your javascript like this.
var selected = new Array();
$(document).ready(function(){
checkBoxTest();
});
function checkBoxTest() {
alert("checkbox test");
for(i = 0; i < 10; i++){
$("#catalog_table").append('<tr><td>Checkbox<input type="checkbox" name ="chkbox" value="' +i+' "/><td></tr>');
test();
}
}
var emails = [];
function test() {
$('#catalog_table input:checkbox').change(function() {
if (this.checked)
{
if ( emails.indexOf( $(this).val() ) === -1 )
{
emails.push($(this).val());
}
} else
{
if ( emails.indexOf( $(this).val() ) !== -1 )
{
var index = emails.indexOf( $(this).val() );
emails.splice(index, 1);
}
}
var textField = document.getElementById("root");
textField.value = emails;
});
}
You need to clear up your code a bit, like this:
I assume that unchecking removes the value from the array, and checking adds.
var selected = new Array(); // What for is this here ?
$(document).ready(function () {
checkBoxTest();
});
function checkBoxTest() {
for (i = 0; i < 10; i++) {
$("#catalog_table").append('<tr><td>Checkbox<input type="checkbox" name ="chkbox" value="' + i + ' "/><td></tr>');
}
test();
}
function test() {
var emails = [],
textField = document.getElementById("root");
$('#catalog_table input:checkbox').change(function () {
var val = $(this).val();
// if you don't want removal of values on `uncheck`, comment out everything below excluding `emails.push(val)` and the last line
if(this.checked){ // if checked
emails.push(val); // add it
}else{
emails.splice(emails.indexOf(val), 1); // remove it if not checked
}
textField.value = emails; // set the value
});
}
DEMO
I thought this would be easier, but running into a weird issue.
I want to split the following:
theList = 'firstword:subwordone;subwordtwo;subwordthree;secondword:subwordone;thirdword:subwordone;subwordtwo;';
and have the output be
firstword
subwordone
subwordtwo
subwordthree
secondword
subwordone
thirdword
subwordone
subwordtwo
The caveat is sometimes the list can be
theList = 'subwordone;subwordtwo;subwordthree;subwordfour;'
ie no ':' substrings to print out, and that would look like just
subwordone
subwordtwo
subwordthree
subwordfour
I have tried variations of the following base function, trying recursion, but either get into infinite loops, or undefined output.
function getUl(theList, splitOn){
var r = '<ul>';
var items = theList.split(splitOn);
for(var li in items){
r += ('<li>'+items[li]+'</li>');
}
r += '</ul>';
return r;
}
The above function is just my starting point and obviously doesnt work, just wanted to show what path I am going down, and to be shown the correct path, if this is totally off base.
It seems you need two cases, and the difference between the two is whether there is a : in your string.
if(theList.indexOf(':') == -1){
//Handle the no sublist case
} else {
//Handle the sublist case
}
Starting with the no sublist case, we develop the simple pattern:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
//Add your element to your list
}
Finally, we apply that same pattern to come up with the implementation for the sublist case:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(element.indexOf(':') == -1){
//Add your simple element to your list
} else {
var innerElements = element.split(':');
//Add innerElements[0] as your parent element
//Add innerElements[1] as your child element
//Increment i until you hit another element with ':', adding the single elements each increment as child elements.
//Decrement i so it considers the element with the ':' as a parent element.
}
}
Keep track of the current list to add items to, and create a new list when you find a colon in an item:
var baseParent = $('ul'), parent = baseParent;
$.each(theList.split(';'), function(i, e) {
if (e.length) {
var p = e.split(':');
if (p.length > 1) {
baseParent.append($('<li>').append($('<span>').text(p[0])).append(parent = $('<ul>')));
}
parent.append($('<li>').text(p[p.length - 1]));
}
});
Demo: http://jsfiddle.net/Guffa/eWQpR/
Demo for "1;2;3;4;": http://jsfiddle.net/Guffa/eWQpR/2/
There's probably a more elegant solution but this does the trick. (See edit below)
function showLists(text) {
// Build the lists
var lists = {'': []};
for(var i = 0, listKey = ''; i < text.length; i += 2) {
if(text[i + 1] == ':') {
listKey = text[i];
lists[listKey] = [];
} else {
lists[listKey].push(text[i]);
}
}
// Show the lists
for(var listName in lists) {
if(listName) console.log(listName);
for(var j in lists[listName]) {
console.log((listName ? ' ' : '') + lists[listName][j]);
}
}
}
EDIT
Another interesting approach you could take would be to start by breaking it up into sections (assuming text equals one of the examples you gave):
var lists = text.match(/([\w]:)?([\w];)+/g);
Then you have broken down the problem into simpler segments
for(var i = 0; i < lists.length; i++) {
var listParts = lists[i].split(':');
if(listParts.length == 1) {
console.log(listParts[0].split(';').join("\n"));
} else {
console.log(listParts[0]);
console.log(' ' + listParts[1].split(';').join("\n "));
}
}
The following snippet displays the list depending on your requirements
var str = 'subwordone;subwordtwo;subwordthree;';
var a = []; var arr = [];
a = str;
var final = [];
function split_string(a){
var no_colon = true;
for(var i = 0; i < a.length; i++){
if(a[i] == ':'){
no_colon = false;
var temp;
var index = a[i-1];
var rest = a.substring(i+1);
final[index] = split_string(rest);
return a.substring(0, i-2);
}
}
if(no_colon) return a;
}
function display_list(element, index, array) {
$('#results ul').append('<li>'+element+'</li>');
}
var no_colon_string = split_string(a).split(';');
if(no_colon_string){
$('#results').append('<ul><ul>');
}
no_colon_string.forEach(display_list);
console.log(final);
working fiddle here
I am having issues figuring out how to resolve the getElementsByClassName issue in IE. How would I best implement the robert nyman (can't post the link to it since my rep is only 1) resolution into my code? Or would a jquery resolution be better? my code is
function showDesc(name) {
var e = document.getElementById(name);
//Get a list of elements that have a class name of service selected
var list = document.getElementsByClassName("description show");
//Loop through those items
for (var i = 0; i < list.length; ++i) {
//Reset all class names to description
list[i].className = "description";
}
if (e.className == "description"){
//Set the css class for the clicked element
e.className += " show";
}
else{
if (e.className == "description show"){
return;
}
}}
and I am using it on this page dev.msmnet.com/services/practice-management to show/hide the description for each service (works in Chrome and FF). Any tips would be greatly appreciated.
I was curious to see what a jQuery version of your function would look like, so I came up with this:
function showDesc(name) {
var e = $("#" + name);
$(".description.show").removeClass("show");
if(e.attr("class") == "description") {
e.addClass("show");
} else if(e.hasClass("description") && e.hasClass("show")) {
return;
}
}
This should support multiple classes.
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) {
matching.push(elements[i]);
}
}
return matching;
}
You can pass in a parent too, to make its searching the DOM a bit faster.
If you want getElementsByClassName('a c') to match HTML <div class="a b c" /> then try changing it like so...
var elementClasses = elements[i].className.split(/\s+/),
matchClasses = findClass.split(/\s+/), // Do this out of the loop :)
found = 0;
for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) {
if (matchClasses.indexOf(elementClasses[j]) > -1) {
found++;
}
}
if (found == matchClasses.length) {
// Push onto matching array
}
If you want this function to only be available if it doesn't already exist, wrap its definition with
if (typeof document.getElementsByClassName != 'function') { }
Even easier jQuery solution:
$('.service').click( function() {
var id = "#" + $(this).attr('id') + 'rt';
$('.description').not(id).hide();
$( id ).show();
}
Why bother with a show class if you are using jQuery?
Heres one I put together, reliable and possibly the fastest. Should work in any situation.
function $class(className) {
var children = document.getElementsByTagName('*') || document.all;
var i = children.length, e = [];
while (i--) {
var classNames = children[i].className.split(' ');
var j = classNames.length;
while (j--) {
if (classNames[j] == className) {
e.push(children[i]);
break;
}
}
}
return e;
}
I used to implement HTMLElement.getElementByClassName(), but at least Firefox and Chrome, only find the half of the elements when those elements are a lot, instead I use something like (actually it is a larger function):
getElmByClass(clm, parent){
// clm: Array of classes
if(typeof clm == "string"){ clm = [clm] }
var i, m = [], bcl, re, rm;
if (document.evaluate) { // Non MSIE browsers
v = "";
for(i=0; i < clm.length; i++){
v += "[contains(concat(' ', #"+clc+", ' '), ' " + base[i] + " ')]";
}
c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null);
while ((node = c.iterateNext())) {
m.push(node);
}
}else{ // MSIE which doesn't understand XPATH
v = elm.getElementsByTagName('*');
bcl = "";
for(i=0; i < clm.length; i++){
bcl += (i)? "|":"";
bcl += "\\b"+clm[i]+"\\b";
}
re = new RegExp(bcl, "gi");
for(i = 0; i < v.length; i++){
if(v.className){
rm = v[i].className.match(bcl);
if(rm && rm.length){ // sometimes .match returns an empty array so you cannot use just 'if(rm)'
m.push(v[i])
}
}
}
}
return m;
}
I think there would be a faster way to iterate without XPATH, because RegExp are slow (perhaps a function with .indexOf, it shuld be tested), but it is working well
You can replace getElementsByClassName() with the following:
function getbyclass(n){
var elements = document.getElementsByTagName("*");
var result = [];
for(z=0;z<elements.length;z++){
if(elements[z].getAttribute("class") == n){
result.push(elements[z]);
}
}
return result;
}
Then you can use it like this:
getbyclass("description") // Instead of document.getElementsByClassName("description")