How to add different classes to template element? - javascript

In my JSON file I have 7 objects, where first 3 of them have "is_read" attribute == 1, and last 4 have "is_read" == 0.
I add rows, using a template and want to give tr different classes according to their "is_read" value (".news_read" for "is_read" == 1 and ".news_unread" for "is_read" == 0).
However, I end up with 7 rows that all have "news_unread" class. Though, console.log shows that I have 3 "newsData.get('is_read') == 1" and 4 "newsData.get('is_read') == 0" objects.
I wonder how to create rows with different classes. I tried to do newsRow.addClass, but the error message says that an object <tr><td>...</td></tr> (newsRow template) can't have a method addClass.
render: function() {
news.fetchMyNews();
for (var i = 1; i <= news.length; i++) {
var newsData = news.get(i);
var newsRow = JST["news/row"](newsData.attributes);
$("#news_tbody").append(newsRow).first('tr').attr("class",function(){
if (newsData.get('is_read') == 1)
return "news_read";
else if (newsData.get('is_read') == 0)
return "news_unread";
});
}
}

You wrote:
I tried to do newsRow.addClass, but the error message says that an object ... (newsRow template) can't have a method addClass.
But I can't find addClass in your example code:
$("#news_tbody").append(newsRow).first('tr').attr("class",function(){
if (newsData.get('is_read') == 1)
return "news_read";
else if (newsData.get('is_read') == 0)
return "news_unread";
});
I just can advice you to try this code(use addClass, instead of attr and add blocks in if statement):
$("#news_tbody").append(newsRow).first('tr').addClass(function(){
if (newsData.get('is_read') === 1){
return "news_read";
} else if (newsData.get('is_read') === 0) {
return "news_unread";
}
});

As #Pinal suggested, I used addClass instead.
However, after append(newsRow) I used .children('tr') and it worked fine.
$("#news_tbody").append(newsRow).children('tr').addClass(function(){
if (newsData.get('is_read') === 1){
return "news_read";
} else if (newsData.get('is_read') === 0) {
return "news_unread";
}
});

Related

Is it possible to call a method from a class in an HTML event like 'onblur'?

