I have a .Net MVC project that fills a table with data using a bootstrapTable from bootstrap v3. I want to add a delete button to each row.
The bootstrapTable takes json data and loads it. The json is built like this:
public virtual JsonResult Search(FormCollection searchArgument)
{
IEnumerable<MyData> myListData = GetMyListData(searchArgument);
var jsonResult = Json(myListData, JsonRequestBehavior.AllowGet);
return jsonResult;
}
So the jsonResult is just a list of all of my MyData. My view that shows the result looks like this:
#model MyNamespace.Web.Models.MyListViewModel
<div class="col-md-12">
#{
ViewBag.Title = "Index";
Layout = MVC.Shared.Views._Layout;
<div class="row">
<div class="col-md-12">
<form role="form" id="formsearch">
<input id="fromsearch" name="fromsearch" type="hidden" value="true" />
<div class="form-group">
#Html.LabelFor(m => m.Status, "Status:")<br />
#Html.DropDownList("status", new SelectList(Model.Status, "Value", "Key", Model.SelectedStatus), new { #class = "selectButton" })
</div>
<input type="button" id="btnsearch" value="Search" />
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
</tr>
</thead>
</table>
</div>
</div>
}
</div>
<script>
$("#btnsearch").click(function () {
$('#table').bootstrapTable('showLoading');
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Search, MVC.MyController.Name)",
data: $('#formsearch').serialize(),
dataType: "json",
success: function (data) {
$('#table').bootstrapTable('hideLoading');
$('#table').bootstrapTable({
data: data,
striped: true,
pagination: true,
pageSize: 25,
pageList: [10, 25, 50, 100, 200],
search: false
});
$('#table').bootstrapTable('load', data).on('click-row.bs.table', function (e, row, $element) {
Showdetail(JSON.stringify(row));
});
},
error: function (err) {
console.log(err)
}
});
});
function Showdetail(jsonrow) {
var obj = JSON.parse(jsonrow);
window.location = "#Url.Action(MVC.MyController.ActionNames.ShowMyData, MVC.MyData.Name)?myDataId=" + obj.Id;
}
</script>
#section AddToHead
{
#Styles.Render("~/bundles/bootstrap-table/css")
}
#section scripts
{
#Scripts.Render("~/bundles/bootstrap-table")
}
So the javascript function ("#btnsearch").click gets the json data from public virtual JsonResult Search and sends that to bootstrapTable which loads the data in the table. What I want to do is to add a new header in my table, like this:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th></th>
</tr>
</thead>
</table>
And then in the last column add a delete button that has the id of that row (#Model.Id for instance) so that I can call the controller to delete the row from the database and then reload the table so that the row also disappears from the GUI.
I could easily do it with an ActionLink but since I don't loop through all objects and then draw them out on the page, I can't just add an ActionLink to the page. All the rendering of the rows is done in the bootstrapTable.
I looked at this question and answer and it seemed promising but it's not quite what I'm doing and I can't get my head around what I would need to do to get it working for me: Bootstrap table - dynamic button in row.
According to documantation and examples here:
https://live.bootstrap-table.com/example/column-options/events.html
Add to your scripts:
<script>
var $table = $('#table')
function operateFormatter(value, row, index) {
return [
'<a class="remove" href="javascript:void(0)" title="Remove">',
'<i class="fa fa-trash"></i> Delete',
'</a>'
].join('')
}
window.operateEvents = {
'click .remove': function (e, value, row, index) {
//edit here for ajax request to delete row.id record
$.ajax({
type: "POST",
url: "#Url.Action(MVC.MyController.ActionNames.Delete,MVC.MyController.Name)",
data: {id:row.id},
dataType: "json",
success: function (data) {
//when success remove row
$table.bootstrapTable('remove', {
field: 'id',
values: [row.id]
})
},
error: function (err) {
console.log(err)
}
});
}
}
</script>
and edit your html table:
<table id="table" class="table">
<thead>
<tr>
<th data-field="MyDataNumber" data-sortable="true">Number</th>
<th data-field="MyDataCreatedate" data-sortable="true">Created</th>
<th data-field="Status" data-sortable="true">Status</th>
<th data-field="operate" data-formatter="operateFormatter" data-events="operateEvents">Actions</th> <!--add this col-->
</tr>
</thead>
</table>
Related
I am trying to update a webpage so that when the delete button is pressed the attached row is removed from the table and the message_uid value is sent to the Flask route so I can process the request to actually change the message's status in the database. However the request does not send. I can get the row to be removed and have attempted to use a form to update instead but would need the delete function to not return any other value than edit the update section in the HTML.
route
#bp.route("/delete", methods=['GET','POST'])
def delete():
data = request.get_json()
data=delete(data, g.user)
return Response(dumps(data), mimetype="application/json")
inbox.html
<h1><b>Messages: </b></h1><div id="update"> </div>
<div class="table-responsive"
<table class="table table-bordered table-hover table-striped">
<tr>
<th></th>
<th>Status</th>
<th>Actions</th>
<th>Date</th>
<th>From</th>
<th>To</th>
<th>Subject</th>
<th>Body</th>
<th>References</th>
</tr>
{% for m in messages %}
{%if m.status!="deleted"%}
<tr >
<td><a class="btn btn-light" id="view" onClick="window.open('{{url_for('open_messages',message_id=m.message_uid)}}','View','resizable,height=500,width=500'); return false;" >View</a>
<input type="hidden" name="message_uid" value={{m.message_uid}} id="message_uid" /> <input type="submit" class="btn-sm btn-secondary" value="Delete" /></td>
<td>{{m.date}}</td>
<td>{{m.sender}}</td>
<td>{{m.recipient_username}}</td>
<td>{{m.subject}}</td>
<td>{{m.body}}</td>
<td>{{m.references}}</td>
</tr>
{%endif%}
{% endfor %}
</table>
<script>
$(document).on("click",".delete", function(e) {
e.preventDefault()
var id = $(".message_uid").val();
delete_id(id);
$(this).parents("tr").remove();
});
function delete_id(id) {
data = {
"id": id
}
console.log(data)
$.ajax({
type:"POST",
url: "/delete",
contentType: "application/json",
data: JSON.stringify(data),
success: function(data){
//displays dates if set
$("#update").html("Message Deleted");
console.log(data)
}
});
};
</script>
database processing
def delete(message_uid, user):
text="MATCH (m:MESSAGE) WHERE m.UID='{message_uid}' SET m.{user}_status='deleted' RETURN m".format(message_uid=message_uid, user=user)
verify=neo_execute(text)
return verify
I have a ViewModel with a parameter List. In the View, the user should be able to add or remove from that list such that the added or removed users are reflected in the POST for that parameter. In JQuery, after clicking an "Add" button, an ajax call returns a UserModel variable, but a simple .append doesn't add to the list.
The other questions I've seen on this issue deal with Partial Views, but this situation updates the table of UserModel without needing a Partial View. It seems like there should be an easy way to do this. Does anyone know how to add the returned UserModel to the List in JQuery so that the List will be returned to the Post with the added models?
<script>
$("#bUser").on('click', function () {
var $addedRecipient = $("#AddedRecipient");
if ($addedRecipient.val() != null && $addedRecipient.val() != "") {
$.ajax({
type: "GET",
url: '#Url.Action("GetFullRecipient", "Message")',
data: { CompanyID: $("#CompanyID").val(), Employee: $addedRecipient.val() },
success: function (data) {
$("#Recipients").append(data);//Not adding to Recipients (Model.List<UserModel>) - is there a simple solution like this?
var bRow = $('<tr></tr>'),
bCell = $('<td style="display:none"></td>').append(data.UserID);
bRow.append(bCell);
bCell = $('<td align="center"></td>').append(data.UserFirstName);
bRow.append(bCell);
bCell = $('<td align="center"></td>').append(data.UserEmail);
bRow.append(bCell);
bCell = $('<td align="center"><input type="button" class="btn btn-info removeRecipient" value="Remove"></td>');
bRow.append(bCell);
$("#bTable tbody").append(bRow);//Works with returned data
$addedRecipient.val("");
},
error: function () {
alert("Recipient could not be added.");
}
});
}
});
</script>
this code worked perfect for me, you just have to go through this list, obviously you have to put the #model directive and a type list Recipient.
#model List<...Models.Recipient>
<input type="button" id="btnAdd" class="btn btn-primary" value="Add"
onclick="myfunction()"/>
<script>
function myfunction() {
$.ajax({
type: 'GET',
contentType:"application/json; charset=utf-8",
url: '#Url.Action("GetFullRecipient","Message")',
data: { CompanyID: $("#CompanyID").val(), Employee:
$addedRecipient.val()},
success: function (response) {
$("#containerData").html(response);
},
error: function (result) {
alert(result);
}
});
}
</script>
<div id="containerData">
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Desc_Prod</th>
<th>Cantidad</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var item in Model)
{
<tr>
<td>#item.UserID</td>
<td>#item.UserFirstName</td>
<td>#item.UserEmail</td>
<td><a class="btn btn-danger" href="#Url.Action("DeleteRow","Message", new {item.UserID})">Delete</a></td>
</tr>
}
}
</tbody>
</table>
</div>
The answer here followed the link in freedomn-m's comment. Iterate through the Razor table using a for loop, then use a HiddenFor with the model parameter's ID and a CheckBoxFor as the model parameter's selecting field, and have a submit button with a unique name and value. When a button input is clicked and the value fits a given string, loop through the model and add a user that's not there or subtract a user that is there and return to the View.
<div class="row">
<div class="col-lg-12">
<table class="table table-bordered" id="bTable">
<thead>
<tr>
<th style="display:none"></th>
<th style="display:none"></th>
<th class="text-center">Recipient</th>
<th class="text-center">E-mail</th>
<th class="text-center">Select</th>
</tr>
</thead>
<tbody>
#if (Model.Recipients.Any())
{
for (var i = 0; i < Model.Recipients.Count; i++)
{
<tr>
<td style="display:none">#Html.HiddenFor(m => m.Recipients[i].RecipientUserID)</td>
<td style="display:none">#Html.HiddenFor(m => m.Recipients[i].RecipientCorporateID)</td>
<td align="center">#Model.Recipients[i].RecipientName</td>
<td align="center">#Model.Recipients[i].RecipientEmail</td>
<td align="center">#Html.CheckBoxFor(m => m.Recipients[i].RemoveRecipient)</td>
</tr>
}
}
</tbody>
</table>
</div>
</div>
why when i try to add select2 to new row the new select2 failed to initialize (it shown as select html tag).
Here's my code to create the table :
<table id="tbldet" class="table table-bordered table-striped table-hover" style="width:100%;margin:0 auto;">
<thead>
<tr>
<th><p>Nama Barang</p></th>
<th><p>Harga</p></th>
<th><p>Qty</p></th>
<th><p>Total</p></th>
<th style="width:50px"><p>Aksi</p></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select class="select2" name="det_brg" style="width:100%;">
</select>
</td>
<td>10000</td>
<td>4</td>
<td>930000</td>
<td><span class="btn btn-danger"><i class="fa fa-remove"></i></span></td>
</tr>
</tbody>
</table>
javascript function to initializeSelect :
function initializeSelect2(selectElementObj) {
selectElementObj.select2({
width: "80%",
tags: true,
language:"id",
ajax: {
url: "controller/barang_list.php",
dataType: "json",
type:"GET",
delay: 250,
data: function (params) {
return {
search: params.term
}
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
id:item.id,
text:item.text
}
})
};
},
cache: false
},
minimumInputLength: 3,
dropdownParent:$("#form-data")
});
};
$(".select2").each(function() {
initializeSelect2($(this));
});
here's the code to add new row :
//create new row
$("#add_row").click(function(e) {
//new row
$("#tbldet").append(
'<tr>\
<td>\
<select class="select2" name="det_brg" style="width:100%;">\
</select>\
</td>\
<td>10000</td>\
<td>4</td>\
<td>930000</td>\
<td><span class="btn btn-danger"><i class="fa fa-remove"></i></span></td>\
</tr>'
);
var newSelect=$(this).closest("tr").find(".select2");
initializeSelect2(newSelect);
})
i suspect there's problem with finding new 'select2' component on new row, but when i use alert(newSelect) it didn't show NULL / Undefined
Your suspicion is correct, your code will never find the new .select2 element. The reason has to do with the way .closest() works. You can investigate that here:
https://api.jquery.com/closest/
But in the mean time:
Change
var newSelect=$(this).closest("tr").find(".select2");
TO
var newSelect=$("#tbldet").find(".select2").last();
I have an ajax request for getting the purchased list of a user. I thought it was perfectly working because it returns the data that I need. But when I click the other user it seems the ajax request only send a request once. Becuase the data is the same, and when I look at the network tool of chrome, there is no another request was send.
This is my current Ajax request.
var purchased_list;
// $('#student_profile_purchased_item_list_tab').click(function(){
function createTablePurchasedList(id){
console.log("Start, student:"+id);
purchased_list= $('#purchased_item_list_table').DataTable({
// "processing": true,
// "paging": false,
// "ordering": true,
"ajax": {
url:'{{ route("student_item_list") }}?student_id='+id,
cache: true,
dataSrc: "",
},
columnDefs: [
{
className: "dt-center",
targets: [0],
},
],
"columns": [
{
data: "date_purchased"
},
{
data: "product_status_id",
render: function(data, type, row){
switch(data){
case 2:
return 'Purchased';
case 3:
return '<p style="color:red;">Consumed</p>';
case 6:
return '<p style="color:green;">Transferred</p>';
}
}
},
{
data: "name",
render: function(data, type, row){
return data;
}
},
]
});
console.log("End, student:"+id);
}
// });
Tab
<li>Purchased Item List</li>
Datatable
<div class="tab-pane fade in" id="student_profile_purchased_item_list">
<div style="position:relative;">
<div class="other_content_header">
Item List
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table width="100%" class="responsive table table-striped table-bordered table-hover purchase-item-table" id="purchased_item_list_table" style="font-size:12px; text-align:center;">
<thead>
<tr>
<th>Date</th>
<th>Item Status</th>
<th>Product Name</th>
{{-- <th>Quantity</th> --}}
{{-- <th> </th> --}}
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
every time I click a user the console.log result changes, At first I thought the ID is not changing when I click another user. But when I do the console log the result changes.
Hope someone can help me solve my problem.
I prepared a page with products and their details. Details are to appear when you press the button. Using a foreach loop I generated tables with the products and a link to the details.
Unfortunately, only the top-form works asynchronously. Others open partialView. What should I do to make the script work for all forms?
<table>
<thead>
<tr>
<th>
IdPromo
</th>
<th>
Name
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.crosspromocje)
{
<tr>
<td>
#using (Html.BeginForm("Details", "promo", FormMethod.Post, new { id = "my-form"} ))
{
#Html.Hidden("IdPromo ", item.IdPromo)
<input type="submit" value="#item.IdPromo" />
}
</td>
</tr>
}
</tbody>
</table> <div id="result"></div>
#section scripts{
<script type="text/javascript">
$(function () {
$("#my-form").on("submit", function (e) {
e.preventDefault();
$.ajax(
{
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (data) {
$("#result").html(data);
}
});
});
});
</script>
}
`
I found the answer. It was necessary to change the id to a class.
From:
#using (Html.BeginForm("Details", "xp", FormMethod.Post, new { id = "my-form}))
$("#my-form").on("submit", function (e)
To:
#using (Html.BeginForm("Details", "xp", FormMethod.Post, new { #class = "my-form" }))
$(".my-form").on("submit", function (e)