0

After pulling my hair out trying to make a jQuery/CSS-calc scenario get the width of a element to equal a specific numerical value (32px) multiplied by the value of an input[type="number"] field, I eventually gave up. I kept running into trouble storing the element's width in a variable & using the correct syntax inside the calc declaration.

I eventually accomplished what I set out to do by hard-coding the CSS width values in conditional statements corresponding to each value from 1-4. Though I got it to work, it is definitely inefficient & dirty. I am hoping someone can show me some more efficient alternatives that accomplish the same result using calc or something else requiring much less code.

So to sum up - when the quantity is 1, the width of the target element span#dogFace is 32px. When the quantity is 2, the width of the target element is 64px, and so on. If you try to increase it to 5, a text warning appears.

Here is the example I posted

Any advice appreciated!

Bonus Points: I initially tried to find a CSS-only solution, which I think still must be possible, but I couldn't make it work. If anyone knows how to accomplish this with some fancy CSS, I'd love to learn how that'd work as well.

$('#input_5_78').on('change', function() {
    if (this.value >= 5) {
      $('#dogFace').hide();
      $('#xtraDog').show();
    } else {
      $('#dogFace').show();
      $('#xtraDog').show();
    }

    if (this.value == 0) {
      $('#dogFace').width('0');
      $('#xtraDog').hide();
    } else if (this.value == 1) {
      $('#xtraDog').hide();
      $('#dogFace').width('32px');
    } else if (this.value == 2) {
      $('#dogFace').width('64px');
      $('#xtraDog').hide();
    } else if (this.value == 3) {
      $('#dogFace').width('96px');
      $('#xtraDog').hide();
    } else if (this.value == 4) {
      $('#dogFace').width('128px');
      $('#xtraDog').hide();
    }
})
.emoji {
  height: 32px;
  background-position: left top;
  background-repeat: repeat-x;
  background-size: contain;
  display: inline-block;
  vertical-align: top;
}

.emoji.dog {
  background-image: url('https://afeld.github.io/emoji-css/emoji/dog.png');
}

#dogFace {
  float: left;
}

#xtraDog {
  display: none;
}

ul li.qtyField {
  list-style-type: none;
}

.qtyField label {
  float: left;
}

.qtyField input[type="number"] {
  float: left;
  font-weight: bold;
  font-size: 1.15em;
  margin: 0 0 0 15px;
  width: 45px!important;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <ul>
    <li class="qtyField">
      <label class="gfield_label" for="input_5_78">How many dogs need training?</label>
      <div class="ginput_container ginput_container_number">
        <input name="input_78" id="input_5_78" step="any" min="0" max="5" value="0" type="number">
      </div>
      <div class="gfield_description">
        <span id="dogFace" class="emoji dog"></span>
        <span id="xtraDog"><br><br>Woah, that's a lot of dogs!<br />Please call (480) 555-1234 to discuss your training needs.</span>
      </div>
    </li>
  </ul>
</form>

1
  • Oooooh there's an if/else mess in your code. Your logic can be simply boiled down to: $('#dogFace').width(32 * this.value); Commented Jun 25, 2017 at 20:51

2 Answers 2

1

Probably not possible using only CSS, but that would be awesome. Here's a variation of your attempt that DRYs up the code a bit and makes it easier to understand.

$('#input_5_78').on('change', function() {
  if (this.value < 5) {
    $('#xtraDog').hide();
    $('#dogFace').width(this.value * 32 + 'px');
  } else {
    $('#dogFace').width('0');
    $('#xtraDog').show();
  }
})
.emoji {
  height: 32px;
  background-position: left top;
  background-repeat: repeat-x;
  background-size: contain;
  display: inline-block;
  vertical-align: top;
}

.emoji.dog {
  background-image: url('https://afeld.github.io/emoji-css/emoji/dog.png');
}

#dogFace {
  float: left;
}

#xtraDog {
  display: none;
}

ul li.qtyField {
  list-style-type: none;
}

.qtyField label {
  float: left;
}

.qtyField input[type="number"] {
  float: left;
  font-weight: bold;
  font-size: 1.15em;
  margin: 0 0 0 15px;
  width: 45px!important;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <ul>
    <li class="qtyField">
      <label class="gfield_label" for="input_5_78">How many dogs need training?</label>
      <div class="ginput_container ginput_container_number">
        <input name="input_78" id="input_5_78" step="any" min="0" max="5" value="0" type="number">
      </div>
      <div class="gfield_description">
        <span id="dogFace" class="emoji dog"></span>
        <span id="xtraDog"><br><br>Woah, that's a lot of dogs!<br />Please call (480) 555-1234 to discuss your training needs.</span>
      </div>
    </li>
  </ul>
</form>

Sign up to request clarification or add additional context in comments.

1 Comment

The code is formatted like that because I very quickly and sloppily sliced bits & pieces out of my wordpress site to get it to work on the W3C fiddle-thing after way too many hours staring at the screen. I just couldn’t get the syntax to work unless I used those icky conditionals. Anyway, thanks for taking the time to help!
0

I went a slightly different way with my answer. A couple of pointers and comments explaining the javascript included in the code snippet;

  • You want to get into to habit of writing functions to run repeatable code.
  • Indent your code and comment it for future reference and readability
  • Indent your CSS again to make it human readable, it will also help people assist you with future answers

JS Bin here: http://jsbin.com/vunajej/edit?html,css,js,output

Snippets here:

  var validate_num_dogs = function ( e ) { // Declare function with variable e for element ;)
      
      $( '#xtraDog' ).hide(); // Hide warning msg each time the function is called
        
        // For simple conditionals it's not required to use braces {}
        if ( e.val() >= 5 ) // If elements value is greater than or == to 5 (max)
          $( '#xtraDog' ).show(); // Display warning msg
    
        else
          $( '#dogFace' ).width( 32 * e.val() ); // Width value is simply 32px multiplied by input value
    
      };


jQuery( document ).ready( function( $ ) {
  
  $( '#input_5_78' ).on( 'change', function(){
      
    validate_num_dogs( $(this) ); // Call function, $(this) is the current element e.g. #input_5_78

  });
                        
});
.emoji {
  height:32px; 
  background-position:left top;
  background-repeat:repeat-x;
  background-size:contain;
  display:inline-block;
  vertical-align:top;
}

.emoji.dog {
  background-image:url('https://afeld.github.io/emoji-css/emoji/dog.png');
}

#dogFace {
  float: left;
}

#xtraDog {
  display: none;
}

ul li.qtyField {
  list-style-type: none;
}

.qtyField label {
  float: left;
}

.qtyField input[type="number"] {
  float: left;
  font-weight: bold;
  font-size: 1.15em;
  margin: 0 0 0 15px;
  width: 45px!important;
  text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>

<form>
<ul>
	<li class="qtyField">
		<label class="gfield_label" for="input_5_78">How many dogs need training?</label>
		<div class="ginput_container ginput_container_number">
			<input name="input_78" id="input_5_78" step="any" min="0" max="5" value="0" type="number">
		</div>
		<div class="gfield_description">
			<span id="dogFace" class="emoji dog"></span>
			<span id="xtraDog"><br><br>Woah, that's a lot of dogs!<br />Please call (480) 555-1234 to discuss your training needs.</span>
		</div>
	</li>
</ul>
</form>

</body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.