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)
Related
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>
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>
i want to enter only unique Machine_serial_no in my editor templates , user can add Machine_serial_no through browsing a file or can enter manually As shown in below code, i just want to make sure that user shouldnot allow to enter same value twice .your suggestion is always welcome
..Thanks in advance..
//main view
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery-ui-1.9.2.min.js"></script>
<div id="cast">
<tr>
<td> File:</td>
<td><input type="file" id="file" /> </td>
<td> <input type="button" value="Upload" id="btnSubmit" /> </td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="manualSerial">
<td class="required">Total No of serial no U want to enter:</td>
<td>#Html.TextBoxFor(x => x.count, new { #Value = 0 })</td>
<td colspan="4">
<input type="button" value="Add Serial" id="addserial" />
#*#Html.ActionLink("Add Serial", "AddMachineSerial", "Import", new { #id = "addserial" ,})
#Html.ValidationMessageFor(model => model.serials.Machine_serial_no)*#
</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td id="ShowModel" colspan="6">
<table id="tbl1" style="width:100%;">
<thead>
<tr>
<td>Brand</td>
<td>Machine</td>
<td>Model</td>
<td>Serial No</td>
<td>Mac Address</td>
<td>Action</td>
</tr>
</thead>
</table>
</td>
</tr>
<tr>
<td id="ShowModel" colspan="6">
<div style="height:253px; width:100% ;overflow: auto;">
<table style="width:100%;margin-left:0px;margin-right:0px">
#*<thead>
<tr>
<th style="width:45px;">Brand</th>
<th style="width:90px;">Machine</th>
<th style="width:80px;">Model</th>
<th>Serial No</th>
<th>Mac Address</th>
<th>Action</th>
</tr>
</thead>*#
<tr>
<td colspan="6" id="td_serial"></td>
</tr>
</table>
</div>
</td>
</tr>
//jquery
$('#addserial').click(function () {
var count = $('#count').val();
var i;
if ($('#searchid').val() != '') {
if ($('#count').val() != 0) {
for (i = 0; i < count; i++) {
$.ajax({
type: 'GET',
data: { mid: $('#machineTypes_MTId').val(), modelName: $('#searchid').val(), modelId: $('#searchValue').val() },
url: '#Url.Action("AddMachineSerial","Import")',
success: function (response) {
$('#ShowModel').show();
$('#td_serial').prepend(response);
$('#count').val(0);
}
});
}
}
else {
alert("Enter no of serial you want to enter!")
}
}
else {
alert("select Model First!")
$('#count').val(0);
}
});
//editor Templates /parital view
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
#using (Html.BeginCollectionItem("serialList"))
{
#Html.ValidationSummary(true)
<div id="DeleteTxt1">
<table id="tbl1" style="width:100%;margin-left:0px;margin-right:0px">
<tr class="importitem1">
<td>#Model.brandName</td>
<td>#Model.machineName</td>
<td>#Model.MachineModel</td>
#*<td class="required">Machine Serial No.:</td>*#
<td>
#Html.TextBoxFor(x => x.Machine_serial_no, new { placeHolder = "Enter Machine Serial here.", #class = "serial1"})
#Html.ValidationMessageFor(x => x.Machine_serial_no)
</td>
<td><input type="button" value="Cancel" id="DeleteBtn1" style="color:red;" /></td>
</tr>
</table>
</div>
}
Assuming you want to alert the user as soon as they enter a non unique value, then you need to handle the .change() event of the textbox, and since the textboxes are being added dynamically, you need to use event delegation
$('#td_serial').on('change', '.serial1', function() {
var isvalid = true;
var inputs = $('.serial1').not($(this));
var text = $(this).val();
$.each(inputs, function(index, item) {
if ($(this).val() && $(this).val() === text) {
isvalid = false;
return false;
}
});
if (!isvalid) {
alert('not unique!');
}
});
Note the alert('not unique!') is just for testing purposes - its not clear how you want to notify the user - e.g. include a div with an error message that your might show/hide as required
Next your partial includes #Html.ValidationMessageFor(x => x.Machine_serial_no) suggesting you have validation attributes. In order to get client side validation for dynamically created elements you need to re-parse the validator when the new elements have been added. Modify your script to
for (i = 0; i < count; i++) {
$.ajax({
type: 'GET',
data: { mid: $('#machineTypes_MTId').val(), modelName: $('#searchid').val(), modelId: $('#searchValue').val() },
url: '#Url.Action("AddMachineSerial","Import")',
success: function (response) {
$('#ShowModel').show();
$('#td_serial').prepend(response);
$('#count').val(0);
// Reparse the validator
$('form').data('validator', null);
$.validator.unobtrusive.parse(form);
}
});
}
Side note - consider modifying this so that you only re-parse once all ajax calls are complete
Note also that you should only have one #Html.ValidationSummary(true) (your currently is adding one for each partial) and you need to remove the scripts from the partial - your should have one copy of the scripts only in the main view
I think this is you want to validate client side
$(function (){
$('#partialViewtextbox_Id').change(function (){
var partial = $('#partialViewtextbox_Id').val();
var main = $('#maintextbox_Id').val();
if(partial == main)
{
alert("value already available");
}
});
});
I have a small application in MVC4. It has a grid and every row has two things.
1) ID
2) Button
When user click on a button I need to invoke a javascript function passing ID as an parameter. How can I do this in MVC. I can eaisly do thin in case of . Please help
Below is my code.
#model IEnumerable<Models.Asset>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Id
</th>
<th>
Show
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td width="80">
#item.Id
</td>
<td>
<button class="btnView" onclick="myfunction(#item.someProperty)">Show</button>
///How can I pass #item.someProperty as an parameter to click handler?
</td>
</tr>
}
</table>
<div id="imageDisplay">
<p>
</p>
</div>
#section scripts{
<script type="text/javascript">
$(function () {
$('#imageDisplay').dialog({
autoOpen: false
});
$('.btnView').click(function () {
alert('ok');
//How can I get id as an parameter to this function?
});
});
</script>
}
Firstly just remove onclick handler from the button(You don't need it as you are handling click event with jquery)
Try this :
HTML :-
<td>
<button class="btnView" data-prop="#item.someProperty">Show</button>
</td>
JQUERY :-
$('.btnView').click(function () {
var prop = $(this).attr('data-prop');
alert(prop);
});
OR
$('.btnView').click(function () {
var prop = $(this).data('prop');
alert(prop);
});
OR(if you don't want to add data-prop on button then you can follow below answer,Just catch 'Id' which is there in td of your table)
$('.btnView').click(function () {
var id = $(this).closest('tr').find('td').eq(0).text();
alert(id);
});
Remove the onclick handler from the button (you don't have a function called myfunction)
Since you already have the ID value in the previous column, you can get it using
$('.btnView').click(function () {
var id = $(this).closest('tr').children('td').eq(0).text();
});
One data binding works well and display automatic data but when I add another copying the same pattern of first, second gives error and do not work. So in below example if I do comment anyone, another do not work.
HTML CODE:
<table>
<thead>
<tr><th>Item Name</th><th>Price</th></tr>
</thead>
<tbody data-bind="foreach: itemsdisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
</tr>
</tbody>
</table>
<table>
<thead>
<tr><th colspan="3" style="color:#06C">Stock Market Metal Rates</th></tr>
</thead>
<tbody data-bind="foreach: MetalDisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
<td data-bind="text: Dated" />
</tr>
</tbody>
</table>
This is my JS code:
function GetProducts(handleData) {
$.ajax({
url: 'form.php',
type: "post",
data: '',
dataType: 'json',
success: function(data){
handleData(data);
},
error:function(data){
alert('Failed');
}
});
}
function GetMetals(handleData) {
$.ajax({
url: 'form2.php',
type: "post",
data: '',
dataType: 'json',
success: function(data){
handleData(data);
},
error:function(data){
alert('Failed');
}
});
}
$(function () {
var ItemDisplayViewModel = function() {
var self = this;
self.itemsdisplay = ko.observableArray();
self.update = function() {
GetProducts(function(output){
self.itemsdisplay.removeAll();
$.each(output, function (i) {
self.itemsdisplay.push(new product(output[i]));
});
});
}
};
var MetalViewModel = function() {
var self = this;
self.MetalDisplay = ko.observableArray();
self.update = function() {
GetMetals(function(output){
self.MetalDisplay.removeAll();
$.each(output, function (i) {
self.MetalDisplay.push(new metals(output[i]));
});
});
}
};
var ItemDisplayViewModel = new ItemDisplayViewModel();
window.setInterval(ItemDisplayViewModel.update,1000);
ko.applyBindings(ItemDisplayViewModel);
var MetalViewModel = new MetalViewModel();
window.setInterval(MetalViewModel.update,1000);
ko.applyBindings(MetalViewModel);
});
var product = function (data) {
return {
Name: ko.observable(data.Name),
Price: ko.observable(data.Price)
};
};
var metals = function (data) {
return {
Name: ko.observable(data.Name),
Price: ko.observable(data.Price),
Dated: ko.observable(data.Dated)
};
};
Can anyone help please!
You can do the following.
Provide id for both the tables
<table id="item">
<thead>
<tr><th>Item Name</th><th>Price</th></tr>
</thead>
<tbody data-bind="foreach: itemsdisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
</tr>
</tbody>
</table>
<table id="metal">
<thead>
<tr><th colspan="3" style="color:#06C">Stock Market Metal Rates</th></tr>
</thead>
<tbody data-bind="foreach: MetalDisplay">
<tr>
<td data-bind="text: Name" />
<td data-bind="text: Price" />
<td data-bind="text: Dated" />
</tr>
</tbody>
</table>
The modify your script to pass the table element to ko.applyBindings method as below.
var itemDisplayViewModel = new ItemDisplayViewModel();
var x = window.setInterval(itemDisplayViewModel.update,1000);
ko.applyBindings(itemDisplayViewModel,document.getElementById("item"));
var metalViewModel = new MetalViewModel();
var y = window.setInterval(metalViewModel.update,1000);
ko.applyBindings(metalViewModel, document.getElementById("metal"));
Please refer 'Activating knockout' section in http://knockoutjs.com/documentation/observables.html - The part of text from the link given below.
For example, ko.applyBindings(myViewModel, document.getElementById('someElementId')). This restricts the activation to the element with ID someElementId and its descendants, which is useful if you want to have multiple view models and associate each with a different region of the page.
What you are doing does not work. you need to do it like this.
ko.applyBindings(ItemDisplayViewModel,document.getElementById('first_div_id'));
ko.applyBindings(MetalViewModel,document.getElementById('second_div_id'));
Or here is another method
var viewModel = function(){
var self = this
self.Item = ko.observable(new ItemDisplayViewModel())
self.Metal = ko.observable(new MetalViewModel())
}
ko.applyBindings(viewModel)
And now
<table data-bind="with:Item">
.
.
.
</table>
<table data-bind="with:Metal">
.
.
.
</table>
And finally
window.setInterval(viewModel.Item().update, 1000);
window.setInterval(viewModel.Metal().update, 1000);
You can take a look at this post for better understanding.