Generate a html button from a javascript array - javascript

I'm struggling with the logic here and hope someone can help. I'm looping through the list array and then through the followers array inside it. I then check to see if the user variable is inside this followers array. The problem is that I want to produce an UNFOLLOW button when the user is in the array and a FOLLOW button when they're not.
What's happening now is that when the followers array has more than one value the loop is going back through it and giving both a FOLLOW and UNFOLLOW button in the one div.
I'm not sure if my logic is off or the syntax.
var user ='b';
lists = [
username: 'pat',
password: '***',
followers: ['a','b','c']
];
<% for (var i = 0; i < lists.length; i++) { %>
<div class="col-xs-4 panel">
<% for (var j = 0; j < lists[i].followers.length; j++) {%>
<% if (lists[i].followers[j] == userId) { %>
<button>Unfollow</button>
<% } else { %>
<button>FOLLOW</button>
<% } %>
<% } %>
</div>
<% } %>

Based on your comment, I think this is what you want:
var user ='b';
lists = [
username: 'pat',
password: '***',
followers: ['a','b','c']
];
<% for (var i = 0; i < lists.length; i++) { %>
<div class="col-xs-4 panel">
<% for (var j = 0; j < lists[i].followers.length; j++) {%>
<% var found = false;
if (lists[i].followers[j] == userId) {
%>
<button>Unfollow</button>
<% found = true;
break;
}
}
if (!found) { %>
<button>FOLLOW</button>
<% } %>
</div>
<% } %>

Related

Passing variable from ejs to js script

I am trying to pass a variable from ejs to JavaScript function but keep getting undefined in output. Here is the code. It is supposed to render a table with file names and clicking on each file name should later redirect to a page which would render the file in the browser but I can't proceed without passing the parameter to URL.
<% if (files.length > 0) {%>
<table class="table table-hovered">
<thead class="thead-light">
<tr>
<th scope="col">No</th>
<th scope="col">File</th>
<% files.forEach((file, index) => { %>
<tr>
<th scope="row">
<%= index + 1 %>
</th>
<td>
<a onclick="func(file.fileName);">
<%= file.fileName %>
</a>
</td>
</tr>
<% }) %>
</tbody>
</table>
<% } %>
</div>
</div>
<script>
function func(fileName) {
window.location.href = "/thesis_view/" + fileName;
}
</script>
getStudentUploadThesisPage: (req, res) => {
const getFilesQuery = "SELECT fileName FROM supervision INNER JOIN thesis ON supervision.thesisId = thesis.id INNER JOIN thesis_details ON thesis_details.thesisId = thesis.Id INNER JOIN people ON supervision.teacherId = people.id INNER JOIN thesis_file ON thesis_details.id = thesis_file.thesis_detail_id WHERE supervision.studId = " + req.session.userId;
db.query(getFilesQuery, (err, result) => {
if (err) {
return res.status(500).send(err);
} else if (result.length >= 0) {
res.render('student_upload_thesis', {
files: result
});
}
});
}
I have come up with something like this. It does it job
<script>
var table = document.getElementById('table'),
rIndex;
for (var i = 0; i < table.rows.length; i++) {
table.rows[i].onclick = function () {
rIndex = this.rowIndex;
window.location.href = "/thesis_view/" + this.cells[1].innerHTML;
}
}
</script>

How to use LocalStorage to make checkboxes persist?

