Display Nested object - thymeleaf

I use spring boot with thymeleaf, in a page try to display a form and it's nested object.
My object Factories has
id
name
List
When I display
<form id="factoriesForm" th:object="${factories}" >
...
...
<table id="machinesTable" class="table table-striped table-hover responsive">
<thead>
<tr>
<th th:text="#{name}">Name</th>
<th th:text="#{description}">Description</th>
<th></th>
</tr>
</thead>
<tbody>
<tr th:each="machine, stat : ${machines}">
<td>
<input type="hidden" th:id="${'machineId-'+stat.index}" th:field="*{machines[__${stat.index}__].id}" />
<input type="text" class="form-control" th:id="${'machineName-'+stat.index}" th:placeholder="#{name.placeholder}" placeholder="Name" th:field="*{machines[__${stat.index}__].name}" />
</td>
<td> <input type="text" class="form-control" th:id="${'machineDescription-'+stat.index}" th:placeholder="#{description.placeholder}" placeholder="Description" th:field="*{machines[__${stat.index}__].description}" /></td>
<td> <i class="fas fa-trash-alt"></i></td>
</tr>
</tbody>
</table>
</form>
My factories has many machines, but none is displayed
Any idea?

change
${factories}
for
*{factories}

Related

Add text boxes data to grid temporarily using knockout.js

Html code
<label class="control-label">Contact Person</label>
<input class="form-control" type="text" placeholder="Enter Contact name" data-bind="value: ContactPerson" data-validate='{"required":"true"}'><br />
<label class="control-label">ContactNo</label>
<input class="form-control" type="tel" data-bind="value: ContactNo" placeholder="ContactNo" data-validate='{"required":"true"}'><br />
<label class="control-label">E-Mail</label>
<input class="form-control" type="email" data-bind="value: Email" placeholder="Email" data-validate='{"required":"true","email":"true"}'><br />
<table class="table table-hover table-bordered" id="listTable">
<thead>
<tr>
<th>ContactPerson</th>
<th>ContactNo</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody data-bind="template:{name: 'Process-list',
foreach: rootViewModel.BodyContent.ProcessList }">
</tbody>
</table>
when I click on add button the data in the three text box should bind to grid ,
and when i click on delete button of row in grid it should disappear for this i need viewmodel.
Thanks
Here's a quick view model that does the requirements. I selected ContactNo as the primary key since they're supposed to be unique. You can use ids if needed instead. It would also be a good idea to run your validations before add method is called.
var viewModel = function(){
var self = this;
self.ContactPerson = ko.observable();
self.ContactNo = ko.observable();
self.Email = ko.observable();
self.ProcessList = ko.observableArray();
self.add = function(){
self.ProcessList.push({
ContactPerson: self.ContactPerson(),
ContactNo: self.ContactNo(),
Email: self.Email(),
});
self.ContactPerson('');
self.ContactNo('');
self.Email('');
};
self.delete = function(data, event){
self.ProcessList.remove(function(listObject){
return listObject.ContactNo === data.ContactNo;
});
};
};
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<label class="control-label">Contact Person</label>
<input class="form-control" type="text" placeholder="Enter Contact name" data-bind="value: ContactPerson" data-validate='{"required":"true"}'><br />
<label class="control-label">ContactNo</label>
<input class="form-control" type="tel" data-bind="value: ContactNo" placeholder="ContactNo" data-validate='{"required":"true"}'><br />
<label class="control-label">E-Mail</label>
<input class="form-control" type="email" data-bind="value: Email" placeholder="Email" data-validate='{"required":"true","email":"true"}'><br />
<button data-bind="click: add">Add Data</button>
<table class="table table-hover table-bordered" id="listTable">
<thead>
<tr>
<th>ContactPerson</th>
<th>ContactNo</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody data-bind="template:{name: 'Process-list',
foreach: ProcessList }">
</tbody>
</tbody>
</table>
<script type="text/html" id="Process-list">
<tr>
<td data-bind="text: ContactPerson"></td>
<td data-bind="text: ContactNo"></td>
<td data-bind="text: Email"></td>
<td><button data-bind="click: $root.delete">Delete</button></td>
</tr>
</script>

POST action returns the model in a valid state but returns Model.Count as 0 when using foreach or for loop

