HTML 5 toggling the contenteditable attribute with javascript - javascript

enter code hereI am trying to make something editable online with a function like this
function toggle_editable (div, cssclass) {
var classToEdit = document.getElementsByClassName(cssclass)
for (i = 0;classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
}
if (classToEdit[i].contentEditable == true) {
classToEdit[i].contentEditable = false ;
}
}
}
classToEdit is a collection of HTML elements with the same class name or whatever document.getElementsByClassName(cssclass) returns
when going through the debugger it jumps over the line
classToEdit[i].contentEditable == true
as well as over the line
classToEdit[i].contentEditable == true
and does not execute the code in the braces following the if statements
this works however - meaning it sets the contenteditable property without hesitation
classToEdit.contenteditable = true;
as well as this
classToEdit.contenteditable = false;
(well obviously)
also this seemed to have no effect
classToEdit.contenteditable = !classToEdit.contenteditable
ideas anyone?
ps why is the loop

You've created an infinite loop here:
for (i = 0;classToEdit.length; i++) {
Should be:
for (var i = 0; i < classToEdit.length; i++) {
But, if you say classToEdit.contenteditable = true "works", you've to define "not working/is working" since the snippet doesn't definitely do what you expect it to do, if classToEdit is a HTMLCollection.
It looks like you'd want to toggle contentEditable values, you can do it like this:
for (var i = 0; i < classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
} else { // Notice else here, no need for another check
classToEdit[i].contentEditable = false;
}
}
Or simply without ifs in the loop:
classToEdit[i].contentEditable = !classToEdit[i].contentEditable;
Your current code will switch the value back to it's original in a case the value was false.

HTMLElement.contentEditable returns a string and not a boolean.
Hence, what you want to identify the state of your editable field is:
// Incorrect
classToEdit[i].contentEditable == true
// Coorect
classToEdit[i].contentEditable === 'true'
What's even better if you want to know the state of your fields is to use HTMLElement.isContentEditable
which returns a boolean:
classToEdit[i].contentEditable = !element.isContentEditable
Another way to refactor the above:
function toggleContentEdit() {
var editableFields = document.getElementsByClassName('editable');
[].forEach.call(editableFields, function(field){
var isEditable = field.isContentEditable;
field.setAttribute('contenteditable', !isEditable);
});
};
JSFiddle: http://jsfiddle.net/6qz3aotv/

Related

Cannot return a True or Force value out of a variable within an if statement in Angular

I have the following checkbox who is calling a function on launch to get checked based on a value that comes in from an api (cat.term_id)
<input ng-checked="ifCatExcluded(cat.term_id)">
The function works as follows: The first bit sets the checkbox value to true and gets an array which i need to cross check the id.
$scope.ifCatExcluded = function(sent_id){
var doesNotExist = true;
arraytosearch = JSON.parse(localStorage.getItem("categoryListMem"));
The second bit creates an empty array and adds the cat.term_id to this new array to avoid re running this id later.
if($scope.tempArray == undefined || $scope.tempArray.indexOf(undefined) > 0) {
$scope.tempArray = [];
}
if ($scope.tempArray.indexOf(sent_id) < 0) {
$scope.tempArray.push(sent_id);
console.log($scope.tempArray);
for (var i = 0; i < arraytosearch.length; i++) {
if (arraytosearch[i]['id'] == sent_id) {
doesNotExist = false;
console.log(sent_id + " IS EXCLUDED");
}
}
}
Then the last part returns the value for the checkbox and here is the problem. I cannot get a return of true or false from the doesNotExist variable. I noticed that when I take
for (var i = 0; i < arraytosearch.length; i++) {" ecc...
out of the if statement everything works...
return doesNotExist;
console.log(doesNotExist);
};
Any help is much appreciated.

GridView Validation is not working properly in JavaScript

I want to validate on button click that at least one of the rows must be edited and updated in JavaScript.
So I wrote the below code for validation
function checkGridValidate() {
var StrPriError = "";
var grdCount = GrdProspective1.Rows.length;
for (var i = 0; i < grdCount; i++) {
if (GrdProspective1.Rows[0].Cells[5].Value == "" || GrdProspective1.Rows[0].Cells[7].Value == "") {
StrPriError += "Kindly edit atleast one row \n";
}
if (StrPriError != "") {
alert(StrPriError);
return false;
}
else {
return true;
}
}
}
What happening here is, when I update the first row and submit it is not giving any alert that's perfect, but when I update the second row it still asks me Kindly edit at least one row.
I don't know what's going wrong here.
Have a look the js fiddle for the same
Currently, the validation is limited to only check the top row for two reasons:
.Rows[0] will always inspect the top row, despite the for loop.
This should make use of i as it increments through the collection:
if (GrdProspective1.Rows[i].Cells[5].Value == "" ||
The last if..else, by returning in either case, will interrupt the loop. The return statements here have a similar effect to break statements, with regards to the loop.
So, unless you want the loop to be interrupted, they should be moved out the loop:
for (var i = 0; i < grdCount; i++) {
if (...) {
// ...
}
}
if (StrPriError != "") {
alert(StrPriError);
return false;
}
else {
return true;
}
Though, fixing those should reveal a different issue – the function is checking that every row has been edited rather than one-or-more.
If, for example, there are 5 rows and you fill in both fields in 2 of the rows, the remaining 3 rows will match the condition and append the error message.
Inverting the condition, so you're searching for a row that's filled in and remembering whether you have, should resolve this.
function checkGridValidate() {
// assume invalid until found otherwise
var anyEdited = false;
var grdCount = GrdProspective1.Rows.length;
for (var i = 0; i < grdCount; i++) {
var cells = GrdProspective1.Rows[i].Cells;
// verify that both fields were given a value
if (cells[5].Value !== "" && cells[7].Value !== "") {
anyEdited = true; // remember that you've found an edited row
break; // and, no need to keep looking for more
}
}
// alert only if no rows were filled out
if (!anyEdited) {
alert("Kindly edit at least one row.");
}
return anyEdited;
}

what is the order of boolean logic in Javascript?

I wanted to use two Not and one and in booleans to test if the variable is neither upper case nor lower case.
I used this code so far but it didn't work as required:
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toLowerCase()) ){
x.splice(x[i], 1);
}
This code was for a function that sorts entered strings yet uppercase are sorted first.
Here is the full code, I am also open to understanding better ways to create this function apart from boolean logic and the array methods I used.
function alpha(str){ // United States
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
for (var i = 0; i<x.length; i++){
if (x[i] == x[i].toUpperCase()){
cap.push(x[i]);
}
else if ((x[i]) !== (x[i].toUpperCase()) && (x[i]!== x[i].toUpperCase()) ) {
x.splice(x[i], 1);
}
else {small.push(x[i]);}
}
var z = cap.sort();
var y = small.sort();
return z.concat(y).join("");
}
Please note the second else if statement is only useful because the code adds an empty space string at the beginning of the output, I'm not sure where it comes from, so please let me know if you have any idea how to sort this even without using the second else if.
In the ASCII table, upper case letters come first. That's why they come first when you sort alphabetically. Here's a link to a page on Wikipedia that shows the table with the upper case letters appearing first and their numerical equivalents. It's even printable.
Also, I took the liberty of simplifying your code a little. Seems like .splice() was not necessary.
function alpha( str ) {
var x = str.split(""); // [U,n,i,t,e,d,S,t,a,t,e,s]
var cap = [];
var small = [];
var length = x.length;
for (var i = 0; i < length; i++) {
if (x[i] === x[i].toUpperCase()) {
cap.push(x[i]);
} else if (x[i] === x[i].toLowerCase()) {
small.push(x[i]);
}
}
return cap.sort().concat(small.sort()).join("");
}
Maybe explain what you're trying to do? It most likely has been done before in some form and you definitely came to the right place to find an answer.
Is this what you want to do?
var str = "United States";
function alpha(str) {
return str.split('').sort().join('');
}
alert(alpha(str));
In all programming languages (as far as i know), boolean expressions are always evaluated from the left to the right with brackets of course.
So in the following example my_func() is called first, and then if there is the chance that the complete expression becomes true my_other_func() is called
if (my_func() && my_other_func()) {
// I only get here if my_func() AND my_other_func() return true
// If my_func() returns false, my_other_func() is never called
}
The same is true for the "or" operator in the following example
if (my_func() || my_other_func()) {
// I only get here if my_func() OR my_other_func() return true
// If my_func() returns true, my_other_func() is not called
}
So back to your code, in details this part (I reformated it a bit for better readability):
if (x[i] == x[i].toUpperCase()){
// only uppercase here
cap.push(x[i]);
} else if (x[i] !== x[i].toUpperCase() && x[i] !== x[i].toUpperCase()) {
// tested twice the same thing, so Im really sure that its not uppercase :D
// only lowercase here
x.splice(x[i], 1);
} else {
// I will never reach this
small.push(x[i]);
}
Im not sure what you want to do, but I hope the comments help to understand your code.

Including a for loop in an if statement

I'm building an application in which I want to display some errors when a user enters invalid values in an input box. A correct value is appended as 'entry' to a div if no errors were found. In total there are 3 cases when to display errors:
The input value is empty
The input value is a number
The input value already exists
These errors are displayed with if else statements.
1.and 2. were easy, but the problem case (3.) only validates against the first element of class .cat_entry.
if(cat_input == '') { // generate errors
errorDisplay(error_input_empty);
} else if(!isNaN(cat_input)) {
errorDisplay(error_input_number);
} else if($('.cat_entry') == cat_input) { // THIS IS THE PROBLEMATIC LINE
// .cat_entry is the class of the entries that have been appended
errorDisplay(error_duplicate);
} else {
// stuff
};
So I believe I need a for loop/ .each() (no problem so far), but how do I include this as a condition in an if statement? Something like.. if( for(i=0;i<$('.cat_entry').length;i++) { ... }; ... How to return true (or something similar) when one of the entries matches the input value, then pass the return value to the if statement?
EDIT: here is a jsFiddle with the relevant code. I updated it with $.inArray() method. I'd like to try and use this instead of a for / .each() loop.
You can try this:
var a=$('.cat_entry'),o={};
for(i=0;i<a.length;i++) {
var s=a[i].val();
if(s in o){
errorDisplay(error_duplicate);
return;
}
o[s]=true;
}
or
var o={};
$('.cat_entry').each(function(){
var s=$(this).val();
if(s in o){
errorDisplay(error_duplicate);
return;
}
o[s]=true;
}
You can actually use the jQuery inArray function for this, such as:
else if($.inArray(cat_input, $('.cat_entry') != -1)
}
The solution was to add this to the function:
var isDuplicate = false;
$('.cat_entry').each(function() {
if(!$(this).text().indexOf(cat_input)) {
isDuplicate = true;
}
// And in the if else loop:
else if(isDuplicate == true)
//and just before the function ends
isDuplicate = false;
Thanks to all for the help you offered.

breaking main loop - jstree

I am using jstree library to display a tree.
In the code below, I am looping through the selected nodes in the tree and based on some conditions, I am assigning a variable 'allow_edit' a boolean value.
I would like to break the main loop if 'allow_edit = false'.
I tried using label and breaking the loop but this does not seem to work. I am getting undefined label.
loop1:
$j.each($j("#demo2").jstree("get_selected"), function(index, element) {
var selected_node_depth = parseInt($j(element).attr('node_depth'));
var allow_edit = false;
var array_first_filter = $j.grep(array_first, function(v) { return v[1] != "not detected";})
var array_second_filter = $j.grep(array_first_filter, function(v) { return v[3] > selected_node_depth;})
if (array_second_filter.length === 0 || array_second_filter.length == null)
{
allow_edit = true;
}
else{
alert("Confliction exists in your selected terms.");
allow_edit = false;
//break loop1; /** not working, getting undefined label **/
}
}
Any suggestions on how to break the main loop if 'allow_edit = false'? Thanks a lot
If the function you pass to .each() returns false, the iteration will stop.
else {
allow_edit = false; // pointless since you're about to return ...
return false;
}
Also, as a programming style note, any construction of the form:
if (something) {
flag = true;
}
else {
flag = false;
}
can be better written as simply:
flag = something;
In JavaScript, to force flag to be boolean (true or false), you can do this:
flag = !!(something);
The two ! (logical "not") operators force the expression ("something") to be evaluated as a boolean by the same rules as are used when that expression is the test clause of an if statement.

Categories