CoffeeScript: toggle "true" and "false" of an attribute - javascript

I know that this should be pretty easy, but after searching around, I just don't seem to be able to find an answer.
I want to toggle the value of an aria attribute between true and false. I hoped there is some easy way for doing this, but I could only come up with the following:
if #container.attr('aria-hidden') == 'true'
#container.attr('aria-hidden', 'false')
else
#container.attr('aria-hidden', 'true')
I tried stuff with negating the values, but didn't succeed (I guess there's a problem between string booleans and real booleans, I mean false and "false").
I hoped that jQuery would offer something like this:
#container.toggleBool('aria-hidden')

There is no toggleBoolean method. All you can do is:
#container.attr 'aria-hidden', !/^true$/.test(#container.attr('aria-hidden'))
PS: And I still think that your snippet is more readable, so preferred.

Starting with jQuery 1.1, .attr() accepts a function as second argument, whose parameters are the index position of the element in the set, and the old attribute value. So, what about something like that (untested):
toggleBool = (index, attr) -> if attr='true' then 'false' else 'true'
[...]
#container.attr('aria-hidden', toggleBool)

If you find yourself doing this a lot, you could create a simple function to flip the strings 'truth value', assuming the string is always either 'true' or 'false':
flip = (x)->{'true':'false', 'false':'true'}[x]
. . .
#container.attr 'aria-hidden', flip(#container.attr('aria-hidden'))
but if it's neither, then it will return undefined, which may or may not be what you want:
coffee> flip('true')
'false'
coffee> flip('false')
'true'
coffee> flip('abcd')
undefined

I came up with this solution. At least it saves a few keystrokes.
handleEnterAndSpace: ->
#container.attr('aria-hidden', !#isOpen())
isOpen: ->
#container.attr('aria-hidden') == 'true'

Related

How to Check the variable value is [""] in JavaScript

Example:
When I check a variable containing this value [""] it returns false.
var th=[]
th.push("");
if($("#multiselect").val()==th)
It returns always false.
Thank you.
Edit 1:
changed Var to var. It was a typo.
Edit 2:
Actually, the problem I faced was I was trying to get the value from a multi-select input. The multi-select input sometimes returns values as [""] even I haven't selected any values basically it's a plugin. So I was confused and I thought [""] is a fixed primitive value like 1, 10, "bla blah",.. So I tried to compare it with the same array as the right-hand side of the '=' operator.
It was stupid. Now I posted the solution to my problem and I explained my stupidity.
there are two things:
Change Var to var
You can use includes method of Array as:
var th = [] <==== chnage Var to var
th.push("");
if(th.includes($("#multiselect").val())) { <=== you can use includes method of array
// DO whatever you want
}
Make sure var is lowercased.
You are accessing th as an array, so you’ll need to specify the index of the value you are checking: th[0]
Use triple equals, too: .val()===th[0]
Double check the jquery docs if you’re still running into trouble.
Happy coding!
A couple of things to consider:
You have a typo in the code above; var is valid; Var is invalid.
Browser will aptly complain to solve this typo.
You are comparing an array to DOM value; this will always be false.
DOM is a costly process. Unless the value associated is dynamic, its better to read once, store value into a variable and continue processing instead of reading from DOM always.
You could choose to try something on these lines:
let arr = [1,2,3,4];
let domValue = $("#multiselect").val();
arr.push(5);
arr.map((el, ix) => {
if el === domValue return true; //or choose to do something else here.
});
var th=[]; //It is var not Var
th.push("");
if($("#multiselect").val()==th[0]) // change th to th[0]
I am unable to comment so having to use an answer for now. Are you trying to check if an array has any values? If so you can use
if(th.length){
// do something
}
If you want to check a normal variable for empty string you can simply use
if(th == “”){
//do something
}
I found the solution after a couple of days when I posted this question. Now I can feel how stupid this question was.
Anyway, I'm answering this question so it might help others.
Answer to my question:
When two non-primitive datatype objects(which is the Array here) are compared using an assignment operator, it compares its reference of the object. So the object creation of both arrays would be different. If I want to check the array has [""] value, I should do something like the below.
function isArrValEmptyCheck(value) {
return !value || !(value instanceof Array) || value.length == 0 || value.length == 1 && value[0] == '';
}
console.log(isArrValEmptyCheck([""]));//returns true
console.log(isArrValEmptyCheck(["value1"]));//returns false
Sorry for the late response. Thanks to everyone who tried to help me.

Boolean value in javascript

