Add new row dynamically with Javascript/JQuery/Rails 3 - javascript

I am building a timesheet form that consists of a calendar which enables a user to select a specified date, and search for a project. I have this functionality working. What I basically have is this:
Once the user searches for their project and press the plus button, that specified project. Which in this instance is Asda the user would then click the plus icon which would create a new row and put it into the table 'task for project. How can you do this in Javascript/JQuery.
Sorry for asking what may be seen as such a basic question, but am still learning Javascript/JQuery.
I currently have the plus icon linked to project_project_tasks_path( project.id ). This is just temporary.
This is what I have so far:
<div class="left">
<table border="2" width="" id='projects' class='datatable'>
<thead>
<tr>
<th>Number &nbsp</th>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
<% #projects.each do |project| %>
<tr>
<td><%= project.project_number %></td>
<td><%= project.project_name %></td>
<td><%= link_to image_tag("icons/add.png"), project_project_tasks_path( project.id ), :remote => true %></td>
<!-- link_to image_tag("icons/add.png"), tasklist_path(project.id), :as => "tasklist" -->
</tr>
<%- end -%>
</tbody>
</table>
</div>
<div class="right">
<b>Recently Viewed</b>
<table>
<tr>
<th>Project No.</th>
<th>Project names</th>
<th>Project Leader</th>
<th></th>
</tr>
<tr>
<td>123</td>
<td>Test</td>
<td>1</td>
<td><%= link_to image_tag("icons/add.png") %></td>
</tr>
</table>
</div>
</fieldset>
<fieldset>
<b><center>Hours for Week commencing: <span id="startDate"><%= Date.today.beginning_of_week.strftime('%d/%m/%Y') %></span></center></b>
</fieldset>
<!-- Task list table -->
<div style="float: right; width: 300px; padding-left: 20px;">
<fieldset>
<b>Tasks for project</b>
<ul id="task_list">
</ul>
</fieldset>
</div>
<!-- Hours list table -->
<fieldset>
<table>
<tr>
<td>Leave</td>
<td><input class="dayinput" type="text" name="Leave"></td>
</t>
<tr>
<td>TOIL</td>
<td><input class="dayinput" type="text" name="TOIL"></td>
</tr>
<tr>
<td>Sick</td>
<td><input class="dayinput" type="text" name="Sick"></td>
</tr>
<tr>
<td>Total</td>
<td><input id="total" class="total_low" type="text" value="0" disabled="">
</tr>
</table>
</fieldset>
Edited:
I have created a task_list.js.erb which is as followed:
$('#task_list').html('');
<% #project.project_tasks.each do |task| %>
$('#task_list').append('<ul><%= task.task_name %>');
<% end %>
Project Controller
def index
# check if we've got a project id parameter
if( params[:project_id].nil? )
#project = nil
else
#project = Project.find(params[:project_id])
end
if #project.nil?
#project_tasks = ProjectTask.all
else
#project_tasks = Project.find(params[:project_id]).project_tasks
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #project_tasks }
format.js # index.js.erb
end
end
From the changes made, it outputs:
JQuery Ui autocomplete code:
$(function() {
function log(message) {
$( "<div/>" ).text( message ).prependTo("#log");
}
$("#tags").autocomplete({
source : function(request, response) {
$.ajax({
url : "/projectlist",
dataType : "json",
data : {
style : "full",
maxRows : 12,
term : request.term
},
success : function(data) {
var results = [];
$.each(data, function(i, item) {
var itemToAdd = {
value : item,
label : item
};
results.push(itemToAdd);
});
return response(results);
}
});
}
});
});

Adding to the DOM with jQuery is very simple with the append or prepend method.
$('element_to_add_to').append('the html to append');
$('element_to_add_to').prepend('the html to append');
Check out the empty method in the jQuery docs as well.
Also, you have some bad markup. The task_list <ul> has no <li>'s and the table in there has an extra </tr>.
Edit: From your updated post, it seems like you want to not only insert a row in a table, but also save the data to your database at the same time. In that case, you'll want to make an ajax call to a controller method which will save the data in your DB. Then add the updated row to the table if the call is successful.
$.ajax({
type: "POST",
url: "path to your route",
data: "the data to send to your controller",
success: function(data){
// here is where you process the return value from your controller method
// the data variable will hold the return value if the call is successful
// you can make your controller return the html to be inserted in your table
// and insert it from here or just return a status message and build and add
// the html manually here.
}
});

Related

Using ejs input for js if statement

