VueJS data bind related - data-binding

I use vueJS to display a table data,when I click the delete button, the table always delete the last row,rather not a specific row.I use my custom UIComponent 'lovTable',it changes a input element to another style,how to avoid it and make the data and page change the same way.Here's the code.Tks.
<script>
//服务类型下拉列表数据转化
var mServiceTypeData = $.map(serviceTypeData, function (obj) {
obj.id = obj.value;
obj.text = obj.meaning;
return obj;
});
$(function(){
var vm = new Vue({
el: '#div-rms-memo',
data: {
sub:[]
},
methods:{
//添加子项目
addSubProject:function () {
vm.sub.push({
subPrjServeType:'',
subPrjBelongToDept:'',
});
},
//移除当前行的子项目
removeCurrentRow:function(index){
var $del=vm.sub.splice(index,1);
},
}
});
function renderLines(el, lineIndex){
//渲染select2
$("#subPro"+lineIndex).find(".subPrjServeType").select2Ext({
placeholder: '请选择服务类型',
data: mServiceTypeData,
width:150
}).on('change', function () {
vm.sub[lineIndex].subPrjServeType = $(this).val();
});
//归属部门LOV
$("#subPro"+lineIndex).find(".subPrjBelongToDept").lovTable({
title:'归属部门',
placeholder:'请选择',
valueField:'unitId',
textField:'unitName',
query:[
{
text:'部门ID',
name:'unitId'
},
{
text:'部门名称',
name:'unitName'
}
],
rowSelected:function(row){
vm.sub[lineIndex].subPrjBelongToDept=row.unitId;
},
textClear:function(){
vm.sub[lineIndex].subPrjBelongToDept = "";
}
},{
url : '${base.contextPath}/project/prjBranchView/queryConditionPage?'+_header+'='+_token,
columns: [{
title:'部门ID',
field:'unitId'
},{
title:'部门名称',
field:'unitName'
}]
});
}
Vue.directive('line-bind', {
bind: function (el, binding) {
var lineIndex = binding.value;
console.info('binding index='+lineIndex)
vm.$nextTick(function () {
renderLines(el,lineIndex);
})
},
unbind:function(el,binding){
vm.$nextTick(function () {
for(var i=0;i<vm.sub.length;i++){
renderLines(vm.sub[i],i);
}
})
}
});
})
</script>
<div class="content-wrapper">
<section class="content">
<div id="div-rms-memo" >
<div class="box box-blue">
<div class="form-group">
<a href="javascript:void(0)" class="btn btn-crm" v-on:click="addSubProject">
<span class="glyphicon glyphicon-plus">添加</span>
</a>
</div>
<table align="center" class="table table-bordered" v-line-bind="index" v-for="(el,index) in sub" :id="'subPro'+index" :cindex="index">
<tr class="crm-title">
<td align="center" valign="middle" rowspan="2" style="width:5%;">
<a href="javascript:void(0)" class="btn btn-default btn-xs removeSubPrj" id="removeSubPrjBtn" v-on:click="removeCurrentRow(index)">
<span class="glyphicon glyphicon-minus"></span>
</a>
</td>
<td align="center" style="width:15%;"class="required">服务类型</td>
<td align="center" style="width:15%;"class="required">归属部门</td>
<td align="center" style="width:15%;" class="required">人天</td>
</tr>
<tr>
<td align="center">
<input type="text" id="subPrjServeType" v-model="el.subPrjServeType" class="form-control input-sm subPrjServeType"/>
</td>
<td align="center">
<input type="text" class="form-control input-sm subPrjBelongToDept" v-model="el.subPrjBelongToDept">
</td>
<td align="center">
<input type="number" class="form-control input-sm subPrjPeoplePerDay" v-model="el.subPrjPeoplePerDay">
</td>
</tr>
</table>
</div>
</div>
</section>
</div>

Related

how to Send records within the loop individually with Ajax

