How to update data in index.html.erb in ruby on rails? - ruby-on-rails

I create one app about product that has name, price and description. In index.html.erb, I wanna add textbox to each of them and click edit link can edit don't need go to /products/id/edit.
How can I edit the product data?
<% #products.each do |product| %>
<tr>
<form action="/products/<%= product.id %>" class="edit_person_<%= product.id %>" id="edit_person_<%= product.id %>" method="post">
<input name="_method" type="hidden" value="patch" />
<input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
<td><input id="product_name" name="product[name]" type="text" value="<%= product.name %>" /><br /></td>
<td><input id="product_price" name="product[price]" type="text" value="<%= product.price %>" /><br /></td>
<td><input id="product_descr" name="product[descr]" type="text" value="<%= product.descr %>" /><br /></td>
<td><input name="commit<%= product.id %>" type="submit" value="edit" /></td>
</form>
</tr>
<% end %>

You need to use AJAX if you want to update your data without reloading the edit.html.erb file. Below, I'm gonna show it how to this for one field, rest you can assume yourself.
<input id="product_price" name="product[price]" type="text" value="<%= product.price %>" />
In your js.erb file, you can write:
$("#product_price").focusout(function() {
var productPrice = $(this).val();
$.ajax({
url: "/products/<%= product.id %>/edit",
type: "POST",
data: { product_price: productPrice}, // same way, other attributes
success: function() {
console.log("The result successfully came back from ther server.");
// Now, here you can show a notice to the user that he has successfully update the record without reloading the page.
}
});
});

Related

Fill table with data from knockout js observableArray then take one item from the list and display it in the form

