How To jQuery JavaScript conditional statement (beginner) - javascript

Apologies if this is an overly simple question, but my searches are getting me nowhere.
I have a jQuery function which produces an error on some of my pages which do not contain the #message input:
Error: jQuery("#message").val() is undefined
Line: 56
And my jQuery function:
function updateCountdown()
{
var $left = 255 - jQuery( '#message' ).val().length;
jQuery( '#countdown' ).text( $left + ' Characters Remaining' );
}
$( document ).ready( function()
{
updateCountdown();
$( '#message' ).change( updateCountdown );
$( '#message' ).keyup( updateCountdown );
});
So my question is, how do I use a conditional to remove the error message from pages without the #message input? I believe my problem is a basic lack of knowledge of how JavaScript works.

I wouldn't bother to perform an explicit test on the jQuery object returned from the selector — let jQuery do that for you!
$(function() {
$('#message').each(function() {
var $self = $(this);
$self.bind('change keyup', function updateCountdown() {
$('#countdown').text((255 - $self.val().length)) + ' characters remaining');
});
});
});
If '#message' doesn't match anything, then the .each( ... ) call won't do anything.

The only problem is with your init code.. after that it'll run fine. So do:
$( document ).ready( function()
{
$( '#message' ).change( updateCountdown ).keyup( updateCountdown ).keyup();
});
Note the use of chaining.

Improve your selector to ensure that it's actually getting an input element (so that there is a value). Then check to see if your selector actually matched anything before working with it. Note that the length of the jQuery object returned is the number of matching elements (it must be greater than 0). Oh, and you can consistently use the $ function as long as there aren't any conflicts with other javascript frameworks.
function updateCountdown()
{
var msg = $('input#message');
if (msg.length > 0) {
var $left = 255 - msg.val().length;
$( '#countdown' ).text( $left + ' Characters Remaining' );
}
}

You just need to check if the jQuery object contains any items. I would do it like this.
$( document ).ready( function()
{
var $message = jQuery( '#message' );
if($message.length > 0) {
updateCountdown();
$( '#message' ).change( updateCountdown );
$( '#message' ).keyup( updateCountdown );
}
});
Then I'd change your updateCountdown() function to use the this keyword rather than doing another jQuery lookup. jQuery sets this to be the DOM element the event occurred on.
function updateCountdown()
{
var $left = 255 - jQuery( this ).val().length;
jQuery( '#countdown' ).text( $left + ' Characters Remaining' );
}

Related

JS YouTube Regex With Empty input acceptable