I want to send and save the records inside the loop one by one with Ajax.Each record has a button to send information.
But when I want to send the record to the action method, only the information of the first record is sent.
I also want to make a Condition that if the user selects an item from dropdown,can send the record, otherwise a message will be displayed.
#model ModiranVira.ViewModels.GhrardadViewModel
#using ModiranVira.PublicClass
#{
Layout = null;
string numSpace = "#,##0.###";
}
<div class="container-fluid mt-5">
<table class="table table-bordered table-striped text-sm">
<thead class="text-center">
<tr style="background-color:#416992; color: white">
<th>نوع قرارداد</th>
<th>مبلغ</th>
<th>تاریخ شروع</th>
<th>تاریخ پایان</th>
<th>تعین کارشناس</th>
<th>عملیات</th>
</tr>
</thead>
#foreach (var item in Model.ghrardads)
{
<tr>
#switch (#item.NoeaKhadmat)
{
case 1:
<td>حسابرسی</td>
break;
case 2:
<td>مالیاتی</td>
break;
case 3:
<td>منابع انسانی</td>
break;
}
<td>#item.MablghGhrardad</td>
<td>
#item.ShoroeeProjectDate
</td>
<td>
#item.PayanProjectDate
</td>
<input class="d-none" value="#item.id" id="GhradadID" />
<td>
<select class="form-control" id="TaeenKarShnas" required autocomplete="off">
<option value="" default="" selected="">انتخاب کنید</option>
#foreach (var item1 in Model.Users)
{
<option value="#item1.Id">#item1.FirstName #item1.Family</option>
}
</select>
</td>
<td class="text-center">
<button id="btnstap39" type="button" class="btn btn-sm btn-outline-success"> <i class="fa fa-save"> </i>ذخیره </button>
</td>
</tr>
}
</table>
<div id="ohsnap" class="col-md-4 col-xs-12 alert d-none" style="text-align:center;"></div>
</div>
<script>
$("#btnstap39").on('click', function () {
$.ajax({
type: "Post",
url: '#Url.Action("SubmitGhrardadStap39", "Project")',
data: {
'GhradadID': $("#GhradadID").val(),
'TaeenKarShnas': $("#TaeenKarShnas").val(),
}
}).done(function (res) {
if (res.status == 'ok') {
$("#ohsnap").removeClass('hidden').removeClass('alert-danger').addClass('alert-success').html('گام دوم با موفقیت ثبت شد');
setTimeout(function () {
$('#ohsnap').fadeOut('fast');
}, 2000)
}
});
});
</script>
[HttpPost]
public IActionResult SubmitGhrardadStap39(int GhradadID, String TaeenKarShnas)
{
var ghrar = _context.Ghrardad.Find(GhradadID);
ghrar.UserID = TaeenKarShnas;
_context.SaveChanges();
return Json(new { status = "ok" });
}
According to your description, the reason why you couldn't send the second data is you use jquery ID selector to select the ID. But all of your table GhradadID and TaeenKarShnas is the same ID, so you will always get the same(first) row. To solve this issue, I suggest you could put the Item ID at the input and select ID and then click the button will find each different ID.
I also want to make a Condition that if the user selects an item from dropdown,can send the record, otherwise a message will be displayed.
I suggest you could try to make a condition before the ajax and if the value is null then alter something.
More details, you could refer to below codes:
<div class="container-fluid mt-5">
<table class="table table-bordered table-striped text-sm">
<thead class="text-center">
<tr style="background-color:#416992; color: white">
<th>نوع قرارداد</th>
<th>مبلغ</th>
<th>تاریخ شروع</th>
<th>تاریخ پایان</th>
<th>تعین کارشناس</th>
<th>عملیات</th>
</tr>
</thead>
#foreach (var item in Model.ghrardads)
{
<tr>
#switch (#item.NoeaKhadmat)
{
case 1:
<td>حسابرسی</td>
break;
case 2:
<td>مالیاتی</td>
break;
case 3:
<td>منابع انسانی</td>
break;
}
<td>#item.MablghGhrardad</td>
<td>
#item.ShoroeeProjectDate
</td>
<td>
#item.PayanProjectDate
</td>
<input class="d-none" value="#item.id" id="#string.Format("GhradadID{0}",item.id)" />
<td>
<select class="form-control" id="#string.Format("TaeenKarShnas{0}",item.id)" required autocomplete="off">
<option value="" default="" selected="">انتخاب کنید</option>
#foreach (var item1 in Model.Users)
{
<option value="#item1.Id">#item1.FirstName #item1.Family</option>
}
</select>
</td>
<td class="text-center">
<button id="#item.id" type="button" class="btn btn-sm btn-outline-success ClicktPost"> <i class="fa fa-save"> </i>ذخیره </button>
</td>
</tr>
}
</table>
</div>
#section Scripts{
<script>
$(".ClicktPost").on('click', function (event) {
var id = event.target.id;
//Get the value according to Button's ID
var GhradadID = $("#GhradadID" + id).val();
var TaeenKarShnas = $("#TaeenKarShnas" + id).val();
//If the TaeenKarShnas is null alert something
if (TaeenKarShnas == '') {
alert("please select dropdownlistvalue");
} else {
$.ajax({
type: "Post",
url: '#Url.Action("SubmitGhrardadStap39", "Home")',
data: {
'GhradadID': GhradadID,
'TaeenKarShnas': TaeenKarShnas,
}
}).done(function (res) {
if (res.status == 'ok') {
$("#ohsnap").removeClass('hidden').removeClass('alert-danger').addClass('alert-success').html('گام دوم با موفقیت ثبت شد');
}
});
}
});
</script>
}
Result:
If you don't select the value, you could refer to below image
If you don't select value, you could refer to below image

