I 'm newebie in Asp.net MVC 5
So , I have a simple project in which i'm usiong asp.net . I have an object named :
Object { Id, Code, Name} .
I want to list the Objects in grid , edit , add and remove .
I am able to show the list and add new object .
Those operations are in modal dialog .
I have some problems now :
How to send the Object to the action Controller then show it or edit itinto a modal dialog using javascript when i choose it ?
The second picture is when i click add new Object , it shows me the modal dialog , and all works fine with the Add , biut not with the others actions.
My Code
ObjectController :
public ActionResult AddObject()
{
if (Request.IsAjaxRequest())
return PartialView(dd);
return View(dd);
}
[HttpPost]
public ActionResult AddObject(ModelObject model)
{
/* Working Code */
}
AddObject partial View :
#using (Ajax.BeginForm("AddObject", "Object",
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "msgAdd",
OnSuccess = "addSuccess",
OnFailure = "addFailure"
},
new { #class = "form-horizontal" }))
{
#Html.ValidationSummary(true);
<div class="row" style="padding: 5px 0 5px 0">
<div class="col-lg-12">
<div class="col-lg-12 border no-margin" style="padding:10px 0px 10px 0 !important">
<div class="form-group" style="align-content:center">
<label class="col-sm-4 control-label">Code </label>
<div class="col-lg-6">
#Html.TextBoxFor(m => m.Code, new { #class = "form-control", placeholder = "Code" })
#Html.ValidationMessageFor(m => m.Code)
</div>
<label class="col-sm-4 control-label">Libellé </label>
<div class="col-lg-6">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", placeholder = "Libellé " })
#Html.ValidationMessageFor(m => m.Name)
</div>
</div>
</div>
</div>
</div>
<div class="hr-line-solid no-margin"></div>
<div class="row" style="padding: 5px 0 5px 0">
<div class="col-sm-1 col-sm-offset-4">
<button type="reset" class="btn btn-outline btn-primary"><i class="icon-refresh icon-white"></i> Réinitialiser</button>
</div>
<div class="col-sm-3 col-sm-offset-4">
<button type="reset" class="btn btn-default right" data-dismiss="modal">Annuler</button>
<input type="submit" value="Enregistrer" class="btn btn-success right" />
</div>
</div>
<div id="msgAdd" style="display:none">
</div>
}
</div>
ListObjects View :
<tbody>
#foreach (var m in Model.objects)
{
<tr class="gradeX">
<td id="idObject" style="display:none;"><span class="hideextra">#m.Id</span></td>
<td><span class="hideextra">#m.Code</span></td>
<td><span class="hideextra">#m.Name</span></td>
<td class="infont">
<center>
<a id="btnEdit"><i class="fa fa-pencil-square-o text-"></i></a>
<i class="fa fa-trash-o text-danger"></i>
<i class="fa fa-search text-navy"></i>
</center>
</td>
</tr>
}
</tbody>
Javascript :
1- For adding :
$(document).ready(function () {
//jQuery.noConflict();
$("#btn").click(function () {
var url = "AddObject"; // the url to the controller
$.get(url, function (data) {
$("#saisieJDiag").draggable({
handle: ".modal-header"
});
$("#saisieJDiag").resizable();
$("#saisieJDiag").html(data);
$("#saisieJDiag").modal("show");
$('#saisieJDiag').on('shown.bs.modal', function () {
$('.chosen-select', this).chosen();
});
$('.i-checks').iCheck({
checkboxClass: 'icheckbox_square-green',
radioClass: 'iradio_square-green',
});
});
});
});
</script>
Now I want the same approch but to edit and show the obecjt on the modal , how i can do that !
Related
I am working on a survey application using Asp.net MVc. My events in jquery popup are triggered more than once. The more a popup is opened, the more it triggers in the event in the popup. What is the reason of this. Every time browsers are opened, the temporary javascript file that starts with the VM is removed. When the popup is closed, these opened virtual javascript files are not destroyed. What is the reason of this?
These events include adding rows to the table, updating and deleting rows.The AddOrEdit.cshtml file contains both screen components and javascript codes.
Images;
AddOrEdit.cshtml(Jquery Popup)
#using MerinosSurvey.Models
#model Questions
#{
Layout = null;
}
#using (Html.BeginForm("AddOrEdit", "Question", FormMethod.Post, new { onsubmit = "return SubmitForm(this)", onreset = "return ResetForm(this)", id = "questionForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group row">
#Html.Label("QuestionId", "Soru No", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.TextBoxFor(model => model.QuestionId, new { #readonly = "readonly", #class = "form-control", })
</div>
</div>
<div class="form-group row">
#Html.Label("QuestionName", "Soru Adı", new { #class = "col-form-label col-md-3" })
<div class="col-md-9">
#Html.EditorFor(model => model.QuestionName, new { htmlAttributes = new { #class = "form-control"
} })
#Html.ValidationMessageFor(model => model.QuestionName)
</div>
</div>
<div class="form-group row">
<div class="col-md-9 offset-md-3">
<div class="custom-control custom-checkbox">
#Html.CheckBoxFor(m => m.IsOtherOptionRequired, new { #class = "custom-control-input ", id = "IsOtherOptionRequired", })
<label class="custom-control-label" for="IsOtherOptionRequired">Diğer Seçeneği Eklensin mi?
</label>
</div>
</div>
</div>
<br>
<hr class="style14">
<br>
#Html.ValidationMessageFor(model => model.Options)
<div class="table-wrapper form-group table-responsive-md">
<div class="table-title">
<div class="form-group row">
<div class="col-md-9">Options</div>
<div class="col-md-3">
<button type="button" class="btn btn-success add-new" style="margin-bottom: 10px"><i class="fa fa-plus"></i>Add Option</button>
</div>
</div>
</div>
<table class="table optionTable">
<thead class="thead-light">
<tr>
<th style="display:none;" width="20%" scope="col">Seçenek Id</th>
<th scope="col">Option Name</th>
<th width="25%" scope="col">Update/Delete</th>
</tr>
</thead>
<tbody>
#foreach (Options options in Model.Options)
{
<tr>
<td style="display:none;">#options.OptionId</td>
<td>#options.OptionName</td>
<td>
<a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip">
<i class="fa fa-check">Approve</i>
</a>
<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip">
<i class="fa fa-pencil">Update</i>
</a>
<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip">
<i class="fa fa-trash">Delete</i>
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="form-group row d-flex justify-content-end">
<button type="submit" class="btn btn-primary" style="margin-bottom: 10px; color: black"><i class="fa fa-save"></i>Kaydet</button> </div>
}
Jquery add, edit, delete click events
<script>
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip();
//var actions = $("table.optionTable td:last-child").html();
var actions =
' <a class="add btn btn-primary btn-sm" title="Add" data-toggle="tooltip"><i class="fa fa-check">Onayla</i></a>' +
'<a class="edit btn btn-secondary btn-sm" title="Edit" data-toggle="tooltip"><i class="fa fa-pencil">Güncelle</i></a>' +
'<a class="delete btn-danger btn-sm" title="Delete" data-toggle="tooltip"><i class="fa fa-trash">Sil</i></a>';
// Append table with add row form on add new button click
$(".add-new").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
$(this).attr("disabled", "disabled");
$(".btnSubmit").attr("disabled", "disabled");
var index = $("table.optionTable tbody tr:last-child").index();
var row = '<tr>' +
'<td style="display:none;">0</td>' +
'<td><input type="text" class="form-control" name="optionName" id="optionName"></td>' +
'<td>' +
actions +
'</td>' +
'</tr>';
$("table.optionTable").append(row);
$("table.optionTable tbody tr").eq(index + 1).find(".add, .edit").toggle();
$('[data-toggle="tooltip"]').tooltip();
});
// Add row on add button click
$(".add").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function () {
if (!$(this).val().trim()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function () {
$(this).parent("td").html($(this).val().trim());
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").removeAttr("disabled");
$(".btnSubmit").removeAttr("disabled");
}
});
// Edit row on edit button click
$(".edit").click(function () { //RUNS MULTIPLE TIMES ON CHROME
debugger;
/*td: nth - child(2)*/
//$(this).parents("tr").find("td:nth-child(2)").each(function () {
$(this).parents("tr").find("td:not(:first-child, :last-child)").each(function () {
$(this).html('<input type="text" class="form-control" value="' + $(this).text() + '">');
});
$(this).parents("tr").find(".add, .edit").toggle();
$(".add-new").attr("disabled", "disabled");
$(".btnSubmit").attr("disabled", "disabled");
});
// Delete row on delete button click
$(".delete").click(function () {//RUNS MULTIPLE TIMES ON CHROME
debugger;
$(this).parents("tr").remove();
$(".add-new").removeAttr("disabled");
var rowCount = $('table.optionTable tbody tr').length;
if (rowCount > 0) {
$(".btnSubmit").removeAttr("disabled");
} else {
$(".btnSubmit").attr("disabled", "disabled");
}
});
});
It seems you are binding event multiple time by using class selector. It means After adding new DOM in the document, bind a click event on newly added action buttons, but it is binding click event on existing action buttons also.
So simple tick to solve your problem is you have to unbind existing click event and bind new once.
$(".add-new").unbind('click').bind('click', function(){
//your code here
});
$(".add").unbind('click').bind('click', function(){
//your code here
});
$(".edit").unbind('click').bind('click', function(){
//your code here
});
$(".delete").unbind('click').bind('click', function(){
//your code here
});
You can use jQuery on/off methods to handle this.
$(".add-new").off('click').on('click', function(){
});
When you open popup for the second time I believe running $(".add-new").length will return 2 for you. Try to resolve that first which will automatically resolve your events problem.
Do changes such that $(".add-new").length is always 1
Hello i am using MVC 5 c# with ado net code , i am inserting master data and master detail data when i insert data and click save all then event fire but value not pass to controller obj show null value , i try a lot but i could not find problem that's why i am sharing code and help senior people maybe you could understand better and easy find problem. i am sharing javascript code view code and controller code function code . when i debug javascript code i did not find any problem in javascript and there is no error in javascript code .
View
<main class="pt-5 mx-lg-5">
<div class="container-fluid mt-5">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_content">
<div class="panel panel-primary">
<div class="panel-heading">
</div>
<div class="panel-body" style="background-color:#F0FFFF">
<button type="button" id="btnAddnew" class="btn btn-primary" data-toggle="modal" data-target="#centralModalLGInfoDemo" style="float:right">Add New</button>
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Sr No</th>
<th>Item Desc</th>
<th>Qty</th>
<th>Remarks</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Requisitions)
{
<tr>
<td>#Html.DisplayFor(module => item.Srno)</td>
<td>#Html.DisplayFor(module => item.ItemDesc)</td>
<td>#Html.DisplayFor(modelItem => item.Qty)</td>
<td>#Html.DisplayFor(modelItem => item.Remarks)</td>
<td>
<a onclick="GetDetails(#item.ReqNo)">
<i class="fa fa-edit"></i>
</a>
<a>
#Html.ActionLink(" ", "DeleteCustomer", "Home", new { id = item.ReqNo }, new { onclick = "return confirm('Are sure wants to delete?');", #class = "fa fa-trash-o" })
</a>
</td>
</tr>
}
</tbody>
<tfoot>
</tfoot>
</table>
</div>
</div>
</div>
<!---End-->
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="centralModalLGInfoDemo" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-notify modal-info" role="document">
<!--Content-->
<div class="modal-content" style="width:140%">
<!--Header-->
<div class="modal-header">
<p class="heading lead">Add New Requisition</p>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" class="white-text">×</span>
</button>
</div>
<!--Body-->
<form id="NewOrderForm">
<div class="modal-body">
<div class="form-row">
<div class="col">
<!-- Requisition Date -->
<div class="md-form">
#Html.TextBox("ReqNo", (String)ViewBag.ReqNo, new { #class = "form-control mr-sm-3", #id = "txtRequisitionno" })
<label for="lblRequisition">Requisition No.</label>
</div>
</div>
<div class="col">
<!-- Requisition Date -->
<div class="md-form">
#Html.TextBoxFor(m => m.ReqDate, new { #class = "form-control", #id = "txtRequisitionDatepicker" })
<label for="lblRequisitionDatepicker">Requisition Date</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
#Html.TextBoxFor(m => m.Job, new { #class = "form-control", #id = "txtjob" })
<label for="lbljob">Job</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
#Html.TextBoxFor(m => m.Approvedby, new { #class = "form-control", #id = "txtApprovedby" })
<label for="lblApprovedby">Approved by</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<div class="custom-control custom-checkbox">
<span style="float:right">
#Html.CheckBoxFor(m => m.IsApproved, new { #class = "custom-control-input", #id = "defaultChecked2" })
<label class="custom-control-label" for="defaultChecked2">Approved</label>
</span>
</div>
</div>
</div>
</div>
<!--Detail-->
<h5 style="margin-top:10px;color:#ff6347">Requisition Details</h5>
<hr />
<div>
<div class="form-row">
<div class="col-md-1">
<!-- Requisition Date -->
<div class="md-form">
<input type="text" id="SrNo" name="SrNo" placeholder="Srno" class="form-control" />
<label for="lblSrno">Sr No.</label>
</div>
</div>
<div class="col-md-4">
<!-- Requisition Date -->
<div class="md-form">
#Html.DropDownListFor(m => m.ItemCode, ViewBag.Items as List<SelectListItem>, new { #class = "form-control", id = "txtItemcode" })
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<input type="number" id="Qty" name="Qty" placeholder="Qty" class="form-control" />
<label for="lbljob">Qty</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<input type="text" id="Reemarks" name="Reemarks" placeholder="Remarks" class="form-control" />
<label for="lblRemarks">Remarks</label>
</div>
</div>
<div class="col-md-2 col-lg-offset-4">
<a id="addToList" class="btn btn-primary">Add To List</a>
</div>
</div>
<table id="detailsTable" class="table">
<thead style="background-color:#33b5e5; color:white">
<tr>
<th style="width:2%">SrNo.</th>
<th style="width:40%">Items</th>
<th style="width:15%">Qty</th>
<th style="width:30%">Remarks</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button type="reset" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="saveRequisition" type="submit" class="btn btn-danger">Save Order</button>
</div>
</div>
</form>
</div>
<!--/.Content-->
</div>
</div>
</div>
</main>
javascript
<script>
//Show model
function addNewOrder()
{
$("#NewOrderForm").modal();
}
// Add Multiple Record
$("#addToList").click(function (e) {
e.preventDefault();
if ($.trim($("#SrNo").val()) == "" || $.trim($("#txtItemcode").val()) == "" || $.trim($("#Qty").val()) == "" || $.trim($("#Reemarks").val()) == "") return;
var Srno = $("#SrNo").val(),
items = $("#txtItemcode").val(),
qty = $("#Qty").val(),
remark = $("#Reemarks").val(),
detailsTableBody = $("#detailsTable tbody");
var ReqItems = '<tr><td>' + Srno + '</td><td>' + items + '</td><td>' + qty + '</td><td>' + remark + '</td><td> <a data-itemId="0" href="#" class="deleteItem">Remove</a></td></tr>';
detailsTableBody.append(ReqItems);
clearItem();
//After Add A New Order In The List
function clearItem()
{
$("#SrNo").val('');
$("#txtItemcode").val('');
$("#Qty").val('');
$("#Reemarks").val('');
}
// After Add A New Order In The List, If You Want, You Can Remove
$(document).on('click', 'a.deleteItem', function (e)
{
e.preventDefault();
var $self = $(this);
if ($(this).attr('data-itemId') == "0") {
$(this).parents('tr').css("background-color", "white").fadeOut(800, function () {
$(this).remove();
});
}
});
//After Click Save Button Pass All Data View To Controller For Save Database
function saveRequisition(data) {
return $.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: "/Home/RequisitionInsert", // function save
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveRequisition").click(function (e)
{
e.preventDefault();
var requisitionArr = [];
requisitionArr.length = 0;
$.each($("#detailsTable tbody tr"), function () {
requisitionArr.push({
Srno: $(this).find('td:eq(0)').html(),
items: $(this).find('td:eq(1)').html(),
qty: $(this).find('td:eq(2)').html(),
remark: $(this).find('td:eq(3)').html(),
});
});
var data = JSON.stringify({
txtRequisitionno: $("#txtRequisitionno").val(),
txtRequisitionDatepicker: $("#txtRequisitionDatepicker").val(),
txtjob: $("#txtjob").val(),
txtApprovedby: $("#txtApprovedby").val(),
defaultChecked2: $("#defaultChecked2").val(),
item: requisitionArr
});
$.when(saveRequisition(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
});
</script>
Controller
[HttpPost]
public ActionResult RequisitionInsert(Requisition objModel, List<Requisition> oblist)
{
try
{
int result = objclsRequisition.RequisitionInsert(objModel, oblist);
if(result==1)
{
ViewBag.Message = "Your record has been inserted Successfully";
ModelState.Clear();
}
else
{
ViewBag.Message = "Unsucessfull";
ModelState.Clear();
}
return RedirectToAction("Requisition", "Home");
}
catch (Exception)
{
throw;
}
}
Function
public int RequisitionInsert(Requisition Req, List<Requisition> objlist)
{
try
{
con.Open();
tr = con.BeginTransaction();
cmd = new SqlCommand("Sp_RequisitionMainInsert", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ReqNo", Req.ReqNo);
cmd.Parameters.AddWithValue("#Comp_ID", "1");
cmd.Parameters.AddWithValue("#GL_Year", "2018-2019");
cmd.Parameters.AddWithValue("#ReqDate", Req.ReqDate.ToString("yyyy-MM-dd"));
cmd.Parameters.AddWithValue("#Job", Req.Job);
cmd.Parameters.AddWithValue("#ApprovedBy", Req.Approvedby);
cmd.Parameters.AddWithValue("#UserName", System.Web.HttpContext.Current.Session["AgentName"]);
cmd.Parameters.AddWithValue("#IsApproved", Req.IsApproved);
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
for (int i = 0; i < objlist.Count; i++)
{
cmd = new SqlCommand("Sp_RequisitionDetailInsert", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ReqNo", Req.ReqNo);
cmd.Parameters.AddWithValue("#Comp_ID", "1");
cmd.Parameters.AddWithValue("#GL_Year", "2018-2019");
cmd.Parameters.AddWithValue("#SrNo", Req.Srno);
cmd.Parameters.AddWithValue("#ItemCode", Req.ItemCode);
cmd.Parameters.AddWithValue("#Qty", Convert.ToDecimal(Req.Qty));
cmd.Parameters.AddWithValue("#Remarks", Req.Remarks);
}
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
tr.Commit();
return i;
}
catch (SqlException sqlex)
{
tr.Rollback();
throw sqlex; // read all sql error
}
catch (Exception ex)
{
tr.Rollback();
throw ex; // General execption
}
finally
{
con.Close();
}
}
The issue lays in the api model definition.
You have declared your methods parameters as this
[HttpPost]
public ActionResult RequisitionInsert(Requisition objModel, List<Requisition> oblist)
But, when posting data in MVC you can only have one input model as that model will be parsed straight from the complete request body.
To solve this, create a request model where you define the properties to read from the body.
public class RequestModel
{
public string TxtRequisitionno { get; set; }
public string TxtRequisitionDatepicker { get; set; }
public string Txtjob { get; set; }
public string TxtApprovedby { get; set; }
public string DefaultChecked2 { get; set; }
public List<Requisition> Items { get; set; }
}
And then use it
[HttpPost]
public ActionResult RequisitionInsert(RequestModel model)
NOTE: I have declared the properties in the RequestModel as the same you try to send from the client
Your client model:
{
txtRequisitionno: $("#txtRequisitionno").val(),
txtRequisitionDatepicker: $("#txtRequisitionDatepicker").val(),
txtjob: $("#txtjob").val(),
txtApprovedby: $("#txtApprovedby").val(),
defaultChecked2: $("#defaultChecked2").val(),
item: requisitionArr
};
I have a page that allows you to create Income Types, but if you click the Create button, in succession then it creates multiple entries, Is there a way to have it limit this to you press it once and that is it?
I have looked at the code it uses an ajax method to get the information then post the form to the database. Some of my code below:
Index
#section scripts {
<script language="javascript" type="text/javascript">
#* DOM ready? *#
$(function () {
#* Pagination Async Partial Handling *#
$(document).on("click", "#indexPager a", function () {
if ($(this).parent().hasClass('disabled') || $(this).parent().hasClass('active'))
return false;
$.ajax({
url: $(this).attr("href"),
type: 'GET',
cache: false,
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
$(document).on("change", "#pageSizeSelector", function () {
var selectedValue = $(this).val();
$.ajax({
url: selectedValue,
type: 'GET',
cache: false,
success: function(result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
});
#* Sorting Async Partial Handling *#
$(document).on("click", "#tableHeader a", function () {
$.ajax({
url: $(this).attr("href"),
type: 'GET',
cache: false,
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
#* Apply ACTION colours for hover *#
addTableStylingScripts();
});
</script>
}
#section additionalStyles {
#Styles.Render("~/plugins/datatables/media/css/cssDatatables")
}
#section modal {
}
<article class="row">
<h1 class="pageTitle artistHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-12">
<div class="panel panel-visible" id="tableContainer">
#Html.Partial("_IncomeTypeManagementList", Model)
</div>
</div>
</article>
IncomeTypeManagementList
#* Header *#
<div class="panel-heading createContentTitle">
<div class="panel-title createLink">
<a href="#Url.Action("Create", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Add Income Type" id="createIncomeTypeLink">
<span class="fa fa-file"></span> Add Income Type
</a>
</div>
</div>
#* Body *#
<div class="panel-body pn">
<table class="table table-striped table-hover dataTable incomeTypesTable admin-form theme-primary" cellspacing="0" width="100%" role="grid">
<thead id="tableHeader">
<tr>
<th class="hidden-xs sorting #Html.SortTitleItem("IncomeTypeGroupId", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "IncomeTypeGroupId",
sortAsc = Model.PagingInfo.SortPropertyName != "IncomeTypeGroupId" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by group">Group</a>
</th>
<th class="sorting #Html.SortTitleItem("Name", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "Name",
sortAsc = Model.PagingInfo.SortPropertyName != "Name" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by name">Name</a>
</th>
<th class="hidden-xs sorting hidden-xs #Html.SortTitleItem("CreatedDate", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "CreatedDate",
sortAsc = Model.PagingInfo.SortPropertyName != "CreatedDate" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by date">Created</a>
</th>
<th class="bg-white">
<div class="text-center">Action</div>
</th>
</tr>
</thead>
<tbody>
#foreach (var it in Model.IncomeTypes)
{
var actionId = "action_" + tableRowIndex;
var editIncomeTypeId = "editIncomeType_" + tableRowIndex;
<tr data-id="#it.ID"
data-isdeleted="#it.IsDeleted"
data-rowversion="#it.RowVersion"
data-createddate="#it.CreatedDate"
data-name="#it.Name"
data-incometypegroupid="#it.IncomeTypeGroupId"
data-incometypegroupname="#it.IncomeGroupName">
<td class="hidden-xs">
#it.IncomeGroupName
</td>
<td>
#it.Name.Truncate(50)
</td>
<td class="hidden-xs">
#it.CreatedDate.ToShortDateString()
</td>
<td class="updateTableRow text-center">
<div class="dropdownContainer btn-group text-right">
<button type="button" class="btn btn-primary br2 btn-xs fs12 dropdown-toggle" data-toggle="dropdown" aria-expanded="false" id="#actionId">
Action
<span class="caret ml5"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li>
<a href="#Url.Action("Update", "IncomeTypeManagement", new
{
id = it.ID,
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" id="#editIncomeTypeId" title="Edit" data-rowhover="editTableRow">
Edit
</a>
</li>
</ul>
</div>
</td>
</tr>
tableRowIndex++;
}
</tbody>
</table>
#Html.Partial("_Pagination", Model.PagingInfo)
</div>
Create
#section scripts {
#Scripts.Render("~/bundles/jqueryajaxval")
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript" type="text/javascript">
$(document).ready(function () {
#* Cancel *#
$(document).on("click", "#CancelForm", function (e) {
var uri = '#Html.Raw(Url.Action("Index", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
}))';
window.location = uri;
e.preventDefault();
});
});
</script>
}
#section additionalStyles {
}
#section modal {
}
<article class="row">
<h1 class="pageTitle incomeTypeHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-1"></div>
<div id="incomeTypeResults" class="col-md-10 formContainer">
<div class="panel">
<div class="panel-heading">
<span class="panel-title">
<i class="glyphicon glyphicon-pencil"></i> Details Of New Income Type
</span>
</div>
#using (Html.BeginForm("Create",
"IncomeTypeManagement", FormMethod.Post,
new { id = "createIncomeType", role = "form", #class = "theme-primary form-horizontal" }))
{
#Html.AntiForgeryToken()
#* Pagination / Sorting *#
#Html.HiddenFor(m => m.PagingInfo.Page)
#Html.HiddenFor(m => m.PagingInfo.Take)
#Html.HiddenFor(m => m.PagingInfo.SortPropertyName)
#Html.HiddenFor(m => m.PagingInfo.SortAscending)
<fieldset>
<legend style="display: none">Create Income Type Form</legend>
#Html.HiddenFor(m => m.IsDeleted)
<div class="panel-body p25 fill bt0">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.IncomeTypeGroupId, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#{
// get drop down values for DropDownFor()
var selectableItems = incomeTypeGroups.Select((v, idx) => new SelectListItem
{
Text = v.Value,
Value = v.Key,
Selected = idx == 0
});
}
#Html.DropDownListFor(m => m.IncomeTypeGroupId, selectableItems, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.IncomeTypeGroupId, string.Empty, new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Name, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", id = "Name", placeholder = "Name..." })
#Html.ValidationMessageFor(m => m.Name, string.Empty, new { #class = "text-danger" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="text-center">
<input type="button" class="btn btn-primary" id="CancelForm" value="Cancel" />
<input type="submit" class="btn btn-primary" id="SubmitForm" value="Create" />
</div>
</div>
</fieldset>
}
</div>
</div>
</article>
Update
section scripts {
#Scripts.Render("~/bundles/jqueryajaxval")
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript" type="text/javascript">
$(document).ready(function () {
#* Cancel *#
$(document).on("click", "#CancelForm", function (e) {
var uri = '#Html.Raw(Url.Action("Index", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
}))';
window.location = uri;
e.preventDefault();
});
});
</script>
}
#section additionalStyles {
}
#section modal {
}
<article class="row">
<h1 class="pageTitle incomeTypeHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-1"></div>
<div id="incomeTypeResults" class="col-md-10 formContainer">
<div class="panel">
<div class="panel-heading">
<span class="panel-title">
<i class="glyphicon glyphicon-pencil"></i> Details Of '#Model.Name'
</span>
</div>
#using (Html.BeginForm("Update",
"IncomeTypeManagement", FormMethod.Post,
new { id = "updateIncomeType", role = "form", #class = "theme-primary form-horizontal" }))
{
#Html.AntiForgeryToken()
#* Pagination / Sorting *#
#Html.HiddenFor(m => m.PagingInfo.Page)
#Html.HiddenFor(m => m.PagingInfo.Take)
#Html.HiddenFor(m => m.PagingInfo.SortPropertyName)
#Html.HiddenFor(m => m.PagingInfo.SortAscending)
<fieldset>
<legend style="display: none">Edit Income Type Form</legend>
#Html.HiddenFor(m => m.ID)
#Html.HiddenFor(m => m.RowVersion)
#Html.HiddenFor(m => m.IsDeleted)
<div class="panel-body p25 fill bt0">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.IncomeTypeGroupId, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#{
// get drop down values for DropDownFor()
var selectableItems = incomeTypeGroups.Select((v, idx) => new SelectListItem
{
Text = v.Value,
Value = v.Key,
Selected = Model.IncomeTypeGroupId.ToString() == v.Key
});
}
#Html.DropDownListFor(m => m.IncomeTypeGroupId, selectableItems, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.IncomeTypeGroupId, string.Empty, new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Name, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", id = "Name", placeholder = "Name..." })
#Html.ValidationMessageFor(m => m.Name, string.Empty, new { #class = "text-danger" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="text-center">
<input type="button" class="btn btn-primary" onclick="this.disabled = true" id="CancelForm" value="Cancel" />
<input type="submit" class="btn btn-primary" id="SubmitForm" value="Update" />
</div>
</div>
</fieldset>
}
</div>
</div>
</article>
So I have tried adding <input type="submit" class="btn btn-primary" id="SubmitForm" value="Update" onclick="this.disabled = true" />
On the Create page When you click on Add Income Tye you are directed to the Create page, but when I have tied testing it the button is disabled, but then it does not submit anything and just remains on the Create page
To answer your question you kind of have to tackle the problem from 2 angles:
once click happens on your button you can either disable it or show an overlay so that no other elements on the page can be interacted with
you also have to think of what happens if some malicious user replays that request multiple times (by bypassing or altering the UI - which is dead easy to do) - on the server side you can use a processing queue of requests and every time you want to add a new request for processing, you can check to see if a duplicate exists
Unfortunately there isn't an easy answer for this. The 2nd part of the answer you have to think about it and assess if you're exposed to this issue. If your application is public and anyone can access it, don't assume that users will do everything on your system just via the UI.
Hope this helps.
This is what I come up with:
<script language="javascript" type="text/javascript">
$('.form-disable').on('submit', function () {
var self = $(this),
button = self.find('input[type="submit"], button'),
submitValue = button.data('submit-value');
button.attr('disabled', 'disabled').val((submitValue) ? submitValue : 'Please Wait...');
});
</script>
I added a class to the form so that when you click on a button that handles the submit, it disables the button and then waits with a message. But it only allows the button to be clicked once.
So I am trying to return a value from a text box as the parameter to another controller action that returns another partial. I think it would easier to just post some sample code rather than trying to explain what I am trying to do, so here is some sample code:
CSHTML:
<div class="row">
<div class="pt-sm-30 pb-xs-30 has-50px-footer">
<div class="col-lg-offset-1 col-lg-10">
<h3>CREATE A NEW PERSON PROFILE</h3>
<form class="form-spacers">
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label class="input-label" for="functionalRole">First Name <span class="ReqField">*</span></label>
#Html.TextBoxFor(model => model.Person.FirstName, new { #class = "form-control input-sm", #id = "firstName", #type = "text" })
</div>
<div class="col-md-6">
<label class="input-label" for="functionalRole">Last Name <span class="ReqField">*</span></label>
#Html.TextBoxFor(model => model.Person.LastName, new { #class = "form-control input-sm", #id = "lastName", #type = "text" })
</div>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-8 col-md-9 col-lg-10 new-profile-footer">
<div class="col-lg-offset-1 col-lg-5 col-md-4 hidden-sm hidden-xs" style="margin-top: 16px;">
</div>
<div class="col-lg-6 col-md-8 col-sm-12" style="margin-top: 10px; text-align: right;">
<div class="row" style="white-space: nowrap;">
<button class="btn btn-primary button-blue btn-xs-110" onclick="location.href='#Url.Action("Index", "DirectoryMaintainer")'"><i class="fa fa-times-circle-o icon-xs-hidden" aria-hidden="true" style="padding-right: 5px;"></i>CANCEL</button>
<button id="continue" type="button" class="btn btn-success button-green btn-xs-110">CONTINUE<i class="fa fa-caret-right icon-xs-hidden" style="padding-left: 5px;" aria-hidden="true"></i></button>
</div>
</div>
</div>
</div>
<script>
$("#continue").click(function () {
$("#partialViewDiv").load('#(Url.Action("RecordsMatch", "DirectoryMaintainer", new { #firstName = getFirstName(), #lastName = getLastName()}, Request.Url.Scheme))');
});
function getFirstName() {
return document.getElementById("firstName").value;
}
function getLastName() {
return document.getElementById("lastName").value;
}
</script>
Controller:
public PartialViewResult RecordsMatch(string firstName, string lastName)
{
//Do some logic with parameters here
return PartialView("_RecordsMatch");
}
So the issue I am having this that the line
$("#partialViewDiv").load('#(Url.Action("RecordsMatch", "DirectoryMaintainer", new { #firstName = getFirstName(), #lastName = getLastName()}, Request.Url.Scheme))');
is giving me an error on getFirstName() and getLastName(). The error is "The name getFirstName() does not exist in the current context". I am pretty new to MVC so I'm not sure if this is even possible or if there is a better way of doing it. If there is, then I am more than happy to learn it. Any and all suggestions would be greatly appreciated.
You cannot mix c# and js like that as the Url.Action gets executed in the server before your js code
Basically any C# code in your razor view gets executed by the razor view engine in the server and output of that (which is HTML/plain text) will be send to the browser. All your javascript code gets executed in the browser.
You can use Url.Action to generate the base url (without route value parameters) and add query strings to that at client side later.
$(function(){
$("#continue").click(function () {
var url='#Url.Action("RecordsMatch", "DirectoryMaintainer")';
url = url+'?firstName='+ getFirstName()+'&lastName='+getLastName();
$("#partialViewDiv").load(url);
});
});
When razor executes this code, it will render output like this (you can check the page view source and see this)
$(function(){
$("#continue").click(function () {
var url='/DirectoryMaintainer/RecordsMatch';
url = url+'?firstName='+ getFirstName()+'&lastName='+getLastName();
$("#partialViewDiv").load(url);
});
});
I have following list view
Once I click Reject I just configured to open a modal dialog like following
So Once I submit this modal dialog I want to submit modal values to method to save that in database table.
this is relevant model classes
public class ProductViewModel
{
public AB_Product Products { get; set; }
public IEnumerable<AB_Product> LProducts { get; set; }
}
public partial class AB_Product
{
public string ProductID { get; set; }
public string ApprovalStatus { get; set; }
public string ReasonEn { get; set; }
public string ReasonAr { get; set; }
}
this is view page code
#model project_name.Models.ProductViewModel
<table class="table">
<tr>
<th>
Name
</th>
<th>
Action
</th>
</tr>
#foreach (var obj in Model.LProducts)
{
<tr>
#Html.HiddenFor(modelItem => obj.ProductID)
<td>
#Html.DisplayFor(modelItem => obj.ProductTitleEn)
</td>
<td>
<div class="btn-group btn-group-sm" id="CreateButton">
<button type="button" class="btn btn-default" onclick="location.href='#Url.Action("Create")';return false;">View Product</button>
</div>
#if (obj.ApprovalStatus == "Pending")
{
<div class="btn-group btn-group-sm" id="ApproveButton">
<button type="button" class="btn btn-success" onclick="location.href='#Url.Action("Change_Product_State","Home", new { productid = obj.ProductID, value = "Approved" },null)';return false;">Approve</button>
</div>
<div class="btn-group btn-group-sm" id="RejectButton">
<button type="button" id="modal-opener" class="btn btn-danger" return false;">Reject</button>
</div>
}
<div class="btn-group btn-group-sm" id="CreateButton">
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Create_ProductComments","Home", new { productid = obj.ProductID }, null)';return false;">Add Comments</button>
</div>
</td>
</tr>
}
</table>
<div id="dialog-modal" title="Basic modal dialog">
#using (Ajax.BeginForm("Change_Product_State", "Home", new { value = "Rejected" }, new AjaxOptions { UpdateTargetId = "ID", OnSuccess = "onSuccess" }))
{
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(m => m.Products.ReasonEn)
</div>
<div class="editor-field">
#Html.TextAreaFor(m => m.Products.ReasonEn)
#Html.ValidationMessageFor(m => m.Products.ReasonEn)
</div>
<div class="editor-label">
#Html.LabelFor(m => m.Products.ReasonAr)
</div>
<div class="editor-field">
#Html.TextAreaFor(m => m.Products.ReasonAr)
#Html.ValidationMessageFor(m => m.Products.ReasonAr)
</div>
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
</div>
}
</div>
#section Scripts
{
<script>
$(function () {
$("#dialog-modal").dialog({
autoOpen: false,
width: 400,
height: 400,
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
}
});
$("#modal-opener").click(function () {
$("#dialog-modal").dialog("open");
});
});
function onSuccess() {
$("#dialog-modal").dialog("close");
}
</script>
}
how to bind list object I click which is ProductID with m.Products.ProductID
Remove the #Html.HiddenFor(modelItem => obj.ProductID) from the foreach loop and inside the Ajax.BeginForm() add
#Html.HiddenFor(m => m.Products.ProductID)
so its value can be posted. Then add the value of the ProductID as a data- attribute of the button (and change the id to class - see notes below)
<button type="button" class="modal-opener btn btn-danger" data-id="#obj.ProductID">Reject</button>
and modify the script to
$(".modal-opener").click(function () { // use class name
$('#Products_ProductID').val($(this).attr("data-id")); // set the value of the hidden input
$("#dialog-modal").dialog("open");
})
Note that you have a lot of invalid html due to duplicate id attributes generated by your foreach loop. Use class names instead. Your html should be
#foreach (var obj in Model.LProducts)
{
<tr>
<td>#Html.DisplayFor(modelItem => obj.ProductTitleEn)</td>
<td>
<div class="btn-group btn-group-sm CreateButton"> // change
<button type="button" class="btn btn-default" onclick="location.href='#Url.Action("Create")';return false;">View Product</button>
</div>
#if (obj.ApprovalStatus == "Pending")
{
<div class="btn-group btn-group-sm ApproveButton"> // change
<button type="button" class="btn btn-success" onclick="location.href='#Url.Action("Change_Product_State","Home", new { productid = obj.ProductID, value = "Approved" },null)';return false;">Approve</button>
</div>
<div class="btn-group btn-group-sm RejectButton"> // change
<button type="button" class="modal-opener btn btn-danger" data-id="#obj.ProductID">Reject</button> // as above
</div>
}
<div class="btn-group btn-group-sm CreateButton"> // change
<button type="button" class="btn btn-primary" onclick="location.href='#Url.Action("Create_ProductComments","Home", new { productid = obj.ProductID }, null)';return false;">Add Comments</button>
</div>
</td>
</tr>
}