-2

Is there a shorter way (cleaner way really) to do the following code of mine?

if (whichToCheck == 1) {
    if ($('#input_3').val().length) {
        $('#error1').css('display', 'none');
        $('#error1').css('visibility', 'hidden');
        hasErrors = false;
    } else {
        $('#error1').css('display', 'block');
        $('#error1').css('visibility', 'visible');
        hasErrors = true;
    }
}
else if (whichToCheck == 2) {
    if ($('#input_4').val().length) {
        $('#error2').css('display', 'none');
        $('#error2').css('visibility', 'hidden');
        hasErrors = false;
    } else {
        $('#error2').css('display', 'block');
        $('#error2').css('visibility', 'visible');
        hasErrors = true;
    }
}
else if (whichToCheck == 3) {
    if ($('#input_5').val().length) {
        $('#error3').css('display', 'none');
        $('#error3').css('visibility', 'hidden');
        hasErrors = false;
    } else {
        $('#error3').css('display', 'block');
        $('#error3').css('visibility', 'visible');
        hasErrors = true;
    }
}
else if (whichToCheck == 4) {
    if ($('#input_7_0').is(':checked')) {
        $('#error4').css('display', 'none');
        $('#error4').css('visibility', 'hidden');
        hasErrors = false;
    } else {
        $('#error4').css('display', 'block');
        $('#error4').css('visibility', 'visible');
        hasErrors = true;
    }
}
else if (whichToCheck == 5) {
    if ($('#input_6').val().length) {
        $('#error5').css('display', 'none');
        $('#error5').css('visibility', 'hidden');
        hasErrors = false;
    } else {
        $('#error5').css('display', 'block');
        $('#error5').css('visibility', 'visible');
        hasErrors = true;
    }
}

Thanks!

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
StealthRT
  • 10,108
  • 40
  • 183
  • 342

9 Answers9

3

First of all you should use a switch block and store the elements you want to modify in variables. Short version:

var input, error;
switch(whichToCheck){
    case 1:
        input=$('#input_3');
        error=$('#error1');
        break;
    case 2:
        input=$('#input_4');
        error=$('#error2');
        break;
    default:
        ...
        break;
}
var hasErrors = !!input.val().length;
if(hasErrors) error.show(); else error.hide();

Or shorter for the end:

hasErrors&&error.show();
hasErrors||error.hide();
Armel Larcier
  • 15,747
  • 7
  • 68
  • 89
2

A much better way to do these if..then...else statements would be to use a switch statement. Especially when there are multiple values that you are looking for...

switch(whichToCheck){
  case "1":
    // when whichToCheck == 1
  break;
  case "2":
    // when whichToCheck == 2
  break;
  default:
    // when the value of whichToCheck doesn't match any expected value
  break;
}

Another thing you can do to lessen the code you have is to use jQuery's show() and hide() functions to...well... hide and show elements :) You don't really have to explicitly set the display and visibility properties.

Reference -

Lix
  • 47,311
  • 12
  • 103
  • 131
2

You can shorten a lot by selecting the elements dynamically. Also, put them in "cache" variables instead of recreating jQuery instances. And you can use a short form for jQuery's .css() method by passing in an object. Also, you should put those two different styles into variables instead of repeating them - do everything to make the code more DRY.

In a one-liner:

$('#error'+whichToCheck).css( (hasErrors = !$('#input_'+(2+whichToCheck)).val().length)
   ? {display: 'block', visibility: 'visible'}
   : {display: 'none', visibility: 'hidden'}
);

However, your ids seem to be not too regular, so I recommend a mapper as in (the possible duplicate) Alternative to a million IF statements:

var toCheck = document.getElementById( 'input_' + {1:'3', 2:'4', 3:'5', 4:'7_0', 5:'6'}[whichToCheck] ),
    errorEl = $('#error'+whichToCheck);
hasErrors = !(toCheck.type=="checkbox" ? toCheck.checked : toCheck.value);
if (hasErrors)
    errorEl.css({display: 'block', visibility: 'visible'});
else
    errorEl.css({display: 'none', visibility: 'hidden'});

Also, you don't need to set display and visibility, and if you'd use jQuery's .hide()/.show() it would work for non-block-elements, too:

