jQuery add and remove class checking - javascript

This function works. No issues with it working.
if ($(".register-frame").length) {
var emailCheck = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
$('#email-field').change(function () {
if (!$('#email-field').val().match(emailCheck)) {
if ($("#email-field").hasClass("field-success")) {
$("#email-field").removeClass('field-success');
}
if (!$("#email-field").hasClass("field-error")) {
$("#email-field").addClass('field-error');
}
} else {
if ($("#email-field").hasClass("field-error")) {
$("#email-field").removeClass('field-error');
}
if (!$("#email-field").hasClass("field-success")) {
$("#email-field").addClass('field-success');
}
}
});
}
.login-frame .field-error { border-color: #A94442; }
.login-frame .field-success { border-color: #3C763D; }
Basically this function checks when an email field changes if its a valid email or not. If its not a valid email it removes the valid class if it exists and then adds the invalid class if it doesn't exist.
So my question is, this function seems over done to me. To many checks. Is there a more efficient way of doing the same thing?

I'd simplify it with functions.
In abstract, it would be something like:
$('#email-field').blur(function () {
var is_valid = is_valid($(this).val());
if (is_valid){
$("#email-field").addClass('field-success').removeClass('field-error');
}else{
$("#email-field").removeClass('field-success').addClass('field-error');
}
});
function is_valid(email){
//blah
}

You can simply use addClass and removeClass without checking if the class already exists, since addClass will do nothing if the class is already there, and removeClass will do nothing if the class is not there.
Also, you can use method chaining to make the code shorter.
You can also assign $('#email-field') to a variable so jQuery doesn't have to search for the same element repeatedly.
var $emailField = $('#email-field');
if (!$emailField.val().match(emailCheck)) {
$emailField.removeClass('field-success').addClass('field-error');
} else {
$emailField.removeClass('field-error').addClass('field-success');
}

https://api.jquery.com/toggleClass/
Refer to the toggleClass documentation

You don't need the if statements using hasClass. JQuery will handle that logic for you.

$('#email-field').change(function () {
var cl = ($(this).val().match(emailCheck)) ? 'field-success' : 'field-error';
$(this).removeClass('field-success field-error').addClass(cl)
});

if ($(".register-frame").length) {
var emailCheck = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
$('#email-field').change(function () {
if (!$('#email-field').val().match(emailCheck)) {
//since it is failure dont check
$("#email-field").removeClass('field-success'); //wont give error if not present
$("#email-field").addClass('field-error');
} else {
$("#email-field").removeClass('field-error');
$("#email-field").addClass('field-success');
}
});
}
.login-frame .field-error { border-color: #A94442; }
.login-frame .field-success { border-color: #3C763D; }
or just simply you can do.
$("#email-field").attr('class','new class') //new class can be either success or error

Related

jQuery to Javascript adding required attribute

So I have the following jQuery code that I've built out that checks whether a on change event has been triggered on #rtk5 and then either removes or adds the 'required' attribute.
Works perfectly in jQuery:
// Make checkbox textboxes not required unless checked
$(document).ready(function() {
$('#rtk5').change(function() {
if ($('.rtk5ReqField').attr('required')) {
$('.rtk5ReqField').removeAttr('required');
}
else {
$('.rtk5ReqField').attr('required','required');
}
});
});
I would like to convert it to JavaScript with a function call, but I can't seem to figure out how to properly do it.
Error:
TypeError: rtk5req.getAttribute is not a function
Here is my attempt:
var rtk5req = document.getElementsByClassName('rtk5ReqField');
function rtk5Required() {
rtk5req.addEventListener('change', (e) => {
if (rtk5req.getAttribute('required')) {
rtk5req.removeAttribute('required');
} else {
rtk5req.getAttribute('required', 'required');
}
});
}
rtk5req.addEventListener('change', rtk5Required());
document.addEventListener('DOMContentLoaded', rtk5Required);
rtk5Required();
Updated code: Removed the repetitive change call
var rtk5req = document.getElementsByClassName('rtk5ReqField');
function rtk5Required() {
if (rtk5req.getAttribute('required')) {
rtk5req.removeAttribute('required');
} else {
rtk5req.getAttribute('required', 'required');
}
}
rtk5req.addEventListener('change', rtk5Required());
document.addEventListener('DOMContentLoaded', rtk5Required);
rtk5Required();
Updated code #2:
Thanks all for all the hard work, there's one small issue that I'm still experiencing and had to make some tweaking - When I uncheck the checkbox, it doesn't remove the required tag placed on rtk5Declaration from which it did in the jQuery.
var rtk5_selection = document.getElementById('rtk5');
document.addEventListener('DOMContentLoaded', () => {
rtk5_selection.addEventListener('change', () => {
if (rtk5_selection.getAttribute('required')) {
document.getElementById('rtk5Declaration').removeAttribute('required');
} else {
document.getElementById('rtk5Declaration').setAttribute('required', 'required');
}
});
});
Thanks so much all!
Since you only have one element you should be using its ID instead of its class, and avoiding the complication caused by document.getElementsByClassName returning a pseudo-array of elements instead of a single element.
NB: use setAttribute to change an attribute's value, or better yet (as shown in the code below) use the direct boolean property that mirrors the element's attribute.
document.addEventListener('DOMContentLoaded', () => {
const rtk_sel = document.getElementById('rtk5');
const rtk_dec = document.getElementById('rtk5Declaration');
rtk_sel.addEventListener('change', () => {
rtk_dec.required = !rtk_sel.checked;
});
});
Thanks all for the contribution, below is the working version which I have tweaked:
var rtk5_selection = document.getElementById('rtk5');
var rtk5declaration = document.getElementById('rtk5Declaration');
function rtd3Declaration() {
if (!rtk5_selection.checked) {
rtd3declaration.removeAttribute('required');
} else {
rtd3declaration.setAttribute('required', 'required');
}
}
rtk5_selection.addEventListener('change', rtd3Declaration);
document.addEventListener('DOMContentLoaded', rtd3Declaration);
rtd3Declaration();

How can I use ng-if to display a button based on the current user?

I am create a user profile and would like to show an edit button that only displays for the profile's owner. I am attempting to use ng-if so that the edit capabilities are removed from the DOM.
How can I use ng-if to display a button based on the current user?
In my view:
<button ng-if="editProfile()">EDIT</button>
In my controller:
$scope.editProfile = function (canedit) {
var canedit = false;
for (var i=0;i<$scope.users.length;i++) {
if ($scope.users[i].id===$scope.currentUser.id) {
canedit = true;
}
}
}
Your function needs to return true or false
<button ng-if="editProfile()">EDIT</button>
$scope.editProfile = function () {
for (var i=0;i<$scope.users.length;i++) {
if ($scope.users[i].id===$scope.currentUser.id) {
return true
}
}
return false
}
You are returning nothing from your function.
You can make it this way
<button ng-if="canEdit()">EDIT</button>
and in your controller
$scope.canEdit = function () {
return $scope.users.find(u=>u.id === $scope.currentUser.id) ? true : false;
}
Just add
return canedit;
below the for closing bracket
As everyone mentioned, the function wasn't returning true or false. After adding the return I discovered that the for statement was extraneous and I just needed a simple check. This code is working correctly:
$scope.editProfile = function () {
if ($scope.user.id===$scope.currentUser.id) {
return true
}
return false
}

My HTML button's javascript will not toggle second time

This is what I have so far:
HTML:
<button id="clockToggle" onclick="toggleClock()">Toggle Clock</button>
CSS:
#clockWidget {
display:none;
}
JavaScript:
function enableClock() {
var clock = document.getElementById("clockWidget");
clock.style.display="block";
}
function disableClock() {
var clock = document.getElementById("clockWidget");
clock.style.display="none";
}
function toggleClock() {
var clock = document.getElementById("clockWidget");
if(clock.style.display="none") {
enableClock();
}
else {
disableClock();
}
}
My goal is to make the button so that it will toggle the clockWidget on and off. If possible answer with JavaScript instead of jQuery.
P.S. If you vote my question down, at least comment on why you did so
In the if statement of your toggleClock() function you are missing a '=' and thus do not compare but instead set the display property of clock. This is why it only calls enableClock(). If you use the following it should work as expected:
if (clock.style.display == "none") {
enableClock();
} else {
disableClock();
}
You're missing another '=' in your comparison:
if(clock.style.display == "none") {
enableClock();
} else {
disableClock();
}
$("#clockToggle").click(function(){
$("#clockWidget").toggle();
});

Pass jQuery change as a paramater

I have a lot of places in my application where I need to execute JS function and also bind it to some jquery event like "change" or "click". For refactoring purposes I'd like to create a generic function that should help me accomplish this. Here are my original thoughts:
function execute_and_track(trackEvent, action) {
action();
trackEvent(function () {
action();
});
}
And I thought to use it like this:
execute_and_track($("#ddl_Test").change, function () {
if ($("#ddl_Test").val().toUpperCase() == "OTHER") {
document.getElementById("txt_Test").style.display = "inline";
}
else {
document.getElementById("txt_Test").style.display = "none";
$("#txt_Test").val("");
}
});
Unfortunately this throws an error: Uncaught TypeError: Object [object global] has no method 'on'. It looks like I am not able to pass jquery change as a parameter. Can anybody help me to fix this logic or suggest another way of creating generic function for such refactoring?
If I understand the question, I would change approach.
Try this new one (as jquery plugin)
$.fn.execute_and_track = function(eventName, func) {
this.each(function() {
func.call(this); // fix the scope
$(this).on(eventName,func);
});
return this;
}
$("#ddl_Test").execute_and_track('change', function() {
if ($(this).val().toUpperCase() == "OTHER") {
this.style.display = "inline";
}
else {
this.style.display = "none";
$(this).val("");
}
});

Shaking effect in my javascript code

I was just trying to use a function of jQuery in my JavaScript code for styling. I want that whenever the required text field is empty, the textfield should shake, but I can't do it. Please help me out I just wasted my whole night on it. Finally asking for your help. I hope that you people get my question.
The code is given below
function validate() {
var em = document.getElementById("email_value").value;
var pass = document.getElementById("password_value").value;
if(em == "") {
shakeIt();
}
}
$(document).ready(function() {
function shakeIt() {
$("input").effect("shake", { times:5}, 50);
}
});
function validate()
{
var em = document.getElementById("email_value").value;
var pass = document.getElementById("password_value").value;
if(em == "")
{
shakeIt();
}
}
function shakeIt()
{
$("input").effect("shake",
{
times: 5
}, 50);
}
Don't wrap it in $(document).ready() function, because your shakeIt function is not longer in global scope, if you do so.

Categories

Resources