How can we make the checkboxes persist for a user even when he reloads the page?
Please if you have the Javascript expertise can you help me with the relevant AJAX calls or give me some further guidance so I can pursue the answer on my own.
Every three boxes the user checks a new set of three boxes will show. How can we keep these AJAX induced boxes from disappearing?
habits/_form.html.erb
<label id="<%= #habit.id %>" class="habit-id"> Missed: </label>
<% #habit.levels.each_with_index do |level, index| %>
<% if #habit.current_level >= (index + 1) %>
<p>
<label id="<%= level.id %>" class="level-id"> Level <%= index + 1 %>: </label>
<%= check_box_tag nil, true, level.missed_days > 0, {class: "habit-check"} %>
<%= check_box_tag nil, true, level.missed_days > 1, {class: "habit-check"} %>
<%= check_box_tag nil, true, level.missed_days > 2, {class: "habit-check"} %>
</p>
<% end %>
<% end %>
habit.js
$(document).ready(function() {
var handleChange = function() {
habit = $(this).parent().prev().attr("id");
level = $('label', $(this).parent()).attr("id");
if ($(this).is(":checked")) {
$.ajax({
url: "/habits/" + habit + "/levels/" + level + "/days_missed",
method: "POST"
});
localStorage.setItem("habit_"+habit+"_"+level, true);
} else {
$.ajax({
url: "/habits/" + habit + "/levels/" + level + "/days_missed/1",
method: "DELETE"
});
localStorage.setItem("habit_"+habit+"_"+level, true);
}
if (!$('input[type="checkbox"]:not(:checked)', $(this).parent()).length) {
/* this is just an example, you will have to ammend this */
$(this).parent().append($('<input type="checkbox" class="habit-check">'));
$(this).parent().append($('<input type="checkbox" class="habit-check">'));
$(this).parent().append($('<input type="checkbox" class="habit-check">'));
$(".habit-check").on('change',handleChange);
}
}
$(".habit-check").on('change',handleChange);
});
habit.rb
class Habit < ActiveRecord::Base
belongs_to :user
has_many :comments, as: :commentable
has_many :levels
serialize :committed, Array
validates :date_started, presence: true
before_save :current_level
acts_as_taggable
scope :private_submit, -> { where(private_submit: true) }
scope :public_submit, -> { where(private_submit: false) }
attr_accessor :missed_one, :missed_two, :missed_three
def save_with_current_level
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.levels.build
self.save
end
def self.committed_for_today
today_name = Date::DAYNAMES[Date.today.wday].downcase
ids = all.select { |h| h.committed.include? today_name }.map(&:id)
where(id: ids)
end
def current_level_strike
levels[current_level - 1] # remember arrays indexes start at 0
end
def current_level
return 0 unless date_started
def committed_wdays
committed.map do |day|
Date::DAYNAMES.index(day.titleize)
end
end
def n_days
((date_started.to_date)..Date.today).count do |date|
committed_wdays.include? date.wday
end - self.missed_days
end
case n_days
when 0..9
1
when 10..24
2
when 25..44
3
when 45..69
4
when 70..99
5
else
6
end
end
end
days_missed_controller
class DaysMissedController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
habit = Habit.find(params[:habit_id])
habit.missed_days = habit.missed_days + 1
habit.save!
level = habit.levels.find(params[:level_id])
level.missed_days = level.missed_days + 1
level.save!
head :ok # this returns an empty response with a 200 success status code
end
def destroy
habit = Habit.find(params[:habit_id])
habit.missed_days = habit.missed_days - 1
habit.save
level = habit.levels.find(params[:level_id])
level.missed_days = level.missed_days - 1
level.save!
head :ok # this returns an empty response with a 200 success status code
end
end
Here's the gist of it: https://gist.github.com/RallyWithGalli/c66dee6dfb9ab5d338c2
Please let me know if you need any further explanation, code, or pictures. Thank you so much for your time!
Looking at your code, shouldnt one of the setItem calls on localstorage set checkbox value to false
if ($(this).is(":checked")) {
$.ajax({
url: "/habits/" + habit + "/levels/" + level + "/days_missed",
method: "POST"
});
localStorage.setItem("habit_"+habit+"_"+level, true);
} else {
$.ajax({
url: "/habits/" + habit + "/levels/" + level + "/days_missed/1",
method: "DELETE"
});
localStorage.setItem("habit_"+habit+"_"+level, false);//<--- ? ?
}
i made a quick fiddle to show how you can pass objects into localStorage, and load them later.
When you first load the page, check if user has something saved, if so, skip ajax requests etc, and simply create the rows based on the info on localStorage.
http://jsfiddle.net/rainerpl/s39c9fws/18/
<div id="container">
<div class="row" id="row_1">
<span class="label">Row 1:</span>
<input type="checkbox" name="test" id="check_1" value="1" />
<input type="checkbox" name="test" id="check_2" value="1" />
<input type="checkbox" name="test" id="check_3" value="1" />
</div>
</div>
<input type="button" value="clear saved values" onclick="localStorage.setItem('checkbox_rows', false)"/>
<input type="button" value="add new row" onclick="addNewRow()"/>
var saveChecks = function() {
var rows = $(".row"), saveObj = [], alreadySavedRows = localStorage.getItem("checkbox_rows");
if ( alreadySavedRows ) {alreadySavedRows = JSON.parse(alreadySavedRows);}
console.log("saveChecks", rows.length);
if ( alreadySavedRows && alreadySavedRows.length ) {saveObj = alreadySavedRows;}
var replacePreviousRow = function(row_obj) {
var i;
for ( i = 0; i < saveObj.length; i++ ) {
if ( saveObj[i].row_id == row_obj.row_id ) {
// console.log("replaced previous", row_obj);
saveObj[i] = row_obj;return true;
}
}
return false;
}
$.each(rows, function( key, val ) {
var
checks = $(val).find("input[type='checkbox']"),
rowObj = {"row_id": $(val).attr("id"), "checkboxes": []};
;
rowObj.label = $(val).find(".label").text();
$.each(checks, function( key, check ) {
check= $(check);
rowObj.checkboxes.push({
check_id: check.attr("id"),
checked: check.prop('checked'),
value: check.attr("value")
});
});
// console.log("rowObj before", rowObj);
if ( !replacePreviousRow(rowObj ) ) { saveObj.push(rowObj);}
});
//console.log("saveObj", saveObj);
localStorage.setItem( "checkbox_rows", JSON.stringify(saveObj) );
}
var container = $("#container");
var loadChecks = function() {
var rows = localStorage.getItem("checkbox_rows"), i, j, row, check, rowElem, checkElem;
if ( !rows ) {return false;}
rows = JSON.parse(rows);
if ( !rows || !rows.length ) {return false;}
//console.log("rows:", rows);
for ( i = 0; i < rows.length; i++ ) {
row = rows[i];
//remove any previously existing rows
$("#" + row.row_id).remove();
rowElem = $("<div class='row'></div>");
rowElem.attr("id", row.row_id);
container.append(rowElem);
rowElem = $("#" + row.row_id );
rowElem.append("<span class='label'>"+row.label+"</span>");
for ( j = 0; j < row.checkboxes.length; j++ ) {
check = row.checkboxes[j];
checkElem = $("<input type='checkbox' name='test'/>");
checkElem.attr("id", check.check_id);
rowElem.append(checkElem);
checkElem = $("#" + check.check_id);
checkElem.attr("id", check.check_id);
checkElem.attr("value", check.value);
checkElem.prop("checked", check.checked);
}
}
}
window.addNewRow = function() {
var rowElem = $("<div class='row'></div>"), i, row_id, checkElem;
row_id = Math.round(1000*Math.random());
rowElem.attr("id", "row_" + row_id );
rowElem.append("<span class='label'>Row id:" + row_id +"</span>");
for (i = 0; i < Math.ceil( Math.random() * 10 ); i++ ) {
checkElem = $("<input type='checkbox' name='test' />");
checkElem.attr("id", "check_" + row_id + "_" + i );
checkElem.val(i);
rowElem.append(checkElem);
}
container.append(rowElem);
setTimeout(saveChecks, 100);
}
$().ready(function() {
console.log("ready");
setTimeout( loadChecks, 30);
$("body").on("click", ".row", function(evt) {
var row = $(evt.currentTarget), notChecked = row.find("input:not(:checked)").length, id;
console.log("evt",notChecked);
if ( !notChecked ) {
id = Math.ceil( 1000 * Math.random() );
row.append("<input type='checkbox' name='test' id='check_"+id+"' value='1' />");
}
saveChecks();
});
});