errorEl[hasErrors ? "show" : "hide"]();
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Did you notice the checkbox as well in there? **if ($('#input_7_0').is(':checked')) {** – StealthRT Sep 17 '12 at 13:57
  • Thanks for the hint, I've adapted the code. – Bergi Sep 17 '12 at 14:05
  • New code does not seem to work now for the input boxes. Keeps saying true when theres nothing in the boxes. – StealthRT Sep 17 '12 at 14:14
  • Isn't it supposed to set `hasErrors=true` if the value is the empty string (== has no length)? – Bergi Sep 17 '12 at 14:43
  • Still has it as fine without having anything in the boxes. Your original code **hasErrors = !toCheck.val().length;** did just find for the boxes but not for the checkbox. – StealthRT Sep 17 '12 at 15:49
  • Um, did you change the jQuery-`$` to `document.getElementById`? Code for jQuery-elements would be like `$toCheck.is(":checkbox") ? $toCheck.prop("checked") : $toCheck.val()` – Bergi Sep 17 '12 at 16:14
  • I copied just like you had it above in your code. – StealthRT Sep 17 '12 at 16:29
1

This one is better to set CSS:

$('#error1').css({'display': 'none', 'visibility': 'hidden'});
keaukraine
  • 5,315
  • 29
  • 54
1

For starters, you could create css classes and use the addClass function in jQuery

Examaple:

CSS

.hide{
  display: none;
  visibility: hidden;
}

jQuery

$('#error1').addClass("hide");
Chase
  • 29,019
  • 1
  • 49
  • 48
  • I've thought about doing that but still just wanted to use just one CSS class. – StealthRT Sep 17 '12 at 14:19
  • You could use `hide` class and set it when appropriate, and instead of having a new class you could use the `removeClass` function that jQuery also offers. – Chase Sep 17 '12 at 14:28
1

As you wrote your code

 $('#error3').css('display', 'block');
 $('#error3').css('visibility', 'visible');

Repeats at several places for style change. Can you make it into a function such that you pass the error field name.

For #error3 you pass the param as 3, then the display and visibility params.

Thanks

Bojangles
  • 99,427
  • 50
  • 170
  • 208
Abhi
  • 6,471
  • 6
  • 40
  • 57
1

You could generate the ids based on the value of whichToCheck and use jQuery's hide method to hide the elements:

function toggleErrors($input, whichToCheck){
  if($input.val() !== '' || $input.is(':checked')){
    $('#error' + whichToCheck).hide();
  }else{
    $('#error' + whichToCheck).show();
  }
}

Pass in whichToCheck and the corresponding input element to the function.

Jørgen
  • 8,820
  • 9
  • 47
  • 67
  • This is correct but i also have a checkbox value in this as well. – StealthRT Sep 17 '12 at 14:20
  • I added the checked condition which is a bit of a hack. However, I'd encourage you to use relations in order to connect the inputs and error elements if possible. – Jørgen Sep 17 '12 at 14:23
  • What does **input** represent? should it be **this.value**? – StealthRT Sep 17 '12 at 14:27
  • You need to pass in the input to the function. If it is invoked from an event handler, you could use this.value. – Jørgen Sep 17 '12 at 14:30
  • You'll need to find the value of input using a switch like the other answers suggests, unless you can find a connection between inputs and errors other ways...such as DOM relations, but I can't help you with that as I don't know how your mark up looks like. – Jørgen Sep 17 '12 at 14:34
1
  1. Use Switch() statements as mentioned By Armel.
  2. Extract Show() & Hide() methods separately.

Here is the sample:

if (whichToCheck == 1) {
        if ($('#input_3').val().length) {
            Show('#error1');
            hasErrors = false;
        } else {
            Hide('#error1');
            hasErrors = true;
        }
    } else if (whichToCheck == 2) {
        if ($('#input_4').val().length) {
            Show('#error2');
            hasErrors = false;
        } else {
            Hide('#error2');
            hasErrors = true;
        }
    } else if (whichToCheck == 3) {
        if ($('#input_5').val().length) {
            Show('#error3');
            hasErrors = false;
        } else {
            Hide('#error3');
            hasErrors = true;
        }
    } else if (whichToCheck == 4) {
        if ($('#input_7_0').is(':checked')) {
            Show('#error4');
            hasErrors = false;
        } else {
            Hide('#error4');
            hasErrors = true;
        }
    } else if (whichToCheck == 5) {
        if ($('#input_6').val().length) {
            Show('#error5');
            hasErrors = false;
        } else {
            Hide('#error5');
            hasErrors = true;
        }
    }

    function Show(id) {

        $(id).show();

    }

    function Hide(id) {
        $(id).hide();
    }
Dhanasekar Murugesan
  • 3,141
  • 1
  • 18
  • 21
  • So why then did you not implement the switch? – Lix Sep 17 '12 at 13:55
  • Here, I have mentioned to use Switch assuming that the person knows how to use. So, I didin explain howto use Switch. But I wanted to point out to move some sphagetti coding for Hide & Show to separate methods to take care of them. It was the context in my explanation and not 'use of Switch'. – Dhanasekar Murugesan Sep 20 '12 at 05:54
1

The key to shortening your code seems to be the source of the whichToCheck variable. Alternatively you can do this:

//...
if ( $('#input_' + whichToCheck).val().length ) {
    $('#error_' + whichToCheck).css ( { 'display' : 'none', 'visibility' : 'hidden' } );
} else {
    $('#error_' + whichToCheck).css ( { 'display' : 'block', 'visibility' : 'visible' } );        
}
wroniasty
  • 7,884
  • 2
  • 32
  • 24