Navigation via button click in Angular 10

I have a list of names that I want to show only 5 of them on every page. Users can see the next 5 names by pressing “Next” button.
How can I set the click attribute of a button to do this for me in Angular.
Here is my .html file:
<div class="container">
<table class="table" >
<tbody *ngFor="let name of names.slice(index, index+ 5)">
<tr> <td>{{ name.value}} </td> </tr>
</tbody>
</table>
<button type="button" class="btn btn-primary" style ="float: left" (click)="previousFunction()"> < Previous </button>
<button type="button" class="btn btn-primary" style ="float: right" (click)="nextFunction()"> Next > </button>
</div>
Thanks in advance.
Well it was quiet easy to solve ...
Here is the html code:
<div class="container">
<table class="table" >
<tbody *ngFor="let name of names.slice(index, index+ 5)">
<tr> <td>{{ name.value}} </td> </tr>
</tbody>
</table>
<button type="button" class="btn btn-primary" style ="float: left" (click)="previousFunction($event, index)"> < Previous </button>
<button type="button" class="btn btn-primary" style ="float: right" (click)="nextFunction($event, index)"> Next > </button>
</div>
and here is the .ts code:
export class AppComponent {
constructor() { }
index: number = 0;
pageSize: number = 5;
names = [
{ name: 'a'},
{ name: 'b'},
{ name: 'c'},
{ name: 'd'},
{ name: 'e'},
{ name: 'f'},
{ name: 'g'},
{ name: 'h'},
{ name: 'i'},
{ name: 'j' },
];
previousFunction($event: any, count: any){
this.index = count - this.pageSize
}
nextFunction($event: any, count: any){
this.index = count + this.pageSize
}

I want to duplicate a table using js on my asp project but stuck here

I have already made a table but now i want to make another table below.In that table, the table data will be the same as before (all the row column data will be same) for that i included a js file in my project
i used ajax where i can get instant result.So here is my js code :
var dataTable;
$(document).ready(function () {
loadDataTable();
});
function loadDataTable() {
dataTable = $('#DT_load').DataTable({
"ajax": {
"url": "/api/book",
"type": "GET",
"datatype": "json"
},
"columns": [
{ "data": "Name", "width": "30%" },
{ "data": "Author", "width": "30%" },
{ "data": "ISBN", "width": "30%" },
{
"data": "id",
"render": function (data) {
return `<div class= "text-center">
<a href="/BookList/Edit?id=${data}" class='btn btn-success text-white' style= 'cursor:pointer; width: 100px;'>Edit</a>
#nbsp
<a class='btn btn-success text-white' style= 'cursor:pointer; width: 100px;' onClick=Delete('/api/book?id='+${data})>Delete</a>
</div>`
"width" : "30%"
},
}
],
"language": {
"emptyTable": "No Data Found"
},
"width": "100%"
})
}
function Delete(url) {
swal({
title: "Are You Sure?",
text: "Once Deleted You cant never Find it again !",
icon: "warning",
dangerMode: true
}).then((willDelete) => {
if (willDelete) {
$.ajax({
type: "DELETE",
url: url,
success: function (data) {
if (data.success) {
toastr.success(message);
dataTable.ajax.reload();
}
else {
toastr.error(message);
}
}
});
}
});
}
The table i made with html css its showing but when i add this js file it should show me the duplicate table i made before.But its not working
Here is my index file:
#page
#model Crud_App.indexModel
<br />
<div class="container row p-0 m-0">
<div class="col-7">
<h2 class="text-info">Book List</h2>
</div>
<div class="col-3">
<a class="btn btn-info form-control text-center" asp-page="create">Create</a>
</div>
<div class="col-12 border p-3 mt-3">
<form method="post">
#if (Model.Books.Count() > 0)
{
<table class="table table-striped border">
<tr class="table-secondary">
<th>
<label asp-for="Books.FirstOrDefault().Name"></label>
</th>
<th>
<label asp-for="Books.FirstOrDefault().Author"></label>
</th>
<th>
<label asp-for="Books.FirstOrDefault().ISBN"></label>
</th>
</tr>
#foreach (var item in Model.Books)
{
<tr>
<td>
#Html.DisplayFor(m => item.Name)
</td>
<td>
#Html.DisplayFor(m => item.Author)
</td>
<td>
#Html.DisplayFor(m => item.ISBN)
</td>
<td>
<a asp-page="Edit" asp-route-id="#item.Id" class="btn btn-success btn-sm">Edit</a>
<button asp-page-handler="Delete" asp-route-id="#item.Id" onclick="return confirm('Are you Sure You want to delete')" class="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
}
</table>
}
else
{
<p>No Books Available</p>
}
</form>
</div>
<div class="col-12" style="text-align: center">
<br />
<span class="h3 text-info">OR</span>
<br/>
<div class="col-12 border p-3">
<table id="DT_load" class="table table-stripped table-bordered" style="width: 100%">
<thead>
<tr>
<th>Name</th>
<th>Atuhor</th>
<th>ISBN</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
#section scripts {
<script src ="~/js/BookList.js"></script>
}
I did it like this,
In DataTable, I added
dataSrc
columnDefs
In HTML, I added
4th table header
In backend controller, I am returning a named array booksData on DataTable ajax call
#section scripts {
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css" />
<script src="//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#DT_load').DataTable({
"ajax": {
"url": "https://localhost:44333/Home/Data",
"type": "GET",
"datatype": "json",
"dataSrc": "booksData"
},
"columns": [
{ "data": "name", "width": "30%" },
{ "data": "author", "width": "30%" },
{ "data": "isbn", "width": "30%" },
{ "data": "id", "width": "10%" }
],
"columnDefs": [
{
"targets": 3,
"data": "id",
"render": function (data) {
return 'Download';
}
}
],
"language": {
"emptyTable": "No Data Found"
},
"width": "100%"
});
});
</script>
}
#if (Model.Count() > 0)
{
<table class="table table-striped border">
<tr class="table-secondary">
<th>
<label>#Model.First().Name</label>
</th>
<th>
<label>#Model.First().Author</label>
</th>
<th>
<label>#Model.First().ISBN</label>
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(m => item.Name)
</td>
<td>
#Html.DisplayFor(m => item.Author)
</td>
<td>
#Html.DisplayFor(m => item.ISBN)
</td>
<td>
<a asp-route-id="#item.Id" class="btn btn-success btn-sm">Edit</a>
</td>
</tr>
}
</table>
<div class="col-12" style="text-align: center">
<br />
<span class="h3 text-info">OR</span>
<br />
<div class="col-12 border p-3">
<table id="DT_load" class="table table-stripped table-bordered" style="width: 100%">
<thead>
<tr>
<th>Name</th>
<th>Atuhor</th>
<th>ISBN</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
}
else
{
<p>No Books Available</p>
}
public class HomeController : Controller
{
public IActionResult Index()
{
var books = new List<Book> { new Book { Id=1, Name="Abcd", Author="Xyz", ISBN="1234" },
new Book { Id=2, Name="Efgh", Author="Igm", ISBN="7896" },
new Book { Id=3, Name="Qrty", Author="Ght", ISBN="8791" },};
return View(books);
}
public IActionResult Data()
{
var books = new List<Book> { new Book { Id=1, Name="Abcd", Author="Xyz", ISBN="1234" },
new Book { Id=2, Name="Efgh", Author="Igm", ISBN="7896" },
new Book { Id=3, Name="Qrty", Author="Ght", ISBN="8791" },};
return Json(new { booksData = books });
}

Why Ajax helpers doesnt work?

Im trying to achieve a filter search box, actually it works but it just completely reload all of my Index view instead of replacing the div content:
My controller Actions (The index action and the partial action):
public IActionResult Index()
{
var grupoModels = _grupos.GetAll("");
var listaGrupos = grupoModels
.Select(resultado => new grupoCRUDModel
{
Codigo = resultado.id,
Nombre = resultado.nombre,
NIS = resultado.nis,
FeAcceso = resultado.feacceso,
Linea = resultado.Linea
});
var model = new grupoIndexModel()
{
grupos = listaGrupos
};
return View(model);
}
public IActionResult tablePartial(string filter = "")
{
var grupoModels = _grupos.GetAll(filter);
var listaGrupos = grupoModels
.Select(resultado => new grupoCRUDModel
{
Codigo = resultado.id,
Nombre = resultado.nombre,
NIS = resultado.nis,
FeAcceso = resultado.feacceso,
Linea = resultado.Linea
});
var model = new grupoIndexModel()
{
grupos = listaGrupos
};
return PartialView("tablePartial",model);
}
My Index view with the searchbox and the target div to render my partial:
<div>
<div class="mdl-grid headeritems">
<div class="mdl-cell mdl-cell--8-col ">
<h2>LISTADO DE GRUPOS</h2>
</div>
<div class="mdl-cell mdl-cell--2-col" style="text-align:right;">
<button class="mdl-button mdl-js-button mdl-button--fab" id="btnAdd">
<a class="material-icons" asp-controller="Grupo" asp-action="Crear" data-ajax="true" data-toggle="modal" data-target="#modalGrupo">add</a>
</button>
</div>
<div class="mdl-cell mdl-cell--2-col">
<form asp-controller="Grupo" asp-action="tablePartial" data-ajax-method="GET" data-ajax-update="#pdiv" data-ajax="true" method="get">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable">
<label class="mdl-button mdl-js-button mdl-button--icon" for="sbox">
<i class="material-icons">search</i>
</label>
<div class="mdl-textfield__expandable-holder">
<input class="mdl-textfield__input" type="text" id="sbox" name="filter">
<label class="mdl-textfield__label" for="sample-expandable">Expandable Input</label>
</div>
</div>
</form>
</div>
</div>
<br />
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--1-col"></div>
<div id="pdiv" class="mdl-cell mdl-cell--10-col">
#Html.Partial("tablePartial")
</div>
<div class="mdl-cell mdl-cell--1-col"></div>
</div>
My partialTable code view:
#model libraryDemo.Models.grupoIndexModel
<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" id="tablaGrupos" style="width:100%;">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Nombre</th>
<th class="text-center">Linea</th>
<th class="text-center">Codigo</th>
<th colspan="2" class="text-center">Acciones</th>
</tr>
</thead>
<tbody>
#foreach (var grupo in Model.grupos)
{
<tr class="mtoRow">
<td class="mdl-data-table__cell--non-numeric">#grupo.Nombre</td>
<td class="text-center">#grupo.Linea.nombre</td>
<td class="text-center">#grupo.Codigo</td>
<td class="text-center" data-toggle="tooltip" data-placement="top" title="Editar"><a class="btn btn-warning" asp-controller="Grupo" asp-action="Editar" asp-route-id="#grupo.Codigo" data-ajax="true" data-toggle="modal" data-target="#modalGrupo">Editar</a></td>
<td class="text-center" data-toggle="tooltip" data-placement="top" title="Eliminar"><a class="btn btn-danger" asp-controller="Grupo" asp-action="Eliminar" asp-route-id="#grupo.Codigo" data-ajax="true" data-toggle="modal" data-target="#modalGrupo">Eliminar</a></td>
</tr>
}
</tbody>
</table>
Finally, my ajax function for keyup event:
$("#sbox").keyup(function () {
$("form").submit();
});
try data-ajax-url in place of asp-action
<form data-ajax-url="#Url.Action("tablePartial","Grupo")" data-ajax-method="GET" data-ajax-update="#pdiv" data-ajax="true" method="get">

Knockout Bindings issue

I keep getting the error when I click on the button to load the data into the table. The data loads but chrome tools throw the error below.
You cannot apply bindings multiple times to the same element
The code I am running is as follows what do I have to change.
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active">AM</li>
<li>CM</li>
<li>IM</li>
<li>KT</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="1">
<table class="table table-hover">
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
<td>D</td>
<td>E</td>
</tr>
</table>
</div>
<div class="tab-pane" id="2">
<table class="table table-hover">
<thead>
<tr>
<th>Title</th>
<th>Author</th>
<th>Link</th>
<th>Link1</th>
</tr>
</thead>
<tbody data-bind="foreach: Questions">
<tr>
<td data-bind="text: title"></td>
<td data-bind="text: author"></td>
<td>
<button type="button" class="btn btn-link">Link</button>
</td>
<td>
<button type="button" class="btn btn-link" data-bind="text: questionLink"> </button>
<!--<a class="btn" type="button" href="http://example.com">Default (Gray) Button</a>-->
<!--<a class="btn" data-bind="href: questionLink">Default (Gray) Button</a>-->
</td>
</tr>
</tbody>
</table>
</div>
<div class="tab-pane" id="3"></div>
<div class="tab-pane" id="4"></div>
<p><button id="clickMe" value="clickme" type="button" onclick="AddQuestions();">Load Questions</button></p>
<script type="text/javascript">
function AddQuestions() {
var self = this;
self.Questions = ko.observableArray();
self.Questions.push(new Question('1', '1', '1', '1', '1'));
self.Questions.push(new Question('2', '2', '2', '2', '2'));
ko.applyBindings();
function Question(label, id, title, author, questionLink) {
var self = this;
self.Label = ko.observable(label);
self.ID = ko.observable(id);
self.title = ko.observable(title);
self.author = ko.observable(author);
self.questionLink = ko.observable(questionLink);
}
}
</script>
The problem is you are calling ko.applyBindings more than once. You should only call this once per page.
function Questions() {
var self = this;
self.Questions = ko.observableArray();
self.addQuestions = function() {
self.Questions.push(new Question('1', '1', '1', '1', '1'));
self.Questions.push(new Question('2', '2', '2', '2', '2'));
};
function Question(label, id, title, author, questionLink) {
var self = this;
self.Label = ko.observable(label);
self.ID = ko.observable(id);
self.title = ko.observable(title);
self.author = ko.observable(author);
self.questionLink = ko.observable(questionLink);
}
}
ko.applyBindings(new Questions());
<button id="clickMe" value="clickme" data-bind="click: $root.addQuestions()">Load Questions</button></p>
You can call ko.applyBindings only once per DOM element.
Either call it once for the whole page with ko.applyBindings(viewmodel) or call it for the elements you want with ko.applyBindings(viewmodel, domElement).
Note that you can't call it on a jQuery object directly:
ko.applyBindings(viewmodel, $("#myObj"));
Won't work.
Use this instead if needed:
ko.applyBindings(viewmodel, $("#myObj").get(0));

Resources