As shown in my post here the GET action method Test(..) works fine when using foreach loop in the corresponding Test.chtml view but the POST action method Test(...) returns null. But, as mentioned by many users, the foreach is not reliable for POST method. So, I decided to use the for loop as shown below. But that returned unexpected results in the view since, according to this post, in a foreachloop type casting is done automatically but in for loop you have to type cast the objects Model[i].BlogID etc to a proper class object type.
So, I decided to type cast the objects Model[i].BlogID etc to a BlogsWithRelatedPostsViewModel class object type as shown in the second version of Test.cshml view below; and this time the Test.cshtml view is displayng the correct records. But although the submit button in the view is sending a a valid model (ModelState.IsValid is true) the Model.Count is 0 that results in no update to database. Why Model.Count is 0 and how to correct it? As you can see below the html page source of the view is showing the name attributes of the tags matching the property values in the View Model.
Note: For complete code, please see this OP. I'm using ASP.NET Core with EF Core and Tag Helpers.
Test.cshtml view with for loop - without type casting the loop objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="#Model[i].BlogID" /></td>
<td><input type="hidden" asp-for="#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="#Model[i].Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="#Model[i].Title" />
</td>
<td>
<input asp-for="#Model[i].Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
Test.cshtml view with for loop objects being casted as BlogsWithRelatedPostsViewModel class objects:
#model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>
#using ASP_Core_Blogs.Models.BlogPostViewModels
#{ ViewData["Title"] = "Index"; }
<div class="row">
<div class="col-md-12">
<form asp-controller="Blogs" asp-action="Test" asp-route-returnurl="#ViewData["ReturnUrl"]" method="post">
#{
IEnumerable<SelectListItem> yearsList = (IEnumerable<SelectListItem>)ViewBag.YearsList;
var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
<strong>Select a Post Year</strong>
<h6>Choose a year and a URL to begin:</h6>
<label>Year:</label><select asp-for="#currentlySelectedIndex" asp-items="yearsList"></select><input type="submit" class="btn btn-default" name="GO" value="GO" />
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th>Url</th>
<th>Title</th>
<th>Content</th>
</tr>
</thead>
<tbody>
#for (int i=0; i< Model.Count(); i++)
{
<tr>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).BlogID" /></td>
<td><input type="hidden" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).PostID" /></td>
<td>
<input type="text" asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Url" style="border:0;" readonly />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Title" />
</td>
<td>
<input asp-for="((BlogsWithRelatedPostsViewModel)#Model[i]).Content" />
</td>
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-default">Save</button>
</form>
</div>
</div>
A Portion of html generated by View after Submit:
<tr>
<td><input type="hidden" data-val="true" data-val-required="The BlogID field is required." id="BlogID" name="BlogID" value="1" /></td>
<td><input type="hidden" data-val="true" data-val-required="The PostID field is required." id="PostID" name="PostID" value="1" /></td>
<td>
<input type="text" style="border:0;" readonly id="Url" name="Url" value="blog1#test.com" />
</td>
<td>
<input type="text" id="Title" name="Title" value="Title1" />
</td>
<td>
<input type="text" id="Content" name="Content" value="Content1" />
</td>
</tr>

integrating ccavenue payment gateway in rails