I got a little problem that I can't solve...
I usually check my form like this:
function checkFirst(field) {
if (field.value.length < 2 || !regLetters.test(field.value)) {
//do something
} else {
//do something else
firstNameOk = true;
}
}
and on the HTML side with onblur="checkFirst(this)".
Now I'm using OOP and I can't use my methods in onblur and I don't know how I could call the class in the onblur HTML attribute...
I already got a solution to work around this without using onblur in HTML and in my case I'd like to know if it's possible or not.
Anyone to help me please?
Edit:to avoid people telling me to use addEventlistener i show you my solution that works fine but not the one i wanted to use...
this.data.forEach(item => item.addEventListener('blur', function () {
console.log(item.id)
// check first name field //
if (item.id === "first") {
if (item.value.length < 2 || !this.regLetters.test(item.value)) { // if this field length =
this.highlightField(item, true);
} else {
this.highlightField(item, false);
this.errorMessagesReset(item);
this.firstNameOk = true;
}
// check last name field //
} else if (item.id === "last") {
if (item.value.length < 2 || !this.regLetters.test(item.value)) {
this.highlightField(item, true);
} else {
this.highlightField(item, false);
this.errorMessagesReset(item);
this.lastNameOk = true;
}
// check email field //
} else if (item.id === "email") {
if (item.value.length < 2 || !this.regmail.test(item.value)) {
this.highlightField(item, true);
} else {
this.highlightField(item, false);
this.errorMessagesReset(item);
this.emailOk = true;
}
// check textarea field //
} else if (item.id === "message") {
if (item.value.length < 1 || item.value > 100) { // if length of item is sup or equal to 1 and
this.highlightField(item, true);
} else {
this.highlightField(item, false);
this.errorMessagesReset(item);
this.messageOk = true;
}
}
}.bind(this))); ```
It should be a static function that belongs to the class then. That way you can call it directly.

Hi, how I can put the value of variable (i) in brackets?

For example I have N input, each input have some id wath start with 1 to N,
the input are not includes in FORM
With JS function I want to display the id of checked input
I try to do this like in example
for (i = 1; i <= count; i++)
{ if (document.getElementById('i').checked == true)
{ alert("id of checked element is:"+i);
}
}
How can I put the value of i here inside the brackets ?
{ if (document.getElementById('i').checked == true)
Couple of options
if (document.getElementById(`${i}`).checked == true)
//or
if (document.getElementById(i.toString()).checked == true)
// or even
if (document.getElementById(i).checked == true)

Javascript element ID visible but not accessible on keyup event

I am trying to cycle through a list of custom autocomplete options using the arrow keys in JavaScript. I am attempting to do this by iterating through the options and adding a "selected" ID to the option currently selected. I've run in to a problem where, although the "selected" ID of the option currently selected is visible (if you log it out, you can see the ID), the ID is inaccessible (trying to log out element.id returns an empty string).
Here is the code:
SearchBox.prototype.handleOptionNavigation = function() {
_this.inputElement.addEventListener("keyup", function(event) {
var options = _this.getOptions();
if (event.key === "ArrowUp") _this.moveSelectedUp();
if (event.key === "ArrowDown") _this.moveSelectedDown();
});
}
SearchBox.prototype.getOptions = function() {
return Array.from(document.getElementsByClassName("result-item"));
}
SearchBox.prototype.getSelectedIndex = function() { //here is the problem
var options = _this.getOptions();
if (options.length === 0) return;
console.log(options[2]);
//this returns <li class="result-item" id="selected">...</li>
console.log(options[2].id);
//this returns an empty string
return 1;
//this function is supposed to return the index of the element currently selected;
//I am returning 1 just to see a selected element on the screen.
}
SearchBox.prototype.moveSelectedDown = function() {
var options = _this.getOptions();
if (options.length === 0) return;
var selectedIndex = _this.getSelectedIndex();
if (selectedIndex === -1) {
options[0].id = "selected"
} else if (selectedIndex === (_this.maxResults - 1)) {
options[0].id = "selected"
options[options.length - 1].removeAttribute("id");
} else {
console.log("we are moving down");
options[selectedIndex + 1].id = "selected";
options[selectedIndex].removeAttribute("id");
}
}
SearchBox.prototype.moveSelectedUp = function() {
var options = _this.getOptions();
if (options.length === 0) return;
var selectedIndex = _this.getSelectedIndex();
console.log(selectedIndex);
if (selectedIndex === -1) {
options[options.length - 1].id = "selected";
} else if (selectedIndex === 0) {
options[0].removeAttribute("id");
} else {
options[selectedIndex - 1].id = "selected";
options[selectedIndex].removeAttribute("id");
}
}
The idea is that, with each press of the up or down arrows, a different element in the list of complete options will become highlighted. However, because I can't seem to access the id of the selected element, it gets stuck and the moveSelectedUp/moveSelectedDown functions don't work.
Does anyone know what is going on here?
Thank you!
Not quite sure what you are trying to achieve in your method SearchBox.prototype.getSelectedIndex, but it is always returning 1, how is that supposed to help ?
I've updated your method so that it returns the real index and it seems to work fine, see the fiddle below :
https://jsfiddle.net/c2p1aayh/

How to refactor long if statment?

I have a long if statement that I'm wanting to refactor. The statement listens for a click and then updates one of five text boxes depending on if those text boxes have anything in them or not. How could I change my code to be more efficient.
$('#img1').click(function() {
if ($('#card1').val().length === 0) {
$('#card1').val('A feeling of warmth');
} else if ($('#card2').val().length === 0) {
$('#card2').val('A feeling of warmth');
} else if ($('#card3').val().length === 0){
$('#card3').val('A feeling of warmth');
} else if ($('#card4').val().length === 0){
$('#card4').val('A feeling of warmth');
} else if ($('#card5').val().length === 0){
$('#card5').val('A feeling of warmth');
}
});
you could use a loop
$('#img1').click(function() {
var items = ["#card1", "#card2", "etc"];
for(var i=0;i<items.length;i++){
if ($(items[i]).val().length === 0) {
$(items[i]).val('A feeling of warmth');
}
}
});
it's at least easier to read. Also if your buttons are always card + a number you could make it even simplier (not easier to read, just less lines & maintenance)
$('#img1').click(function() {
for(var i=0;i<=5;i++){
if ($("#card" + i).val().length === 0) {
$("#card" + i).val('A feeling of warmth');
}
}
});
It seems like you're using JQuery. You can use a selector and a filter to isolate the first empty item:
$('#img1').click(function() {
$('input:text[id^=card]')
.filter(function() { return $(this).val() == ""; })
.first()
.val('A feeling of warmth');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="img1">CLICK ME</button><br>
<input id="card1"><br>
<input id="card2"><br>
<input id="card3"><br>
<input id="card4"><br>
<input id="card5">
$('input:text[id^=card]') selects all text inputs whose IDs begin with 'card'. But the same principle would apply to other element types.
$('#img1').click(function() {
// num can be total count of the element like $(.card).children.count
var num = 5, // preferably dont make it hardcoded.
str = 'A feeling of warmth',
preIdStr = '#card',
id;
for (var i = 1; i <= num; i += 1) {
id = preIdStr + i;
if ($(id).val().length === 0) {
$(id).val(str);
}
}
});
Give all cards the same class.
Then use the selector $('.yourclass')
Now use the jQuery for-each (.each) function to iterate all elements. Within the loop you check the value, set it to whatever you want and return false when the value was set, since this exit's the loop.
$('.yourclass').each(
function () {
if (this.val().length === 0) {
this.val('your value');
return false; // exit loop
}
});

Change image on json property when appending template

An image can have [1,2,3,4] states (placeholder, processing, accepted, rejected) in a JSON format. I am figuring out a function to check the property and select the right image to place in the Mustache HTML.
I tried the following:
for (let i=0;i<101;i++) {
var output = Mustache.render(template, view[i]);
$('#entryTable tbody').append(output);
if (view[i].status == 2) {
this.getElementById('picture1').src= 'img/analyzing.png';
} else if (view[i].status == 3) {
this.getElementById('picture1').src= 'img/irrelevant.png';
console.log(this)
} else if (view [i].status == 4) {
this.getElementById('picture1').src= 'img/relevant.png';
}
But 'this' refers to the document and not the image -> it changes only the first image (for all entries, repeatedly) that appears.
Next, I tried:
for (let i=0;i<101;i++) {
var output = Mustache.render(template, view[i]);
$('#entryTable tbody').append(function() {
//the default image in the template is state 1, hence it checks for state 2 and above
if (view[i].state == 2) {
this.getElementById('picture1').src= 'img/analyzing.png';
} else if (view[i].state == 3) {
this.getElementById('picture1').src= 'img/irrelevant.png';
console.log(this)
} else if (view [i].state == 4) {
this.getElementById('picture1').src= 'img/relevant.png';
}
return output;
});
Which seems(?) to work but only appends one entry.
I am not experienced with 'this', how would I get it to the right context/scope to change the entry specific image?
Solved
if (view[i].state === 1) {
$("#entryTable tbody tr .status1").eq(i).attr("src", "img/analyzing.png");
} else if (view[i].state === 3) {
$("#entryTable tbody tr .status1").eq(i).attr("src", "img/irrelevant.png");
} else if (view[i].state === 4) {
$("#entryTable tbody tr .status1").eq(i).attr("src", "img/relevant.png");
}
}

Categories