I have a code problem I need to do for a class. I have a database that has users, another table has the titles which the user has access to. I'm trying to make a page where they can edit a user and when they click the button the form fills automatically with the id, first name and last name fine.
Now I'm trying to show what access the user selected has access to at the moment. And what I thought would just be a simple if statement has turned into a headache, it seems I can't access the id variable inside the html code that I want to insert and when I try to put the if statement outside, it says errors with the http headers, like it is sending too many renders. How can I accomplish this?
So here the code works but it loads the tabs of all of the users but I would like to filter the results based on the id.
<tbody>
<% all_users_to_modify.forEach(function(row){ %>
<tr>
<td>
<button class="btn btn-primary m-b-0"
onClick="fillForm('<%= row.id %>','<%= row.f_name %>','<%= row.l_name %>');";
onclick="moneyCalc('<%= row.id %>')" >
<%= row.id %>
</button>
</td>
<td><%= row.f_name %></td>
<td><%= row.l_name %></td>
<td><%= row.email %></td>
<td><%= row.phone_number %></td>
</tr>
<% }); %>
</tbody>
<table class="table table-striped table-bordered nowrap">
<thead>
<tr>
<th>Acceso</th>
</tr>
</thead>
<tbody id="lastResult">
</tbody>
</table>
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
Now this is what I would like to do, in each row of the list_of_all_users_tabs it has a column that is the user_id and the other column is tab_name. So I have had two ideas but neither seem to work.
First idea was to put a while loop to compare the user_id in the db and the input id however I get: Error [ERR_HTTP_HEADERS_SENT]:
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
while(list_of_all_users_tabs.user_id == id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
}
Second idea had an if statement in the html code however it says id not defined:
function moneyCalc(id) {
'use strict';
var id = document.getElementById('id').value;
if (id) {
var html_to_insert = `
<% list_of_all_users_tabs.forEach(function(row1){ %>
<% if(row1.id == id) { %>
<tr>
<td><%= row1.tab_name %> </td>
</tr>
<% } %>
<% }); %>
`;
lastResult.innerHTML += html_to_insert;
}
}
Wrap your javascript code into <script> tag.
<script>
//Your code goes here
</script>
You need to set you header status to 200 in your route file.
res.json({
success: 'updated',
status: 200
})
And write you JS code inside <script> </script> tags only.

How to get a MySQL Value as a colour in EJS?

I have a table in my nodeJS project that has data with a status. I would like to show this status in red and green. To render the HTML page I use EJS.
I've already tried using an if/else statement, but there I always get the first value of the statement.
MySQL:
SELECT g_id, g_name, g_status FROM games
EJS:
<table class="table table-hover">
<thead>
<tr class="table-info">
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<% if (data) {
data.forEach(function(game){
var status = game.g_status;
if (status = '1') {
status = 'color-green';
} else {
status = 'color-red';
}
%>
<tbody id="myTable">
<tr>
<td><%= game.g_name %></td>
<td><%= status %></td>
</tr>
</tbody>
<% }) %>
<% } %>
</table>
What's the problem, and how do I get the SQL output to a specific colour?
use ternary condition like this way :
<table class="table table-hover">
<thead>
<tr class="table-info">
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<% if (data) {
data.forEach(function(game){ %>
<tbody id="myTable">
<tr>
<td><%= game.g_name %></td>
<td><%= game.g_status=='1'?'color-green':'color-red' %></td>
</tr>
</tbody>
<% }) %>
<% } %>
well.
there is many places to look for.
read on equals operator in JavasScript
status is not part of the list, just app variable
create function returning color for given status

How to display parsed data from ajax in express.js

