Editable row in rails using java script - javascript

I want to make each row editable in table. For this I place rows with text_fields in each bellow the row with table data.
<style>
.dtr{
display:none;
}
</style>
<body>
<div class="container" align="center">
<h1>Products Description</h1>
</div>
<br />
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Product Name</th>
<th scope="col">Product Description</th>
<th scope="col">Brand Name</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<% #csv_table.each do |row| %>
<tr class="mtr">
<% row.each do |key, value| %>
<%unless key == "id"%>
<td class="value"><%= value %></td>
<%end%>
<% end %>
<td>
<div class="edit">
<%=link_to "Edit",class: 'form-control' %>
</div>
<div class="delete">
<%=link_to "Delete",class: 'form-control' %>
</div>
</td>
</tr>
<tr class="dtr">
<td>
<%= text_field_tag :login_aei2, "", class: 'form-control' %>
</td>
<td>
<%= text_field_tag :login_aei3, "", class: 'form-control' %>
</td>
<td>
<%= text_field_tag :login_aei4, "", class: 'form-control' %>
</td>
<td>
<%=link_to "Save", remote: true, class: 'form-control' %>
</td>
</tr>
<%end%>
</tbody>
</table>
</body>
<script>
$(document).ready(function(){
$(".edit").click(function(){
debugger;
var mtr = this.closest(".mtr");
mtr.style.display = "none";
mtr.nextElementSibling.style.display="inline";
// this.parentElement.parentElement.style.display='none';
event.preventDefault();
});
});
</script>
When I click on edit button current row become hidden and the row with input field get shown but the problem is, it shows only in area of table data not in whole row. please help. Thanks in advance

So when the user click on "edit", its necessary to know exactly what Info has been clicked, in order to update to the database, and in order to show and hide the infos.
The changes that I've made is based on a demo-data that I've created to develop this solution:
#csv_table = [ {id:3, product: "Product", description: "Description",
brand:"Brand", action: "Action" }, {id:4, product: "Product2",
description: "Description2", brand:"Brand2", action: "Action2" }]
This is so called "Array of Hashes", and I thought that was what you were using too.
In the complete code, as we iterate throught the array, we can see two values that are name, and value. I used "value" instead of id, because I didnt want to cause a html conflict. So you can see in the code this:
<% value = row[:id] %>
And this
<% name = key[0] %>
Then each row has the field, and has the info (but one of them is hidden), like so:
<td class="value">
<a id=<%= "info_#{name}#{value}" %> class="info <%= "info_dtr#{value}" %>" name=<%= name %> value=<%= value %>><%= row[name] %></a>
<%= text_field_tag :login_aei, "", class: "form-control field field_dtr#{value}", id: "field_#{name}#{value}" %>
</td>
Can you notice that the id it has name and value? In that way we can tell JQuery to look for the field we have clicked. For example info_product1, and field_product1, and set it to hide(); or show();. Below is the complete code, these are mostly javascript and html tricks, so you can try to play around a little bit:
Ruby + Html:
<style>
.dtr{
display:none;
}
</style>
<div class="container" align="center">
<h1>Products Description</h1>
</div><br />
<table class="table table-striped" border=2 style="border: 2px solid;">
<thead>
<tr>
<th scope="col">Product Name</th>
<th scope="col">Product Description</th>
<th scope="col">Brand Name</th>
<th scope="col">Action</th>
<th></th>
</tr>
</thead>
<tbody>
<% #csv_table.each_with_index do |row, i|%>
<% value = row[:id] %>
<tr class="mtr">
<% row.each_with_index do |key, j| %>
<% name = key[0] %>
<% unless j==0 %>
<td class="value">
<a id=<%= "info_#{name}#{value}" %> class="info <%= "info_dtr#{value}" %>" name=<%= name %> value=<%= value %>><%= row[name] %></a>
<%= text_field_tag :login_aei, "", class: "form-control field field_dtr#{value}", id: "field_#{name}#{value}" %>
</td>
<% end %>
<% end %>
<td>
<%= link_to "Save", {}, remote: true, class: 'form-control save', 'value' => value %>
<div class="delete"><%=link_to "Delete",class: 'form-control'%></div>
</td>
</tr>
<% end %>
</tbody>
</table>
</body>
Javascript:
$(document).ready(function(){
$(".field").hide();
});
$(".info").click(function(event){
console.log("info");
name = $(this).attr("name");
id = $(this).attr("value");
console.log($(this).attr("value"));
$("#info_" + name + id).hide();
$("#field_" + name + id).show();
});
$(".save").click(function(event){
event.preventDefault();
// { .. if saves}
console.log("salvar");
id = $(this).attr("value");
$(".field_dtr" + id).hide();
$(".info_dtr" + id).show();
});