I have a youtube input for the embedding code and I wish to be able to also have the user not necessarily have to input a youtube embed. But I'm stuck about how to alter my regex to accept an empty field... I have set errors if the user fails the regex and no errors if the user passes the regex, So I would imagine there would be a simple fix to the regex to accept an empty input value.
Can anybody see how I would achieve this from my code below...
Thank you for any advice.
function checkyoutube() {
var youtube = $("#youtubevalue").val();
//var youtubeReg =/^[a-zA-Z][a-zA-Z0-9-+&%#=?<>()£~_\.*#$!, \r\n]{0,300}$/;
var youtubeReg =/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((.|-){11})(?:\S+)?$/;
if(!youtubeReg.test(youtube)) { localStorage.setItem('error', 'true');
$("#youtubefooter").text("Example https://youtu.be/12KxXnFbwbU"), $( "#youtubevalue" ).addClass( "errorclass" ), $( "#youtubevalue" ).removeClass( "noerrorclass");
}
if(youtubeReg.test(youtube)) { localStorage.setItem('error', 'false');
$("#youtubefooter").text("URL Is Good, Thanks!"), $( "#youtubevalue" ).addClass( "noerrorclass" ), $( "#youtubevalue" ).removeClass( "errorclass");
}
var youtubeB = document.getElementById('youtubevalue');
(var regex= LOTS / OF / BAD / WORDS;)'EDITED FOR STACK'
youtubeB.value=youtubeB.value.replace(regex, "****");
};
You could make the regex optional ? by using a non capturing group (?:.....)?
^(?:(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((.|-){11})(?:\S+)?)?$
var youtubeReg = /^(?:(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((.|-){11})(?:\S+)?)?$/;
var strings = [
'https://youtu.be/12KxXnFbwbU',
'',
'https://youtu'
];
strings.forEach((s) => {
console.log(s + ' ==> ' + youtubeReg.test(s));
});
Must it be done with regex? If not, you could simply trim the input and check if its empty, if empty then its good and if not apply regex.
See the below code
function checkyoutube() {
var youtubeReg =/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((.|-){11})(?:\S+)?$/;
var youtube = $("#youtubevalue").val();
//checking for length here after trimming
if(youtube.trim().length==0||youtubeReg.test(youtube)) { localStorage.setItem('error', 'false');
$("#youtubefooter").text("URL Is Good, Thanks!"), $( "#youtubevalue" ).addClass( "noerrorclass" ), $( "#youtubevalue" ).removeClass( "errorclass");
}
else{//skipped testing for regex again here
localStorage.setItem('error', 'true');
$("#youtubefooter").text("Example https://youtu.be/12KxXnFbwbU"), $( "#youtubevalue" ).addClass( "errorclass" ), $( "#youtubevalue" ).removeClass( "noerrorclass");
}
var youtubeB = document.getElementById('youtubevalue');
(var regex= LOTS / OF / BAD / WORDS;)'EDITED FOR STACK'
youtubeB.value=youtubeB.value.replace(regex, "****");
};

Retrieving jQuery data from dynamic HTML element returns undefined

I am trying to retrieve data from a variable HTML element. On click, the id of the <span> element is retrieved, which I want to enable me to dynamically $([dynamic id]) select that element and request the data stored in the data attribute.
My jQuery looks like this:
$( document ).ready( function() {
$( ".checkmark" ).on( "click", ( event ) => {
let checkBoxId = "#" + event.target.id, // #checkBox1
checkBoxData = event.target.id + "-value", // checkBox1-value
checkBoxValue = $( checkBoxId ).data( checkBoxData ); // undefined
} );
} );
The HTML element targeted looks like this:
<span class="checkmark" id="checkBox1" data-checkBox1-value=-155></span>
The value of let checkBoxValue is undefined and I cannot figure out why.
Help would be greatly appreciated.
You can get attribute value of span using attr() function in jQuery
checkBoxValue = $(checkBoxId).attr(checkBoxData);
The checkBoxId variable is unnecessary because you can use the this keyword since it is the current element you are working with.
$(function() {
$(".checkmark").on("click", (event) => {
let checkBoxData = event.target.id + "-value";
let checkBoxValue = $(this).data(checkBoxData);
});
});
It seems you are having scope issues with the new ()=>{} syntax.
So, you will need to bind this to the function event handler using {self:this}. If you don't want to do this, you can use the old function(){} syntax instead.
$( document ).ready( function() {
$( ".checkmark" ).on( "click", {self:this}, ( event ) => {
var checkBoxValue = $(this).data("checkbox1-value")
alert(checkBoxValue);
} );
} );
And also as #Erwin mentioned, use only lowercase in your data- attribute name:
<span class="checkmark" id="checkbox1" data-checkbox1-value="-155"></span>
JsFiddle
It's returning undefined because it is declared incorrectly. The part after data- should be in lower case. In your case, it must be
<span class="checkmark" id="checkbox1" data-checkbox1-value=-155></span>
for the .data() to work.
this code works for me try it ;)
$( document ).ready( function() {
$( ".checkmark" ).on( "click", function() {
var checkBoxId = "#" + $(this).attr('id');
var checkBoxData = $(this).attr('id') + "-value";
$( this ).attr('data-'+ checkBoxData, 155 );
} );
});
jsfiddle link

Dynamically loaded jQuery not finding class

I have the following code which loads jQuery into the page dynamically after page load and then attempts to run some jQuery of its own afterwards. The first console log of the page title works. The issue comes when it cant find the class "special-div" later on in the page and replace it with the appropriate text. Any thoughts?
//Load jQuery library using plain JavaScript
(function(){
var newscript = document.createElement('script');
newscript.type = 'text/javascript';
newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(newscript);
// Poll for jQuery to come into existance
var checkReady = function(callback) {
if (window.jQuery) {
callback(jQuery);
}
else {
window.setTimeout(function() { checkReady(callback); }, 100);
}
};
// Start polling...
checkReady(function($) {
console.log( 'jQuery is loaded on: ' + $('title').text() );
$( '.special-div' ).each(function( index ) {
console.log( index + ": " + $( this ).text() );
$( this ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
});
});
})();
The HTML looks like this:
<div id="something" class="special-div" title="else"> </div>
The wacky CMS that I am working on only allows for me to paste in one external javascript file so i have to load in jQuery and all other scripts i need through that one file.
Edit:
so i ran a few additional tests and tried this:
console.log( 'jQuery is loaded on: ' + $( '.special-div' ).attr( "id" ) );
the response i am getting is:
jQuery is loaded on: undefined
If you want to return content of div in second console.log, use $( this ).html() instead of $( this ).text()
If you want to replace text for each $( '.special-div' ) with the content of their attributes, you have to do:
$( this ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
instead of
$( '.special-div' ).replaceWith( "Say something here " + $( this ).attr( "id" ) + ' ' + $( this ).attr( "title" ) );
otherwise you get the same replacement for all occurrences.
I tried it and it works.
But if you are putting it in <head> and another jQuery is loaded before it, DOM searching will run before the DOM getting ready so that it can not find the DOM.
(case of no window.setTimeout(function() { checkReady(callback); }, 100);)
(another CMS plugin might load jQuery)
So it could be better to run the script on kind of window.onload timings.
Or putting it on the end of <body> may also work.

Fadein loop for class

I'm trying to loop through each element of a class in javascript and display it after pausing a certain amount of seconds. I have the logic down, but because jQuery is calling the class, and not the unique instance of this, it displays everything all at once:
jQuery( document ).ready(function ($) {
$( ".fadein" ).hide();
$( ".fadein" ).each(function (index) {
$( "." + this.className ).delay(index * 800).fadeIn( "slow" );
});
});
The each loop is already designed to hand you the elements one at a time. The target element is passed as 'this', so just fadeIn the current element in your 'loop' instead of fetching all of them each time.
// Replace this
$( "." + this.className ).delay(index * 800).fadeIn( "slow" );
// with this
$( this ).delay(index * 800).fadeIn( "slow" );
// result:
$( ".fadein" ).each(function (index) {
$( this ).delay(index * 800).fadeIn( "slow" );
});

How to use CKEditor by class in asp.net?

Is it possible to enable ckeditor by class type?
For example, I tried the following code but getting error:
$(document).ready(function() {
var txtArea= $(".ckeditor");
CKEDITOR.replace(txtArea,{ });
});
CKEDITOR.replace accepts ids and native element instances. But you're trying to pass jQuery object to it - it cannot work.
You should try this way:
$( document ).ready( function() {
$( '.ckeditor' ).each( function() {
CKEDITOR.replace( this );
} );
} );
Or, if you know that there's just one textarea to be replaced:
$( document ).ready( function() {
CKEDITOR.replace( $( '.ckeditor' )[ 0 ] );
} );
See this example on JSFiddle.

Categories

Resources