I am trying to integrate ccavenue payment gateway in my rails app..But I cant find any proper documentation. All they provide is 4 files for the integration. I cant figure out how to fit all these together.
1) ccavRequestHandler.html.erb
<html>
<head>
<title> Iframe</title>
</head>
<body>
<center>
<%
merchantData=""
working_key="" #Put in the 32 Bit Working Key provided by CCAVENUES.
access_code="" #Put in the Access Code in quotes provided by CCAVENUES.
params.each do |key,value|
merchantData += key+"="+value+"&"
end
crypto = Crypto.new
encrypted_data = crypto.encrypt(merchantData,working_key)
%>
<iframe width="482" height="500" scrolling="No" frameborder="0" id="paymentFrame" src="https://test.ccavenue.com/transaction/transaction.do?command=initiateTransaction&encRequest=<%=encrypted_data %>&access_code=<%=access_code %>"></iframe>
</center>
<script type="text/javascript" src="assets/javascripts/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('iframe#paymentFrame').load(function() {
window.addEventListener('message', function(e) {
$("#paymentFrame").css("height",e.data['newHeight']+'px');
}, false);
});
});
</script>
</body>
</html>
2) ccavResponseHandler.html.erb
<html>
<head>
<title>Response Handler</title>
<%= csrf_meta_tags%>
</head>
<body>
<%
workingKey=""#Put in the 32 Bit Working Key provided by CCAVENUES.
encResponse=params[:encResp]
crypto = Crypto.new
decResp=crypto.decrypt(encResponse,workingKey);
decResp = decResp.split("&")
%>
<center>
<font size="4" color="blue"><b>Response Page</b></font>
<table border="1">
<tr>
<td><b>Parameter Name</b></td>
<td><b>Parameter Value</b></td>
<%decResp.each do |key|%>
<tr>
<td><%=key.from(0).to(key.index("=")-1)%> </td>
<td><%=key.from(key.index("=")+1).to(-1)%> </td>
</tr>
<%end%>
</table>
</center>
</body>
</html>
3) crypto.rb
#*****************************************************************
# * COMPANY - AVENUES INDIA PVT Ltd.,
#*****************************************************************
#Name of the Program : AES Encryption/Decryption
#Created by : AVENUES INDIA PVT Ltd., TC-Team
#Created On : 16-02-2014
#Version : Version 1.0
#Contribution : eLitmus Evaluation Pvt Ltd
#*****************************************************************
class Crypto < ActiveRecord::Base
INIT_VECTOR = (0..15).to_a.pack("C*")
def encrypt(plain_text, key)
secret_key = [Digest::MD5.hexdigest(key)].pack("H*")
cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
cipher.encrypt
cipher.key = secret_key
cipher.iv = INIT_VECTOR
encrypted_text = cipher.update(plain_text) + cipher.final
return (encrypted_text.unpack("H*")).first
end
def decrypt(cipher_text,key)
secret_key = [Digest::MD5.hexdigest(key)].pack("H*")
encrypted_text = [cipher_text].pack("H*")
decipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
decipher.decrypt
decipher.key = secret_key
decipher.iv = INIT_VECTOR
decrypted_text = (decipher.update(encrypted_text) + decipher.final).gsub(/\0+$/, '')
return decrypted_text
end
end
4) dataForm.html.erb
<html>
<head>
</head>
<body>
<form method="POST" name="customerData" action="/transaction/ccavRequestHandler">
<table width="40%" height="1" border='1' align="center"><caption><font size="4" color="blue"><b>Integration Kit</b></font></caption></table>
<table width="40%" height="100" border='1' align="center">
<tr>
<td>Parameter Name:</td><td>Parameter Value:</td>
</tr>
<tr>
<td colspan="2"> Compulsory information</td>
</tr>
<tr>
<td>Merchant Id :</td><td><input type="text" name="merchant_id" value="2954"/></td>
</tr>
<tr>
<td>Order Id :</td><td><input type="text" name="order_id" value="123654789"/></td>
</tr>
<tr>
<td>Amount :</td><td><input type="text" name="amount" value="1.00"/></td>
</tr>
<tr>
<td>Currency :</td><td><input type="text" name="currency" value="INR"/></td>
</tr>
<tr>
<td>Redirect URL :</td><td><input type="text" name="redirect_url" value="http://merchantdomain/transaction/ccavResponseHandler"/></td>
</tr>
<tr>
<td>Cancel URL :</td><td><input type="text" name="cancel_url" value="http://merchantdomain/transaction/ccavResponseHandler"/></td>
</tr>
<tr>
<td>Language :</td><td><input type="text" name="language" value="EN"/></td>
</tr>
<tr>
<td colspan="2">Billing information(optional):</td>
</tr>
<tr>
<td>Billing Name :</td><td><input type="text" name="billing_name" value="Charli"/></td>
</tr>
<tr>
<td>Billing Address :</td><td><input type="text" name="billing_address" value="Room no 1101, near Railway station Ambad"/></td>
</tr>
<tr>
<td>Billing City :</td><td><input type="text" name="billing_city" value="Indore"/></td>
</tr>
<tr>
<td>Billing State :</td><td><input type="text" name="billing_state" value="MP"/></td>
</tr>
<tr>
<td>Billing Zip :</td><td><input type="text" name="billing_zip" value="425001"/></td>
</tr>
<tr>
<td>Billing Country :</td><td><input type="text" name="billing_country" value="India"/></td>
</tr>
<tr>
<td>Billing Tel :</td><td><input type="text" name="billing_tel" value="9876543210"/></td>
</tr>
<tr>
<td>Billing Email :</td><td><input type="text" name="billing_email" value="person#gmail.com"/></td>
</tr>
<tr>
<td colspan="2">Shipping information(optional)</td>
</tr>
<tr>
<td>Shipping Name :</td><td><input type="text" name="delivery_name" value="Chaplin"/></td>
</tr>
<tr>
<td>Shipping Address :</td><td><input type="text" name="delivery_address" value="room no.701 near bus stand"/></td>
</tr>
<tr>
<td>shipping City :</td><td><input type="text" name="delivery_city" value="Hyderabad"/></td>
</tr>
<tr>
<td>shipping State :</td><td><input type="text" name="delivery_state" value="Andhra"/></td>
</tr>
<tr>
<td>shipping Zip :</td><td><input type="text" name="delivery_zip" value="425001"/></td>
</tr>
<tr>
<td>shipping Country :</td><td><input type="text" name="delivery_country" value="India"/></td>
</tr>
<tr>
<td>Shipping Tel :</td><td><input type="text" name="delivery_tel" value="9595226054"/></td>
</tr>
<tr>
<td>Merchant Param1 :</td><td><input type="text" name="merchant_param1" value="additional Info."/></td>
</tr>
<tr>
<td>Merchant Param2 :</td><td><input type="text" name="merchant_param2" value="additional Info."/></td>
</tr>
<tr>
<td>Merchant Param3 :</td><td><input type="text" name="merchant_param3" value="additional Info."/></td>
</tr>
<tr>
<td>Merchant Param4 :</td><td><input type="text" name="merchant_param4" value="additional Info."/></td>
</tr>
<tr>
<td>Merchant Param5 :</td><td><input type="text" name="merchant_param5" value="additional Info."/></td>
</tr>
<tr>
<td>Promo Code :</td><td><input type="text" name="promo_code" value=""/></td>
</tr>
<tr>
<td>Vault Info. :</td><td><input type="text" name="customer_identifier" value=""/></td>
</tr>
<tr>
<td>Integration Type :</td><td><input type="text" name="integration_type" value="iframe_normal"/></td>
</tr>
<tr>
<td></td><td><INPUT TYPE="submit" value="CheckOut"></td>
</tr>
</table>
</form>
</body>
</html>
These 4 files is the only docs they provides..
I can also see that in html.erb file they want us to put the keys?? Is it safe??
The gem they provide is really outdated and hence didnt even mention about it.. I really cant figure out where to start with this..Can someone give me a rough idea on how to do this???

