I am working in ASP.Net MVC4 with Dojo. I have a strange problem when I am adding new rows to html table. I need to have a table which supports adding and removing rows and textboxes inside should have dojo style. I referred the post http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ ad tried to create the same thing. Let me explain my code. Below is my view
#section scripts {
<script type="text/javascript">
require(["dojo/parser", "dijit/form/TextBox", "dijit/form/Button"]);
</script>
}
<table id="servicesTable">
<tr>
<th>
<label id="lblSelectService">
Select</label>
</th>
<th>
<label id="lblServiceName">
Name</label>
</th>
<th>
<label id="lblTitle">
AE Title</label>
</th>
</tr>
#for (int i = 0; i < Model.Services.Count; i++)
{
#Html.Partial("_ServiceRow", Model.Services[i])
}
</table>
My partial view for rendering each row is like below
#model WebUI.Models.RemDevServiceViewModel
<tr>
<td>
#Html.CheckBoxFor(x => x.IsMarked,
new { id = #String.Format("Service[{0}]IsMarked", #Model.ID) })
</td>
<td>
<input style="width: 100px; id="Service[#Model.ID]Name"
name="Service[#Model.ID].Name" type="text"
data-dojo-type="dijit/form/TextBox" value="#Model.Name"/>
</td>
<td>
<input style="width: 100px;" id="Service[#Model.ID]Title"
data-dojo-type="dijit/form/TextBox"
name="Service[#Model.ID].Title" type="text"
value="#Model.Title" />
</td>
</tr>
I have an add button which will add new row to the table. The problem that I am facing is, new row does not get the dojo style and they are rendered as normal textboxes. Initially loaded rows are rendered as dojo style text boxes, but the newly added are not like that. My jquery function to add new rows is like below
function addNewService() {
$.ajax({
url: rootPath + "MyController/AddNewService",
type: "get",
cache: false,
success: function (html) {
$("#servicesTable tbody").append(html);
},
error: function (ts) {
alert("Error while adding services");
}
});
}
Can any one tell me how to solve this? Please note that I am aware about the existence of Dojo grid. I want to take the advantage of model binding and hence following this style
Try running the parser over the added nodes. Are you seriously loading jquery on the page as well? Anyway, with the code you've got, it's kind of tricky to select the just added nodes, but if you put the following inside the success method it might work.
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/parser"], function(parser){
newNodes.forEach(function(node){
parser.parse(node);
});
});
If you parse over nodes that were already parsed, the parser will throw an error. Also, if you need to support older browsers you'll want to replace the forEach with a standard for loop.
Thanks a lot David for your reply. Your code did not work exactly, but I got the idea and below code is working for me. Please dont feel that I am answering my own question. I want to format the code properly and hence using this view. Once again thanks a lot
success: function (html) {
var newNodes = $(html).appendTo("#servicesTable tbody");
require(["dojo/_base/array", "dojo/parser"], function (array, parser) {
array.forEach(newNodes, function (node, i) {
parser.parse(node);
});
});
Related
I need to create view that contains table with pagination, sorting and search. I'm getting my data from backend api and then I'm passing it to the view.
My action method looks like this:
public async Task<IActionResult> Home(int page = 1)
{
var list = await _service.Get<List<Model.Rezervacija>>(page);
ViewBag.Page = page;
return View(list);
}
And I have this view:
#using eBiblioteka.Model
#model List<Rezervacija>
#{
ViewBag.Title = "Home";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="view-all">
#await Html.PartialAsync("_ViewAll", Model, null)
</div>
<a asp-action="Home" asp-route-page="#(ViewBag.Page - 1)">Previous</a>
<a asp-action="Home" asp-route-page="#(ViewBag.Page + 1)">Next</a>
And what view looks like:
And that all works. Don't pay attention for displaying pages number like this and changing with previous and next, I just wanted to simplify my question. So when i click next page, data changes and table also update very fast and that isn't problem.
But i see in tab that page is reloaded:
.
So is there any solution in asp .net core to do this without seeing that page reload. I need to call my action again to change this param "page" and then fetch new data from api without see that ugly page reload.
Thank you for all solutions.
So you want to create view that contains table with pagination, sorting and search without reloading.so you should use jquery for this.update your code like below:-
#using eBiblioteka.Model
#model IEnumerable<Rezervacija>
<div>
<table class="table table-striped border" id="myTable">
<thead>
<tr class="table-info">
<th>
#Html.DisplayNameFor(c => c.Name)
</th>
<th>
#Html.DisplayNameFor(c => c.SpecialTagId)
</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td> #item.Name </td>
<td> #item.SpecialTag.Name </td>
<td>
<partial name="_ButtonPartia3" model="#item.Id" /> //you can use partial view for delete or add data.
</td>
</tr>
}
</tbody>
</table>
</div>
<br /> <br />
#section scripts{
<script src="https://cdn.datatables.net/1.11.2/js/jquery.dataTables.min.js"></script>
<script type="text/javascript">
$(document).ready( function () {
$('#myTable').DataTable();
});
</script>
}
And Add this below link in your _Layout.cshtml:-
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.2/css/jquery.dataTables.min.css">
And your output will be like this:-
So when you will go from one page to another page, it will not reload because you used jquery. and it's already sorted and you can also search as needed.
You can use some excellent front-end frameworks. I now recommend you use layui, this is a Chinese community, of course you can also choose other ones. When this layui is paging, the URL is like the following format.
https://www.layui.com/demo/table/user/?page=2&limit=10
In this way, the .net core api can be called to perform partial refresh without reloading the entire page.
I have a table in which I add the input field dynamically and I set the validation manually by using Toastr notifications . what the problem is that when I add the input at the first time the validation is working perfectly but when I add another input the validation is not working on new added input. I have tried and searched for the solution but I did not find any solution.Any help will be highly appreciated.
My HTML code :
<table class="table-hover" id="form">
<thead>
<tr>
<th>پلورنکی</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, $index) in rows" :key="row.id">
<td>
<input
dir="rtl"
id="supplier_id1"
v-model="row.supplier_id1"
placeholder="نیټه "
type="text"
name="supplier_id1"
class="form-control"
/>
</td>
</tr>
</tbody>
</table>
<button
class="btn btn-success btn-xs"
#click="getData()"
>
خوندی کړی
</button>
My script code :
export default {
data() {
return {
rows: [
{
supplier_id1: "",
}
],
}
}
methods: {
getData: function() {
if (this.rows[0].supplier_id1 == "") {
toast.fire({
icon: "warning",
html: "<h5> supplier id is required.</h5>"
});
} else {
//if the input is not emptyexecute the coed successfully
}
}
}
}
You will always check for the first row, because of if (this.rows[0]...)
rows[0] will always take the first object in your array
If you always want to validate all the rows, you could check if there are any rows without a supplier id: if (this.rows.filter((row) => row.supplier_id1 === "").length)
I not sure which toast component did you used, but i can do similar mock for your validation message + databinding of your {{row.supplier_id1}}
v-model value of input[type="date] will only valid when you inputted date correctly so this.rows[0].supplier_id1.length == 0 to validate is fine. The reactivity is working fine.
My Working Fiddle: https://jsfiddle.net/bu9twps2/
UPDATE: Your original condition to validate works fine as well, problem likely lies at your toast
I am working on jhipster 5.7.2 project with angular 7 and I am using angular datatables and it's responsive extension is working fine when I have static data, but when I use *ngFor directive in tag it doesn't collapse the column on resizing, just hides the column header but the column is still there.
After I resize to small window size and size back to normal the orientation of the first table row gets distorted and doesn't get fixed until I reload the page.
P.S - Struggled a lot on finding a fix, and tried giving width=100% to the table but the issue still persists.
user-management-component.html
<div>
<table datatable [dtOptions]="dtOptions" class="row-border hover" width="100%">
<thead>
<tr class="tr-bg">
<th>ID</th>
<th>Login</th>
<!-- <th>Last name</th> -->
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users; trackBy: trackIdentity">
<td><span>{{user.id}}</span></td>
<td><span>{{user.login}}</span></td>
<!-- <td><span>Bar</span></td> -->
</tr>
</tbody>
</table>
</div>
Here is the ngOnInit() function where dtOptions are declared.
user-management-component.ts
ngOnInit() {
this.dtOptions = {
responsive: true
};
this.accountService.identity().then(account => {
this.currentAccount = account;
this.loadAll();
this.registerChangeInUsers();
});
}
Full size page table
Table After resizing the window
Thanks in advance for the help!
I have a half answer to your question, the code below adjusts the table, im using it to readjust my tables on sidemenu open/close. Its a half answer because I dont know when should you call it. I hope It helps
datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.columns.adjust().draw();
})
My template is:
<tbody id="deliveries-table">
<tr v-for="item in deliveries">
<td class="table-view-item__col"></td>
<td class="table-view-item__col" v-bind:class="{ table-view-item__col--extra-status: item.exclamation }"></td>
<td class="table-view-item__col">{{item.number}}</td>
<td class="table-view-item__col">{{item.sender_full_name}}</td>
<td class="table-view-item__col" v-if="item.courier_profile_url">{{item.courier_full_name}}</td>
<td class="table-view-item__col" v-if="item.delivery_provider_url">{{item.delivery_provider_name}}</td>
<td class="table-view-item__col">
<span style="font-weight: 900">{{item.get_status_display}}</span><br>
<span>{{item.date_state_updated}}</span>
</td>
</tr>
</tbody>
My javascript code for render a lot of prepared data is:
var monitorActiveDeliveries = new ActiveDeliveries();
monitorActiveDeliveries.fillTable(allDeliveries);
class ActiveDeliveries {
constructor() {
this.table = new Vue({
el: '#deliveries-table',
data: {
deliveries: []
}
});
}
fillTable (d) {
this.table.deliveries = d;
}
}
But after script starts any render into tbody, i have just empty place in HTML.
Where i got some wrong?
First, although you can instantiate your Vue app on the <table> tag, usually you want just a single Vue instance on the whole page, so it might be better to make the Vue instance on one main div/body tag.
Second, I think your code could work (I don't know what your deliveries objects should look like...), but your fillTable() method is probably not getting called, i.e. deliveries are empty.
I made this working example based on your code: http://jsfiddle.net/wmh29mds/
Life is easier than it seems.
I got a mistake into this directive:
v-bind:class="{ table-view-item__col--extra-status: item.exclamation }"
I just forgot single quotas into class name, next variant is working:
v-bind:class="{ 'table-view-item__col--extra-status': item.exclamation }"
I'm new to Camunda and didn't find any tutorial or reference explaining how to achieve the following:
When starting a process I want the user to add as many items as he likes to an invoice. On the next user task all those items and their quantity should be printed to somebody approving the data.
I don't understand yet how to get this 1:n relationship between a process and its variables working. Do I need to start subprocesses for each item? Or do I have to use a custom Java object? If so, how can I map form elements to such an object from within the Tasklist?
I got it working with the help of the links provided by Thorben.
The trick is to use JSON process variables to store more complex data structures. I initialize such lists in my "Start Event". This can be done either in a form or in my case in a Listener:
execution.setVariable("items", Variables.objectValue(Arrays.asList(dummyItem)).serializationDataFormat("application/json").create());
Note that I added a dummyItem, as an empty list would lose its type information during serialization.
Next in my custom form I load this list and can add/remove items. Using the camForm callbacks one can persist the list.
<form role="form" name="form">
<script cam-script type="text/form-script">
/*<![CDATA[*/
$scope.items = [];
$scope.addItem = function() {
$scope.items.push({name: '', count: 0, price: 0.0});
};
$scope.removeItem = function(index) {
$scope.items.splice(index, 1);
};
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('items');
});
// variables-fetched is not working with "saved" forms, so we need to use variables-restored, which gets called after variables-fetched
camForm.on('variables-restored', function() {
$scope.items = camForm.variableManager.variableValue('items');
});
camForm.on('store', function() {
camForm.variableManager.variableValue('items', $scope.items);
});
/*]]>*/
</script>
<table class="table">
<thead>
<tr><th>Name</th><th>Count</th><th>Price</th><th></th></tr>
</thead>
<tbody>
<tr ng-repeat="i in items">
<td><input type="text" ng-model="i.name"/></td>
<td><input type="number" ng-model="i.count"/></td>
<td><input type="number" ng-model="i.price"/></td>
<td>
<button class="btn btn-default" ng-click="removeItem($index)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-default" ng-click="addItem()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
</tr>
</tfoot>
</table>
</form>
Two things aren't working yet:
Field validation, e.g. for number fields
The dirty flag used on the "save" button doesn't get updated, when adding/removing rows