I have this page made using node.js + express where I am displaying the following table :
I wish to reload only the table with new data using ajax when limit is changed using the dropdown (one with the label show result), but am having trouble doing so.
Here's the ejs code that displays my table :
<table class="assignment-table table table-striped table-bordered table-hover table-condensed table-responsive">
<thead>
<tr>
<th>S.No.</th>
<th>Name</th>
<th>Subject</th>
<th>Topic</th>
<th>Faculty</th>
<th>Posted</th>
<th>Last Date</th>
<th>Mode of Submission</th>
</tr>
</thead>
<tbody class="table_body">
<% for(var i =0;i< result.length;i++) { %>
<tr>
<td class="result_id">
<a target="_blank" href="/assignment/abc.pdf" class="download-link" id="">
<%= result[i]._id %>
</a>
</td>
<td class="result_name">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].nameAssignment %>
</a>
</td>
<td class="result_subject">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Subject %>
</a>
</td>
<td class="result_topic">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Topic %>
</a>
</td>
<td class="result_faculty">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Faculty %></a>
</td>
<td class="result_posted">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Posted %></a>
</td>
<td class="result_lastdate">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].LastDate %></a>
</td>
<td class="result_submission">
<a target="_blank" href="/assignment/abc.pdf" class="download-link">
<%= result[i].Submission %></a>
</td>
</tr>
<% } %>
</tbody>
</table>
In the filter_result() route mentioned above, I am fetching limit from the url and querying the database with new limits and rendering the page again.
Router.get('/filter_result',(req,res) => {
limit = parseInt( decodeURIComponent(req.query.limit) );
models.filterResults(limit, (count,result) => {
//if (err) throw err;
console.log(limit);
//res.send(result);
res.render('assignment-list',{limit:limit,result:result,count : count});
});
});
How can I redisplay the table in the ejs page?
Basically your .ejs format is rendered only once when you load or reload the page. So what you do is re-render (or, replace) the HTML from your AJAX call on top of already-rendered HTML.
It seems that you're using jQuery already so my example code uses jQuery too.
Re-rendering (or, again, replacing) HTML depends on what your /filter_result responds. If it's just bunch of <tr>s then it might be
JS
$('table.assignment-table').find('tbody').html(result);
If it's the entire <table> then you'd better wrap <table> with some wrapper like <div> and do the following.
HTML
<div id="table-wrapper">
<table>
...
</table>
</div>
JS
$('div#table-wrapper').html(result);
How you refer your wrapper and replace the content can vary.
Update 1
Assuming your API (/filter_result) returns an array of assignment objects like
{
"status": "success",
"data": [
{
"Subject": "Your subject",
"Topic": "Your topic",
...
},
...
]
}
you can create bunch of <tr/>s from data and replace the existing <tr/>s with them like (with jQuery of course. About creating DOM with jQuery, you can refer the docs.)
$.ajax({
method: 'GET',
url: 'URL_TO_FILTER_RESULT',
data: SOME_DATA,
success: function(res) {
var assignments = res.data;
var body = [];
assignments.forEach(function(assignment) {
var tr = $('<tr/>');
tr.append($('<td/>').html('' + assignment.Subject + '');
tr.append($('<td/>').html('' + assignment.Topic + '');
...
body.push(tr);
});
$('table.assignment-table').find('tbody').html(body);
}
})

jQuery datatables dynamically changing is not removing correct rows in Ruby on Rails

I am using jQuery datables with dynamically change columns using Colvis.
Everything is working fine (adding and removing columns).
But when the data is loaded and trying to remove a column, it is not correctly removing the corresponding rows. Instead just the column is being removed but the corresponding row data is being displayed in the next column. It should also be removed.
Pleas help to fix this issue.
CODE
partner.js
$('#example').dataTable( {
"dom": 'C>"clear"<lfrtip',
searching:false,
paging:false,
"bServerSide": true,
"sAjaxSource": window.location.href,
"fnServerData": function ( sSource, aoData, fnCallback ) {
console.log(sSource);
console.log(aoData);
console.log(fnCallback);
alert('change in dataTable');
$.getJSON( sSource, aoData, function (json) {
// Do whatever additional processing you want on the callback, then tell DataTables
fnCallback(json)
} );
}
} );
transaction.html.erb # where the table is listed.
this is where the data is being loaded in the each loop.
<div class="panel">
<div class="panel-heading">
<span class="panel-title"><i class="fa fa-exchange"></i> Transactions</span>
<%= render partial: 'date_filter', locals: {filter_name: 'load_more'}%>
</div>
<div id="merchant_list" class="panel-body">
<div class="table-success">
<table id ="example" class="table table-bordered">
<thead>
<tr>
<th>Merchant</th>
<th>Bank Name</th>
<th>Payment Gateway</th>
<th>Status</th>
<th>Amount</th>
<th>Discount</th>
<th>Additional Charges</th>
<th>Added On</th>
</tr>
</thead>
<tbody id="details">
<% #all_settlement_details.each do |sd| %>
<tr>
<td><%= sd.merchantname %></td>
<td><%= sd.bank_name %></td>
<td><%= sd.payment_gateway %></td>
<td><%= get_status(sd.status) %></td>
<td><%= sd.amount %></td>
<td><%= sd.discount %></td>
<td><%= sd.additional_charges%></td>
<td><%= get_added_on_date sd.addedon %></td>
</tr>
<% end %>
</tbody>
</table>
<div id="align">
<% if #all_settlement_details.count < 1 %>
Nothing, more
<% else %>
Load more...
<% end %>
</div>
</div>
</div>
</div>
# BEFORE UNCHECKING STATUS COLUMN
# AFTER CLICK CHECK "Status"
See the two images. In the status column initially notice "Status", "Amount" columns. the row data is "dropped" for "Status" column but when I uncheck the status column, the status column is removed but the row data which was "dropped" is now moved to next column Amount.
I could not understand why it is happening. How can I fix this behavior.

How to call js for appropriate element

Can't how to deal with my problem: part of view are hidden, when page is loaded.
Here is this part:
<table>
<% #websites.each do |website| %>
<%if (current_user.id == website.user_id)%>
<tr>
<td> <%= link_to(image_tag("/images/caret-horizontal.png", id: "caret-horizontal"), '#') %> </td>
<td> <h4><%= website.name %></h4> </td>
</tr>
</table>
<table id="<%= website.id %>"> // or can be like this:
//I don't what variant is better
<table id="table-data" data-id="<%= website.id %>">>
<tr >
<td >
<%= website.url %>
</td>
</tr>
<tr>
<td >
<%= website.category %>
</td>
</tr>
<tr>
<td><%= website.language %></td>
</tr>
</table>
And I can get attributes in JavaScript like this(thanks to good people):
var yourWebsiteId = $("#table-data").attr("data-id");
How I can choose approriate element and show it? I should use getElementById or something like this, but I don't know exactly how to do it.
Please help me, if you can.
$("#table-data").show()
You can find information on this from here
$("#table-data") gets a reference to the part of the dom you are trying to access (# denotes id, . denotes class), once you have a reference you can then call any jquery operation you want on it

Categories

Resources