Related

Using forEach inside of an EJS template

<table class="pt-5">
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
<% cart.forEach(function(item) { %>
<tr>
<td>
<div class="product-info">
<img src="images/<%= item.image %>">
<div>
<p><%= item.name %></p>
<% if(item.sales_price){ %>
<small><span>$</span><%= item.sales_price %></small>
<% } else { %>
<small><span>$</span><%= item.price %></small>
<% } %>
Error
TypeError: /Users/netra/Desktop/project/views/pages/cart.ejs:174
172| </tr>
173|
>> 174| <% cart.forEach(function(item) { %>
175|
176|
177|
I tried putting => but it also did not work.

Access values of array within array within object

I have an object
{
'Bob Joerson': [
[ 'Tuesday March 31, 2020', '07:58:12.0' ],
[ 'Wednesday April 1, 2020', '11:00:03.7' ]
],
'Joe Bobberson': [
[ 'Tuesday March 31, 2020', '07:58:12.0' ],
[ 'Wednesday April 1, 2020', '11:00:03.7' ]
]
}
How would I access the information within the array within the array?
I have tried:
<% for(var key in timesheets){ %>
<% if(timesheets.hasOwnProperty(key)){ %>
<% a = 0 %>
<table id="timesheetTable" class='table-primary table-bordered table' style='border-spacing: 10px;'>
<tr>
<td rowspan="2" id="name"> <%= key %> </td>
<% for(var value in key){ %>
<td> <%= value %> </td>
<% } %>
</tr>
</table>
<% a++ %>
<% } %>
<% } %>
But value just outputs the string index for the name stored in key.
When I try
<h1>Timesheet for dates</h1>
<% for(var key in timesheets){ %>
<% if(timesheets.hasOwnProperty(key)){ %>
<% a = 0 %>
<table id="timesheetTable" class='table-primary table-bordered table' style='border-spacing: 10px;'>
<tr>
<td rowspan="2" id="name"> <%= key %> </td>
<% for(i = 0; i < key.length; i++){ %>
<td> <%= key %> </td>
<% } %>
</tr>
</table>
<% a++ %>
<% } %>
<% } %>
It just outputs the names over and over again in a table.
Try this:
<% for(var key in timesheets){ %>
<% if(timesheets.hasOwnProperty(key)){ %>
<% a = 0 %>
<table id="timesheetTable" class='table-primary table-bordered table' style='border-spacing: 10px;'>
<tr>
<td rowspan="2" id="name"> <%= key %> </td>
<% for(var value of timesheets[key]){ %>
<td> <%= value[0] %><%= value[1] %> </td>
<% } %>
</tr>
</table>
<% a++ %>
<% } %>
<% } %>
Note that key is each key of timesheets so timesheets[key] will be the value(array of arrays) of that key.
try something like this:
<% for(var entry of timesheets[key]){ %>
<td> Date: <%= entry[0] %> </td>
<td> Time: <%= entry[1] %> </td>
<% } %>

SyntaxError: missing ) after argument list in while compiling ejs

I am getting the error: missing ) after argument list while compiling ejs.
I tried many times, but I can't find the problem.
Here's the ejs that causes errors.
What is the problem with this code?
<%- include('../_layouts/adminheader') %>
<h2 class='page-title'>Products</h2>
<br>
Add a new product
<br><br>
<% if (count > 0) { %>
<table class="table table-striped">
<thead>
<tr class="home">
<th>Product</th>
<th>Price</th>
<th>Category</th>
<th>Product Image</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<% products.forEach(function(product) { %>
<tr>
<td><%= product.title %></td>
<td>$<%= parseFloat(product.price).toFixed(2) %></td>
<td><%= product.category %></td>
<td>
<% if (product.image == "") { %>
<img src="/images/noimage.png">
<% } else { %>
<img src="product_images/<%= product._id %>/<%= product.image %>">
<% }%>
</td>
<td>Edit</td>
<td>Delete</td>
<% } %>
</tr>
<% }); %>
</tbody>>
</table>>
<% } else { %>
<h3 class="text-center">There are no products.</h3>>
<% } %>
<%- include('../_layouts/adminfooter') %>
Before your closing </tr>, the line
<% } %>
is superfluous. The parser therefore interprets this as ending the callback function of forEach() without providing further arguments or closing the
round bracket of the function call. (The error message is actually pretty clear about what's going on, if you think about it. :))
By the way you also got two superflous > behind your closing </tbody> and </table>.
Here's a working fixed code example you can put into https://ionicabizau.github.io/ejs-playground/
<%
var products = [
{title: "foobar", category: "things", image: "", _id: 1, price: 0}
];
var count = products.length;
%>
<h2 class='page-title'>Products</h2>
<br>
Add a new product
<br><br>
<% if (products.length > 0) { %>
<table class="table table-striped">
<thead>
<tr class="home">
<th>Product</th>
<th>Price</th>
<th>Category</th>
<th>Product Image</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<% products.forEach(function(product) { %>
<tr>
<td><%= product.title %></td>
<td>$<%= parseFloat(product.price).toFixed(2) %></td>
<td><%= product.category %></td>
<td>
<% if (product.image == "") { %>
<img src="/images/noimage.png">
<% } else { %>
<img src="product_images/<%= product._id %>/<%= product.image %>">
<% }%>
</td>
<td>Edit</td>
<td>Delete</td>
</tr>
<% }); %>
</tbody>
</table>
<% } else { %>
<h3 class="text-center">There are no products.</h3>>
<% } %>

Web Page Loading Time Long for Rails web page

I'm developing a web page using ruby on rails.
I found one of my page loading time is very long.
I use pingdom to test it,here is the result:
Then I refer to this and Yslow report
some of the F grade options:
1.Grade F on Make fewer HTTP requests
This page has 78 external Javascript scripts. Try combining them into one.
Decreasing the number of components on a page reduces the number of HTTP requests required to render the page, resulting in faster page loads. Some ways to reduce the number of components include: combine files, combine multiple scripts into one script, combine multiple CSS files into one style sheet, and use CSS Sprites and image maps.
2.Grade F on Add Expires headers
There are 82 static components without a far-future expiration date.
3.Grade F on Use cookie-free domains
There are 81 components that are not cookie-free
4.Grade F on Put JavaScript at bottom
There are 78 JavaScript scripts found in the head of the document
I feel mostly is the messy java script or CSS cause the long waiting time.
Suggestion is put java script at end of page.
problem is:for ruby on rails,my Javascript is in file : app\assets\javascripts\custom.js
while my view page is in: app/view/sth.html.erb
I have no idea how to put it at the end.
attached is my code in app/view/sth.html.erb
<h3>Project Information</h3>
<div class="project-report">
<table class="content-table">
<tr>
<td><strong>PJO Number</strong></td>
<td><%= #project.job_number %></td>
</tr>
<tr>
<td><strong>Client</strong></td>
<td><%= #project.client_name %></td>
</tr>
<tr>
<td><strong>Location</strong></td>
<td><%= #project.jobsite_location %></td>
</tr>
<br>
<td>
<tr>
<td><strong>Contacts</strong></td>
</tr>
<br>
<table class="yellow-header-table contact-table">
<tr>
<th>Name</th>
<th>Designation</th>
<th>Email</th>
<th>SMS</th>
<th>Fax</th>
</tr>
<% #project.contacts.each do |contact| %>
<tr>
<td><%= contact.contact_person_name %></td>
<td><%= contact.designation %></td>
<td><%= contact.email %></td>
<td><%= contact.phone_number %></td>
<td><%= contact.fax_number %></td>
</tr>
<% end %>
</table>
</td>
</table>
<table class="yellow-header-table">
<tr>
<th>Instrument Type</th>
<th>Total</th>
<th>Installed</th>
<th>Active</th>
<th>Remarks</th>
</tr>
<tr>
<td>first Meter</td>
<td><%= #project.quantity_active %></td>
<td><%= #project.quantity_active %></td>
<td><%= #project.quantity_active %></td>
<td><%= #project.sound_remarks %></td>
</tr>
</table>
<div style='margin-left:50px;float:left;'>
<button id="buttonN" class="btn btn-info" style="width:190px;">View Data1</button>
<button id="buttonV" class="btn btn-info" style="margin-left:50px;width:190px;">View Data2</button>
<button id="buttonR" class="btn btn-info" style="margin-left:50px;width:190px;">Generate Report</button>
</div>
<div id="report-reviewn" class="hidden" style='margin-top:55px;'>
<% if (#devices.count > 0) %>
<h4 style="width:100%">1st Devices</h4>
<table id="tableselect" class="yellow-header-table">
<tr>
<th scope="Row">Select</th>
<th>Device ID</th>
<th>Brand</th>
<th>Address</th>
</tr>
<%= form_tag viewdata_devices_path,class:"form-horizontal viewlist-form" do %>
<% #project.first_devices.each do |first_device| %>
<tr>
<th scope='col'>
<%= radio_button_tag(:deviceID, first_device.id ) %></th>
<td><%= first_device.device_id %></td>
<td><%= first_device.serial_number %></td>
<td><%= first_device.brand %></td>
<td><%= first_device.last_calibration_date %></td>
<td><%= first_device.remarks %></td>
<td><%= #project.project_type %></td>
<td>
<select style='border:none;'>
<option><%= first_device.device_location %></option>
<option><%= first_device.device_latlng %></option>
</select>
</td>
</tr>
</tr>
<% end %>
</table>
<table class="table-row">
<tr>
<th> <%= text_field_tag 'startday', nil, placeholder: 'Start Date',style:'width:100px;', class: "date-picker" %></th>
<th> <%= text_field_tag 'endday', nil, placeholder: 'End Date' ,style:'width:100px;',class: "date-picker" %><th>
<%= hidden_field_tag "project_id", #project.id %>
<th> <%= submit_tag "View Data",class: "btn" %></th>
<% end %>
</tr>
</table>
<% else %>
<p style="width:100%;text-align:left;margin-left:50px;">There is no first device for this project </p>
<% end %>
</div>
<div id="report-reviewv" class="hidden" style='margin-top:55px;' >
<% if (#vdevices.count > 0) %>
<table class="yellow-header-table">
<h4 style="width:100%">second Devices</h4>
<tr>
<th scope="Row">Select</th>
<th>Device ID</th>
<th>Address</th>
</tr>
<%= form_tag viewdata_second_devices_path,class:"form-horizontal viewlist-form" do %>
<% #project.second_devices.each do |second_device| %>
<tr>
<th scope='col'>
<%= radio_button_tag(:deviceID, second_device.id ) %></th>
<td><%= second_device.device_id %></td>
<td><%= second_device.serial_number %></td>
<td><%= second_device.brand %></td>
<td><%= second_device.current_trigger_value %></td>
<td><%= second_device.last_calibration_date %></td>
<td><%= second_device.remarks %></td>
<td><%= #project.project_type %></td>
<td>
<select style='border:none;'>
<option><%= second_device.device_location %></option>
<option><%= second_device.device_latlng %></option>
</select>
</td>
</tr>
<% end %>
</table>
<table class="table-row">
<tr>
<th> <%= text_field_tag 'startday', nil, placeholder: 'Start Date',style:'width:100px;', class: "date-picker" %></th>
<th> <%= text_field_tag 'endday', nil, placeholder: 'End Date' ,style:'width:100px;',class: "date-picker" %><th>
<%= hidden_field_tag "project_id", #project.id %>
<th> <%= submit_tag "View Data",class: "btn" %></th>
<% end %>
</tr>
</table>
<% else %>
<p style="width:100%;text-align:left;margin-left:50px;">There is no second device for this project </p>
<% end %>
</div>
<div id="report-reviewr" class="hidden" style='margin-top:100px;'>
<div class="report-forms report-left-align">
<span><strong>Report Type</strong></span>
<%= select_tag "report-type", options_for_select([["first", "first-report"], ["second", "second-report"]]), :prompt => "Choose Report" %>
<div id="first-report" class="report-form hidden">
<%= form_tag report_first_devices_path, class: "form-horizontal device-form", target: "_blank" do %>
<div class="control-group">
<%= label_tag "Choose Devices", nil, class: "control-label" %>
<div class="controls">
<% selected_first_device = #project.first_devices.blank? ? nil : #project.first_devices.first.id %>
<%= select_tag "devices", options_from_collection_for_select(#project.first_devices, "id", "serial_number", selected_first_device), :multiple => false %>
</div>
</div>
<div class="control-group">
<%= label_tag "Choose Time", nil, class: "control-label" %>
<div class="controls">
<%= text_field_tag "time_range", nil, class: "input-large date-picker" %>
</div>
</div>
<%= hidden_field_tag "project_id", #project.id %>
<%= hidden_field_tag "device_type", "first" %>
<div class="control-group">
<div class="controls">
<%= submit_tag "Generate Report", class: "btn" %>
</div>
</div>
<% end %>
</div>
<div id="second-report" class="report-form hidden">
<%= form_tag report_second_devices_path, class: "form-horizontal device-form", target: "_blank" do %>
<div class="control-group">
<%= label_tag "Choose Devices", nil, class: "control-label" %>
<div class="controls">
<% selected_second_device = #project.second_devices.blank? ? nil : #project.second_devices.first.id %>
<%= select_tag "devices", options_from_collection_for_select(#project.second_devices, "id", "serial_number", selected_second_device), :multiple => false %>
</div>
</div>
<div class="control-group">
<%= label_tag "Choose Time", nil, class: "control-label" %>
<div class="controls">
<%= text_field_tag "time_range", nil, class: "input-large date-picker" %>
</div>
</div>
<%= hidden_field_tag "project_id", #project.id %>
<%= hidden_field_tag "device_type", "second" %>
<div class="control-group">
<div class="controls">
<%= submit_tag "Generate Report", class: "btn" %>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
anyone can give some suggestions?
In the default app/views/layouts/ directory there should be a file named application.html.erb. This file contains the following lines within the head
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
If you move this to just below the closing body tag all your JS will be at the bottom of the page on every pageload. This is the most effective way of not blocking the rendering of the page client side.
All your files will be included via the compiled application.js in the end.
EDIT 1
As you've seen in your YSLOW results, you have alot - and with that i mean alot of JS. All these files perform a dns lookup (they will be cached but still frequently updated). Every n of dns lookups comes with a penalty due to the fact that a cached dns lookup only exists for something upto a day. Reducing the number of requests is key to making your application alot faster.
Info about the asset pipeline
SO post of assets not being compiled into one file
You may want to look at these for extra information about the asset pipeline and / or what to do to compress your assets.

Password fields not clearing on submit in asp.net mvc

I have a user preference page in which the user can type in their current password, new password and confirm new password. When the user submits the form it sends them to an action. The problem is that when the form submits, the password fields stay filled. I want them to clear. I attempted javascript but when I use document.preferences.submit(), the submit isn't fired, or the action isn't fired, or both. Here is the code:
<script language="JavaScript" type="text/javascript">
function clearpwd() {
document.preferences.submit();
document.preferences.currentPassword.value = '';
document.preferences.newPassword.value = '';
document.preferences.confirmPassword.value = '';
}
</script>
<% using (Html.BeginForm("ChangePreferences", "Home", FormMethod.Post, new { id="preferences", name="preferences" })) { %>
<div>
<div style="text-align:left; width:500px;">
<div class="FormLabel">User Information:</div>
<table border="0" cellpadding="4" cellspacing="0">
<tr>
<td>First Name:</td>
<td>
<%= Html.TextBox("firstName")%>
<%= Html.ValidationMessage("FirstName") %>
</td>
</tr>
<tr>
<td>Last Name:</td>
<td>
<%= Html.TextBox("lastName") %>
<%= Html.ValidationMessage("LastName") %>
</td>
</tr>
<tr>
<td>New email:</td>
<td>
<%= Html.TextBox("email")%>
<%= Html.ValidationMessage("Email") %>
</td>
</tr>
<tr>
<td>Billing Method:</td>
<td>
<%=Html.RadioButton("billingMethod", 'E', new { id = "BillingMethod_E", value = 'E' })%><label for="BillingMethod_E">Electronic</label>
<%=Html.RadioButton("billingMethod", 'M', new { id = "BillingMethod_M", value = 'M' })%><label for="BillingMethod_M">Mailing</label>
</td>
</tr>
</table>
</div>
<br /><br />
<div style="text-align:left; width:500px;">
<div class="FormLabel">Login and Security Information:</div>
<table border="0" cellpadding="4" cellspacing="0">
<tr>
<td>Current Password</td>
<td>
<%= Html.Password("currentPassword") %>
<%= Html.ValidationMessage("currentPassword") %>
</td>
</tr>
<tr>
<td>New password:</td>
<td>
<%= Html.Password("newPassword") %>
<%= Html.ValidationMessage("newPassword") %>
</td>
</tr>
<tr>
<td>Confirm new password:</td>
<td>
<%= Html.Password("confirmPassword") %>
<%= Html.ValidationMessage("confirmPassword") %>
</td>
</tr>
<tr>
<td>Security Question:</td>
<td>
<%= Html.TextBox("securityQuestion") %>
<%= Html.ValidationMessage("SecurityQuestion") %>
</td>
</tr>
<tr>
<td>Security Answer:</td>
<td>
<%= Html.Password("securityAnswer") %>
<%= Html.ValidationMessage("SecurityAnswer") %>
</td>
</tr>
</table>
</div>
<br /><br />
<table>
<tr>
<td></td>
<td><input type="submit" value="Change Preferences" onclick="clearpwd()" /></td>
</tr>
</table>
</div>
<% } %>
To Debug JavaScript Problems, better post the generated HTML
To debug JavaScript problems easier, use Firefox browser with Firebug Extension.
Edit: You are trying to clear the password, after page is submitted. After submission page navigates to another page, so i think, JavaScript won't affect any DOM elements after that.
You can try the following sequence.
Store Username and Password on JavaScript variables.
clear Username and Password values.
Post to the page with the stored values.
It could be your browser filling in the password field if you have it set to remember your password(s). I've had this happen to me.

Categories