Ok, I've got an issue I don't understand.
I have a boolean value which I test and if true I do something.
BUT javascript never go in it even if the var is true.
I try this :
if(isConfigD)
handleConfigurationD;
this :
if(isConfigD == true)
handleConfigurationD;
And this :
if(isConfigD === true)
handleConfigurationD;
But nothing work whereas isConfigD is always set on true :(
What am I missing ?
You condition works well, but if you call a function, then you need parenthesis for the call.
handleConfigurationD();
// ^^
handleConfigurationD is just an identifier. That statement is going to have one of two outcomes:
A ReferenceError
"Yup, that's a bit of data"
Presumably you have stored a function in it and want to call the function.
handleConfigurationD();

!variable not working in javascript

I have a javascript: bookmarklet with the code
javascript:document.body.contentEditable = !document.body.contentEditable;
which should switch on and off an "editor" for the page (just for pranks on friends and such). But it does not acheive the desired outcome, nothing happens when I click the bookmark. Opening up the Javascript Console, I see that:
document.body.contentEditable
"false"
!document.body.contentEditable
false
Previously, I used javascript:document.body.contentEditable = true; and this makes the page editable but I cannot turn it off.
Like you probably noticed in the JavaScript Console, document.body.contentEditable is a String, not a Boolean. You can do this instead:
document.body.contentEditable = !(document.body.contentEditable == "true");
or just
document.body.contentEditable = document.body.contentEditable != "true";
The HTMLElement.contentEditable property is used to indicate whether
or not the element is editable. This enumerated attribute can have the
following values:
"true" indicates that the element is contenteditable.
"false" indicates that the element cannot be edited.
"inherit" indicates that the element inherits its parent's editable status.
https://developer.mozilla.org/en/docs/Web/API/HTMLElement/contentEditable
document.body.contentEditable is a string value and JavaScript considers non-empty strings to be truthy.
!"" == true
!"a" == false
The value of contentEditable is a string, not a boolean. It can have the values "true", "false" or "inherit" (therefore it can't be a simple boolean). A boolean inversion won't work. You need to explicitly assign one of these three strings.
Is contentEditable a text input? So you need to parse the texto into boolean:
javascript:document.body.contentEditable = !JSON.parse(document.body.contentEditable);
deceze is correct here, I (somewhat stupidly) thought that because you do
document.body.contentEditable = true;
you could also do
!document.body.contentEditable;
but this is not correct.
In the end, I decided to use the property that is actually a boolean, isContentEditable, like so:
document.body.contentEditable = !document.body.isContentEditable;

Javascript regex matching on a time

I want to see if the string I have is in the form of HH:MM:SS.
Here is what I have so far:
d = '00:01:01'
d.match(/\d{2}:\d{2}:\d{2}/)
["00:01:02"]
Is there a way to just get a True/False, instead of an array?
Use .test method of Regexp object.
/\d{2}:\d{2}:\d{2}/.test(d)
// true
Perhaps, you can use regex.test(str) but it's also possible using match because on success, match returns an array which is a truthy value and on failure, match returns null which is a falsy value. Check this to understand truthy and falsy.
So, if you use
if(d.match(/\d{2}:\d{2}:\d{2}/)) {
// true
}
else {
// false
}
This will work, check this fiddle as an example and this answer as well (about !!), I've used !! in my example, so you may have doubts.

Coffeescript ternary if-statement wrong logic

I have a pretty much simple logic in a return function, but it doesn't work as expected. Of course I can make the code slightly longer and solve the issue, but I want it to be as small as possible.
Here is my code:
#Return title if exists or false otherwise
getPageTitleFromMainContent = (mainContent) ->
mainContent.find('#pageTitle') ?.length ?= false
if y = (getPageTitleFromMainContent $("#mainContent"))
y.css color:red
As you see, if it finds the #pageTitle in #mainContent, it should make it red. But the function doesn't return the #pageTitle if found, it returns .length.
From js2coffee.org I see that the code is compiled into:
var getPageTitleFromMainContent, y;
getPageTitleFromMainContent = function(mainContent) {
var _ref, _ref1;
return (_ref = mainContent.find('#pageTitle')) != null ? (_ref1 = _ref.length) != null ? **_ref1 : _ref.length = false : void 0;**
};
if (y = getPageTitleFromMainContent($("#mainContent"))) {
y.css({
color: red
});
}
And it should be _ref : _ref.length = false : void 0;, not _ref**1** : _ref.length = false : void 0; .
http://jsfiddle.net/X8VjJ/1/
Thank you!
if it finds the #pageTitle in #mainContent, it should make it red
You can accomplish this with the much simpler:
$('#mainContent #pageTitle').css(color: 'red')
Since, if it doesn't find #pageTitle in #mainContent, it will try to change the css of an empty set of elements -- a no-op.
The code as you've presented it doesn't really make sense. ?. is unnecessary, as the jQuery selector will not return null or undefined if it doesn't match; it will return an empty set of elements. So it will always be returning length, which will always be a number, so the assignment will never execute, since it depends on length returning null or undefined. Which is good, since you probably don't want to set the length of the elements to false.
Finally, this isn't the ternary if statement. CoffeeScript's ternary if statement looks like this: if foo then bar else baz.
Not sure that code makes sense. You're effectively trying to assign TO the length property, unless length is defined. If it is defined, it simply returns the length property. Looks like the code and behaviour is correct, but your understanding of the existential operator and return values is wrong. If you want to return the found element you probably need to disconnect it from the length check.
Maybe something like:
getPageTitleFromMainContent = (mainContent) ->
arr = mainContent.find('#pageTitle')
if arr.length then arr else false
As Ian explained in his more elegant answer, you do not need to use the existential operator on arr (assuming jquery), since it will always be an array of elements (with zero length if not found).

Categories

Resources