change color of table cell using jsp

i have a jsp file which prints a mysql table with the help of jdbc.The columns of table are id, name , division and age.I want to change the color of table cell with age data to change red and green depending upon some particular values.
<body>
<%!Connection con; %>
<%!Statement s; %>
<% ResultSet rs=null;
String name=request.getParameter("t1");
try{
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3307/****","root","****");
s=con.createStatement();
System.out.println(name);
rs=s.executeQuery("select * from employee");
}catch(Exception e){ e.printStackTrace(); }
%>
<div id="dt_table">
<table border=1>
<tr>
<th>Empolyee ID</th>
<th>Empolyee Name</th>
<th>Employee Division</th>
<th>age</th>
</tr>
<tr>
<% try
{
while(rs.next())
{ %>
<tr>
<td><%=rs.getInt(1)%></td>
<td><%=rs.getString(2)%></td>
<td><%=rs.getString(3)%></td>
<td><%=rs.getInt(4)%></td>
</tr>
<% }
}catch(Exception e){ e.printStackTrace(); }%>
</table></div>
</body>
This question has been already asked but it has not been answered.Here's the link.
https://stackoverflow.com/questions/23131874/change-color-of-table-based-on-values-of-mysql-database-using-jsp
I even found something like this in php, but i donot know php,
Change color of table based on values from SQL Query database using PHP
So any help in jsp or javascript may be helpful.Thanks.
You could do this based on the header of the table
function colorIt() {
var val = 0; //value to be compared with
var val2 = 10; //value to be compared with
var ColIndexToCheck = 0;
var header = document.getElementById("dt_table").getElementsByTagName("th");
for (var j = 0; j < header.length; j++) {
if (header[j].innerHTML == "Age") {
ColIndexToCheck = j;
}
}
var trs = document.getElementById("dt_table").getElementsByTagName("tr");
for (var i = 0; i < trs.length; i++) {
if (trs[i].cells[ColIndexToCheck].innerHTML > val) {
trs[i].cells[ColIndexToCheck].style.backgroundColor = "red";
}
if (trs[i].cells[ColIndexToCheck].innerHTML > val2) {
trs[i].cells[ColIndexToCheck].style.backgroundColor = "green";
}
}
}
Try this, suppose the fourth column is the age in table:
while(rs.next()) {
{ %>
<tr>
<td><%=rs.getInt(1)%></td>
<td><%=rs.getInt(2)%></td>
<td><%=rs.getInt(3)%></td>
<td <%=(rs.getInt(1) > 10 : "style='background-color:red;'" : "")%> ><%=rs.getInt(1)%></td>
</tr>
<% } %>
Or you simply use If-else if you want.
Hope, it helps!!

Why does my form not submit what I want it to?

I'm trying to submit a javscript generated value.
The script is:
var save = function () {
var left = document.getElementById("left"); //Get a select box
var result = document.exchange; //get the form
result.value = ""; //set it's value to ""
for (i = 0; i < right.length; i++) {
result.value = result.value + "," + left.options[i].value; //set it's value to the values of the select box, divided by commas.
}
result.submit(); //submit the form
}
But my form only submits this:
{
"utf8" = > "✓",
"authenticity_token" = > "9gf3upm65ugEhsNvdcaykjdlg7xZbOyTiWJs79SnY3A=",
"timespan_id" = > {
"name" = > ["",
""]
},
"subgroup_id" = > "369141985"
}
The form is generated by my Rails. It looks like this:
<%= form_tag(subgroup_change_timespans_path(#subgroup), {
id: 'exchange',
name: 'exchange'
}) do %> <% timespans_array = #subgroup.timespans.all.map { | timespan | [timespan.name, timespan.id]
} %> <%= select(: timespan_id, : name, options_for_select(timespans_array), {}, {: multiple = > true,
: style = > "width: 300px; background-color: #9FE",
: width = > "300",
: size = > 20,
: id = > "left"
}) %> <%= link_to "<<", {
anchor: "",
remote: true
}, {
id: "toleft",
w_command: "add_timespan",
w_auth: form_authenticity_token,
w_controller: "subgroups",
w_id: #subgroup.id.to_s
} %> <%= link_to ">>", {
anchor: "",
remote: true
}, {
id: "toright",
w_command: "rem_timespan",
w_auth: form_authenticity_token,
w_controller: "subgroups",
w_id: #subgroup.id.to_s
} %> <% timespans_array = Timespan.all.map { | timespan | [timespan.name, timespan.id]
} %> <%= select(: timespan_id, : name, options_for_select(timespans_array), {}, {: multiple = > true,
: style = > "width: 300px; background-color: #F99",
: width = > "300",
: size = > 20,
: id = > "right"
}) %> <%= link_to "save", {
anchor: "",
remote: true
}, {
id: "save"
} %> <% end %>
But as I told you:
It just submits the names of two hidden fields:
<input name="timespan_id[name][]" type="hidden" value="" />
<input name="timespan_id[name][]" type="hidden" value="" />
I think, there is something wrong with these two. But I don't get what.
Do you have any Ideas?
#Малъ Скрылевъ: It has to be this way.
The form should look like this:
I found a Solution for my Problem:
I had to put the select boxes outside of the form, which removed the this parameter:
"timespan_id" = > {
"name" = > ["",
""]
Then I added a hidden_field_tag called 'string' inside the form.
Then at last, I changed my save function to:
var save=function()
{
var left = document.getElementById("left");
var result;
result="";
for(i=0;i<left.length;i++)
{
result = result+","+left.options[i].value;
}
var string=document.getElementById("string");
alert(result);
string.value=result;
document.exchange.submit();
}

Backbone pagination 10 at a time

Im building an pagination in backbone. The problem is that the amount of pages has grown and are now that many that it ruins the layout of the site. So i want to implement a functionality where i can render lets say the first 10 pages and then with a next/prev button control which page numbers should be shown. But always only show 10 pages like so:
< 1 2 3 4 5 6 7 8 9 10 >
< 2 3 4 5 6 7 8 9 10 11 >
So now i append this to my pagination (its all pages)
updateTotal: function () {
var self = this;
self.totalModel.fetch({
success:function(model,response) {
var total = response.data; //all iems
var p = total/self.perPage;
var r = total-Math.round(p)
self.pagination = _.template($("#pagination_template").html(), {
pages:Math.ceil(p)
});
self.render();
}
});
},
This is how i print it out in html (underscore.js)
<script type="text/template" id="pagination_template">
<section class="pagination">
<ul>
<% for (var i = 0; i < pages; i++) { %>
<li>
<a href="#" data-offset="<%= i*9 %>" data-page="<%= i+1 %>">
<%= i+1 %>
</a>
</li>
<% } %>
</ul>
<div class="paging prev">◄</div>
<div class="paging next">►</div>
</section>
</script>
I have a variable the represents the current page and i know the total amount of pages. But i dont know how to implement this that i describes as my problem.
Anyone knows how to do this and can come with an example? Would be very appreciated!
You can do it like this :
updateTotal: function () {
var self = this;
self.totalModel.fetch({
success:function(model,response) {
var total = response.data; //all iems
var p = total/self.perPage;
var r = total-Math.round(p);
var c = ... // current page
self.pagination = _.template($("#pagination_template").html(), {
pages:Math.ceil(p),
current: c
});
self.render();
}
});
},
And the html
<script type="text/template" id="pagination_template">
<section class="pagination">
<ul>
<%
var renderPage;
for (var i = 1; i <= pages; i++) {
renderPage = false;
if (pages < 10) {
renderPage = true;
} else {
if (current <= 5) {
if (i < 10) {
renderPage = true;
}
} else if (current <= pages - 5) {
if ((current - 5) < i || (current + 5) > i) {
renderPage = true;
}
} else {
if ((pages - 9) < i) {
renderPage = true;
}
}
};
if (renderPage) { %>
<li>
<a href="#" data-offset="<%= i*9 %>" data-page="<%= i %>">
<%= i %>
</a>
</li>
<% }
} %>
</ul>
<div class="paging prev">◄</div>
<div class="paging next">►</div>
</section>
</script>
That will print the current page and the 4 pages before and after.

Categories

Resources