Knockout with class scoped properties

I am using Knockout and have the ViewModel bound to my data object in my ASP.Net MVC 4 project quite nicely like so:
$(document).ready(function() {
properties = #Html.Raw(Json.Encode(Model));
selectedProperty = properties[0];
viewModel = { properties: ko.mapping.fromJS(#Html.Raw(Json.Encode(Model))), selectedProperty: ko.observable()};
viewModel.setItem = function(item) {
viewModel.selectedProperty(item);
}
ko.applyBindings(viewModel);
Now I want to refactor my JavaScript so that the logic is encapsulated inside a class:
RealEstate.Search = function (properties) {
this.properties = properties;
this.selectedProperty = this.properties[0];
this.viewModel = { properties: ko.mapping.fromJS(this.properties), selectedProperty: ko.observable()};
this.viewModel.setItem = function(item) {
viewModel.selectedProperty(item);
}
ko.applyBindings(this.viewModel);
}
And I am instantiating that object in my HTML page like so:
$(document).ready(function() {
search = new RealEstate.Search(#Html.Raw(Json.Encode(Model)));
}
Now, I am getting the following error:
Error: Unable to parse bindings.
Message: ReferenceError: 'properties' is undefined;
Bindings value: foreach: properties
Here is the snipped HTML for the table bound to the ViewModel:
<div id="divDataTable" data-bind="with: properties">
<table id="dataTable" class="tablesorter">
<thead>
<tr>
<th>Address
</th>
<th>
Suburb
</th>
<th>Price
</th>
<th>Beds
</th>
<th>Baths
</th>
<th>Days Listed
</th>
</tr>
</thead>
<tbody data-bind="foreach: properties">
<tr data-bind="click: $root.setItem">
<td>
<label data-bind="text: $data.Street"></label>
<input data-bind="attr: { value : $index(), id : $index(), name : $index() }" type="hidden" />
</td>
<td data-bind="text: $data.Suburb"></td>
<td data-bind="text: $data.PriceFormatted"></td>
<td data-bind="text: $data.NumOfBedrooms"></td>
<td data-bind="text: $data.NumOfBathrooms"></td>
<td data-bind="text: $data.DaysListed"></td>
</tr>
</tbody>
</table>
</div>
</section>
<div id="divProperty">
<aside class="float-right" data-bind="with: selectedProperty">
<table>
<tr>
<td>
<label data-bind="text: $data.Street"></label>
</td>
<td>
<label data-bind="text: $data.PriceFormatted"></label>
</td>
</tr>
<tr>
<td colspan="2">
<img src="#" /></td>
</tr>
<tr>
<td>Beds:
<label data-bind="text: $data.NumOfBedrooms"></label>
</td>
<td>On OZMite:
<label data-bind="text: $data.DaysListed"></label>
</td>
</tr>
<tr>
<td>Baths:
<label data-bind="text: $data.NumOfBathrooms"></label>
</td>
<td>Year built:</td>
</tr>
</table>
</aside>
I would appreciate it if someone could shed some light on what I am doing wrong.
With the data-bind="with: properties" you are already "in the context" of the properties property inside your div.
So when you write <tbody data-bind="foreach: properties"> KO tries to find the properties property inside your properties array.
What you need is to use to reference the current binding context with the $data.
So your foreach should look like this:
<tbody data-bind="foreach: $data">
...
</todby>

asp.net mvc checkbox/radiobutton matrix model-binding

I have a dynamic forms with checkbox/radio-button lists & matrices:
Following code renders checkbox list:
#foreach (var sq in Model.SubQuestions)
{
<label>
<input type="hidden" name="answerResult.index" value="#sq.Id" />
<input type="checkbox" name="answerResult[#sq.Id].SubQuestionId" value="#sq.Id" />
#sq.Label.Name
</label>
}
radio-button list:
<input type="hidden" name="answerResult.index" value="#Model.Id" />
#foreach (var sq in Model.SubQuestions)
{
<label>
<input type="radio" name="answerResult[#Model.Id].SubQuestionId" value="#sq.Id" />
#sq.Label.Name
</label>
}
My POST-action in controller:
[HttpPost]
public ActionResult PassageSurvey(int surveyId, int surveyPageIndex, IList<AnswerResult> answerResult)
where IList<AnswerResult> is an auto-bound collection from my form. I get only items that were checked/selected. Everything is going well.
Now I need to get the same collection from checkbox/radio-button matrices.
Radio-button matrix:
<table width="100%">
<tr>
<th></th>
#foreach (var av in Model.AnswerVariants)
{
<th style="text-align: center;">
<label>#av.Label.Name</label>
</th>
}
</tr>
#foreach (var sq in Model.SubQuestions)
{
<tr>
<td>
<label>#sq.Label.Name</label>
<input type="hidden" name="answerResult.index" value="#sq.Id" />
<input type="hidden" name="answerResult[#sq.Id].SubQuestionId" value="#sq.Id" />
</td>
#foreach (var av in Model.AnswerVariants)
{
<td align="center">
<input type="radio" name="answerResult[#sq.Id].AnswerVariantId" value="#av.Id" />
</td>
}
</tr>
}
</table>
Checkbox matrix:
<table width="100%">
<tr>
<th></th>
#foreach (var av in Model.AnswerVariants)
{
<th style="text-align: center;">
<label>#av.Label.Name</label>
</th>
}
</tr>
#foreach (var sq in Model.SubQuestions)
{
<tr>
<td>
<label>#sq.Label.Name</label>
</td>
#foreach (var av in Model.AnswerVariants)
{
<td align="center">
<input type="hidden" name="answerResult.index" value="#sq.Id" />
<input type="hidden" name="answerResult[#sq.Id].AnswerVariantId" value="#sq.Id" />
<input type="checkbox" name="answerResult[#sq.Id].SubQuestionId" value="#sq.Id" />
</td>
}
</tr>
}
</table>
POST-action in controller always the same.
Now from radio-button matrix (in current sample 3x3) IList<AnswerResult> gets always 3 items, depending on items that were selected in rows and columns.
But from Checkbox matrix (3x3) IList<AnswerResult> gets always all 9 items (regardless items were checked, hidden-inputs always have values)
But I want to get only items, that were checked. How could I change my checkbox-matrix template to solve this problem?
Finally I decided to handle this problem in my post-action instead. Removing items (checkboxes) that were not selected, and have nulls in answerResult[##].SubQuestionId fields.

Resources