Learn Jquery: style methods not working

Can someone please explain what is wrong with the code, whenever I add a function that targets .preview the textarea gets disabled (stops working). It works to type if i just has the first keyup function, but not if I add another.

https://www.codecademy.com/paths/web-development/tracks/learn-jquery/modules/learn-jquery-style-methods/projects/font-preview

$(document).ready(() => {
  $('#text').on('keyup', (event) => {
    $('.preview').html($(event.currentTarget).val());
})
  
 $('#font').on('change', (event) => {
    $('.preview').css({
      fontFamily: $(event.currentTarget).val();
    })
  })
 
   $('#weight').on('change', (event) => {
    $('.preview').css({
     fontWeight: $(event.currentTarget).val();
    })
   })
 
  $('#size').on('keyup', (event) => {
    let fontSize = $(event.currentTarget).val() + 'px';
    $('.preview').css({
      fontSize: fontSize;
    })
  })
  
});

I plugged that into my code and it worked as expected. Your code looks alright. Not sure what the problem is.

If i remove the font, weigth and size functions the textarea works, but if i add the functions the textarea doesnt work, it doesnt update and the input only shows in the textarea and not in the preview. Which mans it doesn’t work to select fonts and size and weight cause it doesn’t have something to select and use it on.

I just noticed that your properties are not in quotes.

$('#font').on('change', (event) => {
  let fontFamily = $(event.currentTarget).val();
  $('.preview').css({'font-family': fontFamily});
});

Update

Just spotted the issue…

fontFamily: $(event.currentTarget).val(); <<< semi-colon inside an object.

Got this to work once the semi-colon was removed.

$('#font').on('change', (event) => {
    $('.preview').css({
      fontFamily: $(event.currentTarget).val()
    })
})

Addendum

Thanks to this question I was forced to re-learn about JS property names. It’s not something I normally use so things get forgotten when you’re my age. JS names do not need quotes. Only CSS names do. The above confirms it, and a revamp of my original code made reading it even more clear.

Like you, I also used objects in my .css() methods, but since it is a single property, we may revert to the basic syntax and expect the same outcome. Note that JS names are not permitted.

    $('.preview').css('font-family', $(event.currentTarget).val())

I only bring this up so it is out there, not as a specific recommendation, or even suggestion.

In the end I reduced my code to a group of callback functions and a jQuery wrapper around the event listeners.

const changeText = event => {
  $('.preview').text($(event.currentTarget).val());
};
const changeFont = event => {
  $('.preview').css('font-family', $(event.currentTarget).val());
};
const changeWeight = event => {
  $('.preview').css('font-weight', $(event.currentTarget).val());
};
const changeSize = event => {
  $('.preview').css('font-size', $(event.currentTarget).val() + 'px');
};
$(() => {
  $('#text').on('keyup', changeText);
  $('#font').on('change', changeFont);
  $('#weight').on('change', changeWeight);
  $('#size').on('keyup', changeSize);
});

This should make evident to you that we do not need to write our functions in the wrapper. Again, not to make a point. They might be better in the wrapper so they are not polluting the global namespace. We see from this, especially, that jQuery works no matter where we call it from, as long as it is loaded.

The flip side of this is that the handlers didn’t need to be written in jQuery. We could have written in vanilla JS with the same effect. Mind, this is a jQuery project. Let’s get back to that…

$(() => {
  const chgText = e => $p.text($(e.currentTarget).val());
  const chgFont = e => $p.css('font-family', $(e.currentTarget).val());
  const chgWeight = e => $p.css('font-weight', $(e.currentTarget).val());
  const chgSize = e => $p.css('font-size', $(e.currentTarget).val()+'px');
  $p = $('.preview');    // cached node
  $('#text').on('keyup', chgText);
  $('#font').on('change', chgFont);
  $('#weight').on('change', chgWeight);
  $('#size').on('keyup', chgSize);
});

Note the cached node. This way we don’t have to keep querying it. We have it in memory.

The $ is of no real significance except to tell the reader that p is a jQuery object, with all the attributes and methods expected of a jQuery object, hence,

$p.css()

and,

$p.text()

Both of those are jQuery methods that our $p instance inherits from jQuery.

Thank you so much, now the code works perfectly!

1 Like