Good day
I am new to knockout js and what is described in the title is what I am trying to do. The first part I can do but I just cant figure out how to put values into form here is some code.
With this I get the data:
$.ajax('#Url.Action("GetEducations", "Candidate")', {
data: { id: #ViewBag.CandidateId },
type: "post", dataType: 'json'
})
.done(function (result) {
var mappedEducations = $.map(result, function (item) { return new Education(item) });
self.educations(mappedEducations);
})
.fail(function (xhr, status) {
alert('#Resources.WebAppLocalization.general_Error');
});
Here I put them into table:
<tbody data-bind="foreach: educations, visible: educations().length > 0">
<tr>
<td data-bind="text: InstitutionName"></td>
<td data-bind="text: Qualification"></td>
<td data-bind="text: EducationFrom"></td>
<td data-bind="text: EducationTill"></td>
<td>
<a class="link" data-bind="attr: {href: ''}, click: $parent.editEducationFill, clickBubble: false"></a>
</td>
</tr>
</tbody>
Now when someone click's on edit link it goes here:
self.editEducationFill = function (education) {
//TODO
}
From here I want the passed object to go to edit form here:
<form id="FormID">
<div class="detValue"><input type="text" data-bind="value: InstitutionName"/> </div>
<div class="detValue"><input type="text" data-bind="value: Qualification" /></div>
<div class="detValue"><input type="text" data-bind="value: EducationFrom" /></div>
<div class="detValue"><input type="text" data-bind="value: EducationTill" /></div>
</form>
However I just cant get it to work.
For any help thank you in advance
Add an observable to your view model that will hold the education object you want to edit.
self.educationToEdit = ko.observable();
In your method: self.editEducationToFill, set the educationToEdit to the one that's passed into the method.
self.editEducationFill = function(education){
self.educationToEdit(education);
}
In your view, add a data-binding that tells the form to use the educationToFill observable to display on your page.
<form id="FormID" data-bind="with: educationToEdit">
<div class="detValue"><input type="text" data-bind="value: InstitutionName"/></div>
<div class="detValue"><input type="text" data-bind="value: Qualification" /></div>
<div class="detValue"><input type="text" data-bind="value: EducationFrom" /></div>
<div class="detValue"><input type="text" data-bind="value: EducationTill" /></div>
</form>

Executing the same partial view multiple times in the same view

I am new to MVC and would like some help.
I have a view (below) which displays the products, next to each other. Till here everything is fine.
#foreach (var item in Model)
{
<a href="#Url.Action("showProductDetails", "Shared", new { ProductID = item.ProductID }, null)">
<div class='OutsideDiv' >
<table class='DivBorder'>
<tr >
<td class='title'>
#item.ProductName
</td>
</tr>
<tr >
<td class='imageBox'>
<img alt='' src="#item.ImageURL" />
</td>
</tr>
<tr>
<td class='title'>
#Html.Action("showAverageRating", "Rating" , new { ProductID = item.ProductID } ) *************
</td>
</tr>
<tr>
<td class='desc'>
#item.Description
</td>
</tr>
<tr>
<td class='price'>
€ #item.Price
</td>
</tr>
</table>
</div>
<script type='text/javascript'> $('.DivBorder').mouseover(function () { $(this).css('border-color', '#0953cb'); $(this).css('background-color', '#eaeaea'); }); $('.DivBorder').mouseout(function () { $(this).css('border-color', '#bdbdbd'); $(this).css('background-color', '#f6f6f6'); });</script>
</a>
}
In the line marked with '****' above I am calling another view (showAverageRating) which for now is just displaying 5 rating stars with the first 3 starts selected.
<input class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
<input checked="checked" class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
<input class="star " name="adv1" type="radio" />
The problem is that on the second item, when the rating stars view (above partial view) is called again, the stars are displayed next to the stars of the first product, picture below.
I think I have to use something else rather than Html.Action?
EDIT : showAverageRating Code
public ActionResult showAverageRating(int ProductID)
{
decimal averageRating = new RatingsService.RatingsClient().getAverageRating(ProductID);
ViewData["averageRating"] = averageRating;
return PartialView();
}
The problem was that the name of the stars where identical, so I included the productID with their name, like below.
showAverageRating partial view
#{decimal averageRating = ViewBag.averageRating;}
#{int productID = ViewBag.productID;}
<div id="averageRating" >
<input class="star" name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
<input checked="checked" class="star " name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
<input class="star " name="star+#productID" type="radio" />
</div>

Emberjs - Create 'Edit' action that edits a model without leaving '/models' url

I need help creating an 'edit' action that selects a specific model from a list of models, and in that table, edits the model. A quick-edit of sorts.
<tbody>
{{#each}}
<tr class="people-list">
<td>
<input type="checkbox" class="toggle">
<label class="category-text">{{#linkTo 'category' this}}{{Name}}{{/linkTo}} </label>
<img class="table-img" src="images/x.png">
<img class="table-img" {{action 'edit'}} src="images/pencil-grey.png">
</td>
</tr>
{{/each}}
</tbody>
By clicking {{action 'edit'}}, {{Name}} becomes and editable input. This is all done without leaving the '/categories' url.
Thanks guys :D
<tbody>
{{#each}}
<tr class="people-list">
<td>
<input type="checkbox" class="toggle">
{{#if isEdit}}
{{input type="text" valueBinding="Name" name="Name"}}
{{else}}
<label class="category-text">{{#linkTo 'category' this}}{{Name}}{{/linkTo}}</label>
{{/if}}
<img class="table-img" src="images/x.png">
<img class="table-img" {{action 'edit'}} src="images/pencil-grey.png">
</td>
</tr>
{{/each}}
</tbody>
And then on the controller:
actions: {
edit:function(){
this.set('isEdit', true);
}
}

IEnumerable is null when I expect values

I am using the approach in this article to return a list of objects that are posted to my action. My method looks like:
//
// POST: /LeaveRequest/Create
[Authorize, HttpPost]
public ActionResult Create(LeaveRequest leaveRequest, IEnumerable<DayRequested> requestedDays)
{
return RedirectToAction("Index", lrRepository.GetLeaveRequests(472940821));
}
leaveRequest has the data that I expect. requestedDays contains the number of rows I expect, but all of the rows contain null in each field. Any ideas of what I may be missing?
Here is the View code:
Create.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<EmployeePayroll.ViewModels.LeaveRequestViewModel>" %>
<%# Import Namespace="EmployeePayroll.Helpers"%>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Create New Leave Request</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create New Leave Request</h2>
<div><%= Html.ActionLink("Back to List", "Index") %></div>
<%= Html.Partial("RequestEditor", Model) %>
<div><%= Html.ActionLink("Back to List", "Index") %></div>
</asp:Content>
RequestEditor.ascx
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<EmployeePayroll.ViewModels.LeaveRequestViewModel>" %>
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Request Details</legend>
<table>
<tbody id="editorRows">
<tr><th>Date</th><th>Time</th><th>Hours</th><th>Request Type</th><th></th></tr>
<% foreach (var item in Model.DaysRequested)
Html.RenderPartial("RequestedDayRow", new EmployeePayroll.ViewModels.LeaveRequestRow(item, Model.LeaveRequestType)); %>
</tbody>
</table>
<p><%= Html.ActionLink("Add Day", "BlankRequestedDayRow", null, new { id = "addItem" })%></p>
<p>Type your time to sign your request.</p>
<p><%= Html.LabelFor(model => model.LeaveRequest.EmployeeSignature) %>: <%= Html.TextBoxFor(model => model.LeaveRequest.EmployeeSignature, new { Class="required" })%></p>
<p><%= Html.LabelFor(model => model.LeaveRequest.EmployeeComment) %>: <%= Html.TextBoxFor(model => model.LeaveRequest.EmployeeComment) %></p>
<p><input type="submit" value="Submit Request" /></p>
</fieldset>
<% } %>
RequestedDayRow.ascx
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<EmployeePayroll.ViewModels.LeaveRequestRow>" %>
<%# Import Namespace="EmployeePayroll.Helpers"%>
<tr class="editorRow">
<% using (Html.BeginCollectionItem("requestedDays"))
{ %>
<td><%= Html.TextBoxFor(model => model.DayRequested.DateOfLeave, new { Class = "datepicker", Maxlength = "10" })%></td>
<td><%= Html.TextBoxFor(model => model.DayRequested.TimeOfLeave, new { Class = "timedropdown", Maxlength = "8" })%></td>
<td><%= Html.TextBoxFor(model => model.DayRequested.HoursRequested, new { Class = "hoursdropdown", Maxlength = "4" })%></td>
<td><%= Html.DropDownListFor(model => model.DayRequested.RequestType,
new SelectList(Model.LeaveRequestType, "Value", "Text", Model.DayRequested.RequestType), "(Select)")%></td>
<td><img src="../../images/site_icons/16/69.png" title="Delete" alt="Delete" border="0" /></td>
<% } %>
</tr>
Here is the generated form:
<form method="post" action="/LeaveRequest/Create">
<fieldset>
<legend>Request Details</legend>
<table>
<tbody id="editorRows">
<tr><th>Date</th><th>Time</th><th>Hours</th><th>Request Type</th><th></th></tr>
<tr class="editorRow">
<input type="hidden" value="c43391a3-7fe4-4514-8b27-d00995d64848" autocomplete="off" name="requestedDays.index">
<td><input type="text" value="11/17/2010" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].DayRequested.DateOfLeave" id="requestedDays_c43391a3-7fe4-4514-8b27-d00995d64848__DayRequested_DateOfLeave" maxlength="10" class="datepicker"></td>
<td><input type="text" value="8:00 AM" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].DayRequested.TimeOfLeave" id="requestedDays_c43391a3-7fe4-4514-8b27-d00995d64848__DayRequested_TimeOfLeave" maxlength="8" class="timedropdown"></td>
<td><input type="text" value="8" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].DayRequested.HoursRequested" id="requestedDays_c43391a3-7fe4-4514-8b27-d00995d64848__DayRequested_HoursRequested" maxlength="4" class="hoursdropdown"></td>
<td><select name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].DayRequested.RequestType" id="requestedDays_c43391a3-7fe4-4514-8b27-d00995d64848__DayRequested_RequestType"><option value="">(Select)</option>
</select></td>
<td><a class="deleteRow" href="#"><img border="0" alt="Delete" title="Delete" src="../../images/site_icons/16/69.png"></a></td>
</tr>
<tr class="editorRow">
<input type="hidden" value="a24b74f6-2947-4ec5-a817-f938d6fe4e24" autocomplete="off" name="requestedDays.index">
<td><input type="text" value="11/17/2010" name="requestedDays[a24b74f6-2947-4ec5-a817-f938d6fe4e24].DayRequested.DateOfLeave" id="requestedDays_a24b74f6-2947-4ec5-a817-f938d6fe4e24__DayRequested_DateOfLeave" maxlength="10" class="datepicker"></td>
<td><input type="text" value="8:00 AM" name="requestedDays[a24b74f6-2947-4ec5-a817-f938d6fe4e24].DayRequested.TimeOfLeave" id="requestedDays_a24b74f6-2947-4ec5-a817-f938d6fe4e24__DayRequested_TimeOfLeave" maxlength="8" class="timedropdown"></td>
<td><input type="text" value="8" name="requestedDays[a24b74f6-2947-4ec5-a817-f938d6fe4e24].DayRequested.HoursRequested" id="requestedDays_a24b74f6-2947-4ec5-a817-f938d6fe4e24__DayRequested_HoursRequested" maxlength="4" class="hoursdropdown"></td>
<td><select name="requestedDays[a24b74f6-2947-4ec5-a817-f938d6fe4e24].DayRequested.RequestType" id="requestedDays_a24b74f6-2947-4ec5-a817-f938d6fe4e24__DayRequested_RequestType"><option value="">(Select)</option>
</select></td>
<td><a class="deleteRow" href="#"><img border="0" alt="Delete" title="Delete" src="../../images/site_icons/16/69.png"></a></td>
</tr>
</tbody>
</table>
<p><a id="addItem" href="/LeaveRequest/BlankRequestedDayRow">Add Day</a></p>
<p>Type your time to sign your request.</p>
<p><label for="LeaveRequest_EmployeeSignature">Employee Signature</label>: <input type="text" value="" name="LeaveRequest.EmployeeSignature" id="LeaveRequest_EmployeeSignature" class="required"></p>
<p><label for="LeaveRequest_EmployeeComment">Employee Comment</label>: <input type="text" value="" name="LeaveRequest.EmployeeComment" id="LeaveRequest_EmployeeComment"></p>
<p><input type="submit" value="Submit Request"></p>
</fieldset>
</form>
The form posts the following information:
Parametersapplication/x-www-form-urlencoded
LeaveRequest.EmployeeComm... Comment
LeaveRequest.EmployeeSign... Michael Wills
requestedDays.index 549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2
requestedDays.index 2838b025-d971-4d98-a081-5ea0c559aebb
requestedDays[2838b025-d9... 11/17/2010
requestedDays[2838b025-d9... 8
requestedDays[2838b025-d9... 1
requestedDays[2838b025-d9... 8:00 AM
requestedDays[549a7c9a-9c... 11/17/2010
requestedDays[549a7c9a-9c... 8
requestedDays[549a7c9a-9c... 1
requestedDays[549a7c9a-9c... 8:00 AM
Source
Content-Type: application/x-www-form-urlencoded
Content-Length: 907
requestedDays.index=549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2&requestedDays%5B549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2%5D.DayRequested.DateOfLeave=11%2F17%2F2010&requestedDays%5B549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2%5D.DayRequested.TimeOfLeave=8%3A00+AM&requestedDays%5B549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2%5D.DayRequested.HoursRequested=8&requestedDays%5B549a7c9a-9c7d-4032-a1cd-6bfda92bf1f2%5D.DayRequested.RequestType=1&requestedDays.index=2838b025-d971-4d98-a081-5ea0c559aebb&requestedDays%5B2838b025-d971-4d98-a081-5ea0c559aebb%5D.DayRequested.DateOfLeave=11%2F17%2F2010&requestedDays%5B2838b025-d971-4d98-a081-5ea0c559aebb%5D.DayRequested.TimeOfLeave=8%3A00+AM&requestedDays%5B2838b025-d971-4d98-a081-5ea0c559aebb%5D.DayRequested.HoursRequested=8&requestedDays%5B2838b025-d971-4d98-a081-5ea0c559aebb%5D.DayRequested.RequestType=1&LeaveRequest.EmployeeSignature=Michael+Wills&LeaveRequest.EmployeeComment=Comment
Looks like you may need to remove DayRequested from your hidden form field name.
For example:
... I removed some of the attributes because the only thing that's changed here is the name attribute.
<input type="hidden" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].DateOfLeave" value="11/17/2010" />
<input type="hidden" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].TimeOfLeave" value="8:00 AM" />
<input type="hidden" name="requestedDays[c43391a3-7fe4-4514-8b27-d00995d64848].HoursRequested" value="8" />
...
As discussed in the question comments, it seems odd that ASP.NET MVC would generate the source you gave, as that suggests that each RequestedDay object has a single property called RequestedDay.
The object you're binding to is called requestedDays, and the guid is an indication of which position in the collection you're binding to (stating the obvious here, I know!). Therefore, stating the object name (DayRequested) doesn't make any sense, since the model binder should already know this, and just needs to know which property of that class it's dealing with.
see this post from Haacked - Model Binding To A List
it might help you

simple question: Difficulty in declaring and using variable

What is wrong with the following code: I`m having the error message
Error 1 ; expected
<%if (Model.ReferenceFields != null)
{%>
<%int count = 1; %>
<%foreach (var referenceName in Model.ReferenceFields)
{%>
<%var value = "value"; %>
<%count++; %>
<%value = value + count.ToString(); %>
<tr>
<td><input type="hidden" name="Tests.Index" value='<%value%>' /></td>
<td><input type="text" name="Tests['<%value%>'].Value"/></td>
<td><input type="button" value= "Add" /></td></tr>
<%}
%>
<%}
%>
The basic problem is lines like this
<input type="hidden" name="Tests.Index" value='<%value%>' />
So you're wanting to write out the contents of value into the html but thats not the way to do it. It should be
<input type="hidden" name="Tests.Index" value='<% Response.Write(value); %>' />
or a shortcut for Response.Write is <%= so
<input type="hidden" name="Tests.Index" value='<%= value %>' />
ASP101 - Writing Your First ASP.NET Page
The other problem is that the formatting of your code is, quite frankly butt ugly and you're making it hard work for yourself when trying to read it. Try this instead.
<%
if (Model.ReferenceFields != null)
{
int count = 1;
foreach (var referenceName in Model.ReferenceFields)
{
var value = "value";
count++;
value = value + count.ToString();
%>
<tr>
<td><input type="hidden" name="Tests.Index" value='<%= value %>' /></td>
<td><input type="text" name="Tests['<%= value %>'].Value"/></td>
<td><input type="button" value= "Add" /></td></tr>
<%
}
}
%>

Resources