MVC Html helper to make a label editable - asp.net-mvc

I have a html table generated in my view, does anyone know of any helpers available that I could use so that one of the fields could be edited in-line.
View:
<table>
<caption>Configuration values for current management group</caption>
<thead>
<tr>
<th scope="col">Device Type</th>
<th scope="col">Section</th>
<th scope="col">Name</th>
<th scope="col">Value</th>
<th scope="col">Operation</th>
</tr>
</thead>
<tbody>
#foreach (var param in Model.ParamData)
{
<tr>
<td>#param.DeviceType</td>
<td>#param.Group</td>
<td>#param.Name</td>
<td>#param.Value</td>
<td>#(param.IsMerge ? "Merge" : "Delete")</td>
</tr>
}
</tbody>
</table>
As you can see there is nothing special here, I would like an edit column that would work in a similar way to a web forms gridview. The only field to be edited would be value, and it would always be a textbox.
Im sure people must have done this before but the only example Ive seen on line was for mvc 1.
I could knock something up using jquery but am sure there must be loads of examples already and dont want to re-invent the wheel.

Ive done it myself, if anyones interested:
#foreach (var param in Model.ParamData)
{
<tr>
<td>#param.DeviceType</td>
<td>#param.Group</td>
<td>#param.Name</td>
<td>
<div class="#("ViewValueDiv_" + param.ParamaterValueId)">
#param.Value
</div>
<div class="#("EditValueDiv_" + param.ParamaterValueId)" style="display:none;">
<input type="text" name="#("EditValue_" + param.ParamaterValueId)" value="#param.Value" class="#("Input_" + param.ParamaterValueId)" />
</div>
</td>
<td>#(param.IsMerge ? "Merge" : "Delete")</td>
<td>
<div class="#("EditButtonDiv_" + param.ParamaterValueId)">
<input type="button" value="Edit" class="EditButton" Id="#param.ParamaterValueId" />
</div>
<div class="#("UpdateCancelButtonDiv_" + param.ParamaterValueId)" style="display:none;">
<input type="button" value="Update" class="UpdateButton" id="#("U" + param.ParamaterValueId)" />
<input type="button" value="Cancel" class="CancelButton" id="#("C" + param.ParamaterValueId)" />
</div>
</td>
</tr>
}
$(document).ready(function () {
$(".EditButton").click(function () {
var id = $(this).attr('id');
$(".ViewValueDiv_" + id).hide();
$(".EditValueDiv_" + id).show();
$(".EditButtonDiv_" + id).hide();
$(".UpdateCancelButtonDiv_" + id).show();
oldvalue = $(".Input_" + id).val();
});
$(".CancelButton").click(function () {
var id = $(this).attr('id').substr($(this).attr('id').indexOf("C") + 1);
$(".ViewValueDiv_" + id).show();
$(".EditValueDiv_" + id).hide();
$(".EditButtonDiv_" + id).show();
$(".UpdateCancelButtonDiv_" + id).hide();
$(".Input_" + id).val(oldvalue);
});
$(".UpdateButton").click(function () {
var id = $(this).attr('id').substr($(this).attr('id').indexOf("U") + 1);
NewValue = $(".Input_" + id).val();
if (NewValue) {
$.ajax({
url: "/Terminals_configuration/UpdateConfigValue",
data: { valueId: id, newValue: NewValue },
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred.");
},
success: function (data) {
$(".ViewValueDiv_" + id).show();
$(".EditValueDiv_" + id).hide();
$(".EditButtonDiv_" + id).show();
$(".UpdateCancelButtonDiv_" + id).hide();
$(".ViewValueDiv_" + id).html(NewValue);
}
});
} else {
alert("You didn't supply a new value");
}
});
});

Related

Removing rows from simple table

I'm trying to figure out how to remove rows from a table. More specifically, rows that user might have ADDED.
Essentially my table gets data from a DB. I have a link "Add Row" that seems to work okay. It'll add a row, and add along the 'save' and 'delete' button on the row. See:
As you can see, the idea is to be able to 'cancel' this newly added row. However, I cannot find simple examples on how to do it, nor can I even seem to trigger the click() of the delete button!
My code:
$(function() {
/* <table id="tableX"> tag to specify different tables to be threated by the Tablesorter */
var $table = $('#table1');
var enabledlbl = localejs.gettext("Enabled");
var disabledlbl = localejs.gettext("Disabled");
var fieldRequiredlbl = localejs.gettext("This field is required!");
var dayslbl = localejs.gettext("days");
var monthslbl = localejs.gettext("months");
var savelbl = localejs.gettext("Save");
var deletelbl = localejs.gettext("Delete");
var accStatuslbl = localejs.gettext("Account Status");
/***************************
* main tablesorter config
***************************/
$table.tablesorter( {
theme : "bootstrap",
widthFixed: true,
/* click on column header a 3rd time to disable sorting, else need to ctrl+click */
sortReset: false,
// widget code contained in the jquery.tablesorter.widgets.js file
// use the zebra stripe widget if you plan on hiding any rows (filter widget)
// the uitheme widget is NOT REQUIRED!
// PROY: eventually also look at the Output Widget
widgets : [ "columns", "zebra"],
widgetOptions : {
// using the default zebra striping class name, so it actually isn't included in the theme variable above
// this is ONLY needed for bootstrap theming if you are using the filter widget, because rows are hidden
zebra : ["even", "odd"],
// class names added to columns (need 'columns' widget) when sorted
columns: [ "primary", "secondary", "tertiary" ]
}
});
/***************************
* Add row function
***************************/
$('.addrow').click(function() {
var row = '' +
'<tr class="newrow">' +
'<td><input type="hidden" name="id" value="0"></td>' +
'<td>'+
'<select name="isActive" id="isActive" class="form-control pl-2" aria-label="' + accStatuslbl + '" aria-describedby="isActiveReq">' +
' <option value="1" selected>' + enabledlbl + '</option>' +
' <option value="0">' + disabledlbl + '</option>' +
'</select>' +
'<div id="isActiveReq" class="pl-1 invalid-feedback">' + fieldRequiredlbl + '</div>' +
'</td>' +
'<td>' +
'<input type="text" name="days" id="days" class="form-control"' +
' placeholder="'+ dayslbl +'"' +
' aria-label="' + dayslbl + '"' +
' aria-describedby="daysReq"' +
' value=""' +
' required/>' +
'<div id="daysReq" class="pl-1 invalid-feedback">' + fieldRequiredlbl + '</div>' +
'</td>' +
'<td>' +
'<input type="text" name="months" id="months" class="form-control"' +
' placeholder="'+ monthslbl +'"' +
' aria-label="' + monthslbl + '"' +
' aria-describedby="monthsReq"' +
' value=""' +
' required/>' +
'<div id="monthsReq" class="pl-1 invalid-feedback">' + fieldRequiredlbl + '</div>' +
'</td>' +
'<td class="text-right text-nowrap">' +
' <input type="submit" name="btnSave" value="' + savelbl + '" style="font-weight: normal; font-size: 1.1em; color: red;">' +
' <input type="button" name="btnDelete" value="' + deletelbl + '" class="delrow" style="font-weight: normal; font-size: 1.1em;">' +
'</td>' +
'</tr>';
$row = $(row),
// resort table using the current sort; set to false to prevent resort, otherwise
// any other value in resort will automatically trigger the table resort.
resort = true;
$table
.find('tbody').append($row)
.trigger('addRows', [$row, resort]);
return false;
});
/***************************
* Delete row function
***************************/
$('.delrow').click(function() {
alert("delete row..");
});
});
<!doctype html>
<html lang="en">
<head>
<!-- jQuery tablesorter related -->
<link href="/css/jquery-tablesorter/theme.bootstrap_4.prestadesk.css" rel="stylesheet" type="text/css">
<script src="/js/jquery-tablesorter/jquery.tablesorter.combined.min.js"></script>
<script src="/js/prestadesk.tablesorter.onem_conditions.js"></script>
</head>
<body>
<table class="table table-striped table-md table-responsive-lg w-auto" id="table1">
<thead class="pt-2">
<th scope="col" data-priority="critical" data-label="ID" data-filter="false" class="colID">ID</th>
<th scope="col" data-priority="critical" data-sorter="false" data-filter="false" class="colStatus" data-label="STATUS" data-placeholder="" class="">STATUS</th>
<th scope="col" data-priority="critical" data-sorter="false" data-filter="false" data-label="DAYS">DAYS</th>
<th scope="col" data-priority="critical" data-sorter="false" data-filter="false" data-label="MONTHS">MONTHS</th>
<th data-priority="critical" data-sorter="false" data-filter="false" data-columnSelector="disable" data-label="SPACER" data-name="SPACER"> </th>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>STATUS</th>
<th>DAYS</th>
<th>MONTHS</th>
<th> </th>
</tr>
<tr>
<td colspan="5" class="pl-3 pt-2 pb-2" style="border-bottom-style: hidden;">
<div class="row ">
<div class="col-auto pr-2">
[ Add Row ]
</div>
<div class="col-auto pl-0 ml-0">
* save the added row before inserting new ones!
</div>
</div>
</td>
</tr>
</tfoot>
<tbody>
<tr>
<!-- ID -->
<td class="pl-3 data-rowheader">
<input type="hidden" name="id" value="1">
1
</td>
<!-- STATUS -->
<td class="text-nowrap">
<select name="isActive" id="isActive" class="form-control pl-2">
<option value="1" selected>Enabled</option>
<option value="0" >Disabled</option>
</select>
</td>
<!-- DAYS -->
<td>
<input type="text" name="days" id="days" class="form-control"
placeholder="days"
value="156"
required/>
</td>
<!-- MONTHS -->
<td>
<input type="text" name="months" id="months" class="form-control"
placeholder="months"
value="18"
required/>
</td>
<!-- FORM BUTTONS -->
<td class="text-right text-nowrap">
<input type="submit" name="btnSave" value="Save" style="font-weight: normal; font-size: 1.1em;">
<input type="button" name="btnDelete" class="delrow" value="Delete" style="font-weight: normal; font-size: 1.1em;">
</td>
</tr>
</tbody>
</table>
</body>
</html>
It seems that the $('.delrow').click(function()... gets properly called if I add the class="delrow" to the main, existing 'delete' buttons, but upon adding a row, even if the new added row button has the 'delrow' class, it doesn't go through the $('.delrow').click even at all.
That is my first problem. Second, as mentioned initially, I can't seem to find a simple example. I am not using any particular widgets here or anything. It's a simple table... Should I ?
I did came across Pager plugin - examples of how to add and remove rows. from https://mottie.github.io/tablesorter/docs/example-pager.html, however, frankly, I do now understand it. Why would I need the pager just to remove a row? And frankly it seems way overkill, no ?
If anyone can shed a light on this... Many thanks! pat
Use delegated binding on the delete button:
$table.on('click', '.delrow', function() {
$(this).closest('tr').remove();
$table.trigger('update');
});

jquery goes on the first page instead mine

I have 2 pages (data-role="page") in my HTML page, in the list page if you go to one detail, save, and try to go into another detail again, it goes to list instead of the detail page.
I tried to follow the code using chrome but the javascript is correct
To change page i use: $.mobile.changePage("#PageAddCustomer");
but it seems working for just 1/2 second, then it goes to the list (who is the first page in the code)
Chrome does not return any javascript error,
just here in stackoverflow preview it returns :"error loading page", with no clues on it
what is wrong ?
I am thinking to use 2 different HTML files, probably it could be an idea
var lat = 0;
var lng = 0;
var map;
var url = "https:////www.suale.it"; //"http://localhost:65386/";//
var urlSito = url+"//GestionePersonale";// "http://localhost:65386/";//
var urlCartellaIMG =url + "//IMGAnnunci";// url+"//public//IMGAnnunci";//
//tiene in memoria
var Categorie;
var Tipologie;
var TipoAnnunci;
var Razze;
$(document).ready(function () {
$("div[data-role='panel']").panel().enhanceWithin();
VaiCustomers();
});
//target the entire page, and listen for touch events
$('html, body').on('touchstart touchmove', function(e){
//prevent native touch activity like scrolling
e.preventDefault();
});
function caricaCustomer(j) {
var $select = $('#cbbInsAdsCustomer');
$select.find('option').remove();
$select.append("<option ></option>");
$.each(j, function (key, value) {
$select.append('<option value=' + value.CodTipologia + '>' + value.DescTipologia + '</option>');
});
}
function GoPage(page) {
//$.mobile.changePage(page);
$(':mobile-pagecontainer').pagecontainer('change', page, {
transition: 'flip',
changeHash: false,
reverse: true,
showLoadMsg: true
});
}
function DoNothing() { }
function CaricaDettagliClienteDetail(J) {
// J = JSON.stringify(J);
J = JSON.parse(J);
$("#txtDetailCliCognome").text(J.Cognome);
$("#txtDetailCliNominativo").text(J.Nominativo);
$("#txtDetailCliIndirizzo").text(J.Indirizzo);
$("#txtDetailCliEmail").text(J.Email);
$("#txtDetailCliCitta").text(J.Citta);
$("#txtDetailCliCellulare").text(J.Cellulare);
$("#txtDetailCliTelefono").text(J.Telefono);
}
function CaricaDatiDetailIMG(data) {
var codAnn = $("#hidCodRapportino").val();
var ico;
var img;
$("#divDetailIMG").empty('');
//img = img.replace('\\', '//').replace('ICO', '');
var x, txt = "";//aggiungo IMG
for (x in data) {
var ico = urlCartellaIMG + "//" + codAnn + "//" + data[x];
var img = ico.replace('ICO', '');
txt += "<img onclick='OpenPopIMG(`" + img + "`)' src='" + ico + "'>";
}
$("#divDetailIMG").html(txt);
}
function GoHEad() {
$.mobile.changePage("#page1");
}
function getToNextPage() {
$.mobile.changePage("#page2");
}
function ScaricaDatiUser() {
var codAnag = $("#hidCodAnagrafica").val();
if (codAnag == '')
{
Messaggio('you must login to see your ads');
return;
}
s = document.createElement("script");
//var Category = $('#cbbSearchCategory option:selected').val();
s.src = urlSito + "/scriptWS.aspx?func=CaricaDatiListaUser&OnErr=Messaggio&modo=ListaUser&codAnag=" + codAnag
//alert(s.src);
document.body.appendChild(s);
}
//#region Customer
function VaiCustomers()
{
if (ControlloLoggato()==false){return;};
GoPage('#PageListCustomer');
CaricaCustomers();
}
function CaricaCustomers()
{
s = document.createElement("script");
var RCodDitta = $('#hidCodDitta').val();
s.src = urlSito + "/scriptWS.aspx?func=CustomersList&OnErr=Messaggio&modo=GetCustomers&CodDitta=" + RCodDitta;
//alert(s.src);
document.body.appendChild(s);
}
function CustomersList(data) {
$('#DTCustomersList').DataTable({
destroy: true,
data: data,
"columns": [
{ "data": "Cognome" },
{ "data": "Nominativo" },
{
"data": "CodAnagrafica",
"mData": function showIMGLista(data, type, dataToSet) {
var J = JSON.stringify(data);
var CodAnagrafica = data.CodAnagrafica;
return "<img src='IMG\\Detail.jpg' onclick='OpenDetailCustomer(" + CodAnagrafica + ");'>";
}
},
]
});
}
function OpenDetailCustomer(CodAnagrafica)//dal principale annuncio carico tutto
{
s = document.createElement("script");
s.src = urlSito + "/scriptWS.aspx?func=CaricaCurstomerDetail&OnErr=Messaggio&modo=GetDetailAnag&CodAnagrafica=" + CodAnagrafica;
document.body.appendChild(s);
//$.mobile.changePage("#PageAddCustomer");
$(':mobile-pagecontainer').pagecontainer('change', '#PageAddCustomer', {
transition: 'flip',
changeHash: false,
reverse: true,
showLoadMsg: true
});
}
function CaricaCurstomerDetail(J) {
// J = JSON.stringify(J);
//J = JSON.parse(J);
$("#txtInsCliCognome").val(J.Cognome);
$("#txtInsCliNominativo").val(J.Nominativo);
$("#txtInsCliIndirizzo").val(J.Indirizzo);
$("#txtInsCliEmail").val(J.Email);
$("#txtInsCliCitta").val(J.Citta);
$("#txtInsCliTelefono").val(J.Cellulare);
$("#txtInsCliCellulare").val(J.Telefono);
$("#hidCodCustomer").val(J.CodAnagrafica);
}
function ConfirmDeleteCustomer()
{
bootbox.confirm("Are you sure?", function (result)
{
if (result) {
DeleteCustomer();
}
});
}
function DeleteCustomer()
{
var CodAnagrafica= $("#hidCodCustomer").val();
s = document.createElement("script");
s.src = urlSito + "/scriptWS.aspx?func=CaricaCustomers&OnErr=Messaggio&modo=DeleteCustomer&CodAnagrafica=" + CodAnagrafica;
document.body.appendChild(s);
$.mobile.changePage("#PageListCustomer");
}
function SaveCustomer()
{
if (ControlloSaveCustomer() == true)
{
var Cognome= $("#txtInsCliCognome").val();
var Nominativo= $("#txtInsCliNominativo").val();
var Indirizzo= $("#txtInsCliIndirizzo").val();
var Email= $("#txtInsCliEmail").val();
var Citta= $("#txtInsCliCitta").val();
var Cellulare= $("#txtInsCliTelefono").val();
var Telefono= $("#txtInsCliCellulare").val();
var CodAnagrafica= $("#hidCodCustomer").val();
var RCodDitta = $('#hidCodDitta').val();
s = document.createElement("script");
s.src = urlSito + "/scriptWS.aspx?func=DoNothing&OnErr=Messaggio&modo=SaveAnagrafica&CodAnagrafica=" + CodAnagrafica + "&Cognome=" + Cognome + "&Nominativo=" + Nominativo
+ "&Indirizzo=" + Indirizzo + "&Email=" + Email + "&Citta=" + Citta + "&Cellulare=" + Cellulare + "&Telefono=" + Telefono + "&RCodDitta=" + RCodDitta+ "&Cliente=1";
document.body.appendChild(s);
VaiCustomers();
GoPage('#PageListCustomer');
}
// $.mobile.changePage("#PageListCustomer");
}
function ControlloSaveCustomer() {
$("#txtInsCliCognome").removeClass('inputObbligatorio');
$("#txtInsCliCellulare").removeClass('inputObbligatorio')
$("#txtInsCliNominativo").removeClass('inputObbligatorio')
if ($("#txtInsCliCognome").val() == '') { $("#txtInsCliCognome").addClass('inputObbligatorio'); return false; }
if ($("#txtInsCliCellulare").val() == '') { $("#txtInsCliCellulare").addClass('inputObbligatorio'); return false; }
if ($("#txtInsCliNominativo").val() == '') { $("#txtInsCliNominativo").addClass('inputObbligatorio'); return false; }
return true;
}
//#endregion
function CaricaDatiListaUser(data) {
caricaUserDatatable(data);
}
function ControlloLoggato() {
var codAnag = $("#hidCodAnagrafica").val();
if (codAnag == '') {
Messaggio('you must login to manage ads');
return false;
}
}
.img-container { position: relative; }
.img-container .top {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.lblDesc {
font-weight: bold !important;
}
.inputObbligatorio {
border: 2px solid #ff0000 !important;
}
.auto-style1 {
height: 25px;
}
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" />
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<input type="hidden" id="hidCodAnagrafica" value="1"/>
<input type="hidden" id="hidCodDitta" value="1"/>
<div data-role="panel" id="menuPanel" data-mini="true" data-rel="popup" style=" z-index: 1;" class="ui-btn ui-corner-all ui-shadow ui-btn-inline ui-icon-bars ui-btn-icon-left ui-btn-b" data-transition="pop">
<h4>Menu</h4>
<ul data-role="listview">
<!-- <li>List Admin</li>
<li>Your Reports</li>-->
<!-- <li>New Report</li>-->
<li>Customers</li>
<!-- <li>Jobs</li>
<li>Employees</li>-->
<!-- <li>Register</li>
<li>Login</li>
<li><a href="#" onclick='Website2APK.rateUs();'>Rate us</a></li>-->
<!--<img src="img/head2.jpg" />-->
</ul>
</div>
<!--panel-->
<div data-role="page" id="PageListCustomer" style="background-color: #E5E7E9;">
<h2>Customers</h2>
Menu
<table id="DTCustomersList" class="display" style="width: 100%">
<thead>
<tr>
<th>Surname</th>
<th>Name</th>
<th></th>
</tr>
</thead>
</table>
<input class="btn btn-primary" type="submit" onclick="GoPage('#PageAddCustomer');" value="Add" />
</div> <!--- PageListCustomer --->
<div data-role="page" id="PageAddCustomer" style="background-color: #E5E7E9;">
<h2>Customer</h2>
Menu
<input type="hidden" id="hidCodCustomer" />
<form id="frmAddCustomer">
<table style='border-collapse:collapse;' >
<tr>
<td>
<label class="lblDesc">Surname</label>
</td>
<td>
<input type="text" id="txtInsCliCognome" />
</td>
</tr>
<tr>
<td>
<label class="lblDesc">Name</label></td>
<td>
<input type="text" id="txtInsCliNominativo" />
</td>
</tr>
<tr>
<td>
<label class="lblDesc">Address</label></td>
<td>
<input type="text" id="txtInsCliIndirizzo" />
</td>
</tr>
<tr>
<td>
<label class="lblDesc">Email</label></td>
<td>
<input type="text" id="txtInsCliEmail" />
</td>
</tr>
<tr>
<td>
<label class="lblDesc">City</label></td>
<td>
<input type="text" id="txtInsCliCitta" />
</td>
</tr>
<tr>
<td class="auto-style1">
<label class="lblDesc">Mobile Ph.</label></td>
<td class="auto-style1">
<input type="text" id="txtInsCliTelefono" />
</td>
</tr>
<tr>
<td>
<label class="lblDesc">Phone</label></td>
<td>
<input type="text" id="txtInsCliCellulare" />
</td>
</tr>
</table>
<input class="btn btn-primary" type="submit" onclick="SaveCustomer();" value="Save" />
<input class="btn btn-primary" type="submit" onclick=" VaiCustomers();" value="List" />
</form>
</div> <!--- PageAddCustomer --->

MVC Partial Page returns whole page, not just the partial

I have a button on a page:
<div>
From:
<input id="fromDate" type="date" name="fromDate" value="#a.FromDate">
To:
<input id="toDate" type="date" value="#a.ToDate">
<button type="button" id="btn_transactions" class="btn btn-primary" onclick="btnTrans()"><span class="glyphicon glyphicon-search"></span></button>
<label class="buy-heading">Total Buys: #String.Format("{0:n0}", #q.BuyQuantity)</label><label class="sell-heading">Total Sells: #String.Format("{0:n0}", #q.SellQuantity)</label>
</div>
It calls this function on click:
function btnTrans() {
var postdata = { "symbol": $("#savesymbol").val(), "fromDate": $("#fromDate").val(), toDate: $("#toDate").val() };
var url = "Company/Transactions?symbol=" + $("#savesymbol").val() + "&fromDate=" + $("#fromDate").val() + "&toDate=" + $("#toDate").val();
$.ajax({
url: url,
success: function (result) {
alert(result)
$('#transTarget').html(result);
},
error: function () {
//alert("Error occured");
}
});
}
The controller method is:
public async Task<PartialViewResult> Transactions(string symbol, string
fromDate, string toDate)
{
return PartialView("Transactions");
}
This is the partial view:
<table id="transactionsTable" class="table table-bordered display hover no-wrap dataTables" style="width: 100%">
<thead>
<tr>
<th>Account Category</th>
<th>Trade Date</th>
<th>Account Name</th>
<th>Activity</th>
<th>Quantity</th>
<th>Exec Price</th>
<th>Principal</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
var a = item.accounts;
foreach (var item2 in a)
{
<tr>
<td>#item2.AcctCategory</td>
<td>#String.Format("{0:MM/dd/yyyy}", #item2.TradeDate)</td>
<td>#item2.AccountName</td>
<td>#item2.Trans</td>
<td>#String.Format("{0:n}", item2.Quantity)</td>
<td>#String.Format("{0:n}", item2.ExecutionPrice)</td>
<td>#String.Format("{0:n}", item2.PrincipalAmount)</td>
</tr>
}
}
</tbody>
</table>
I have 3 partials on this page as follows:
<div class="mycontent2">
#{Html.RenderAction("Documents", "Company");}
</div>
<div class="mycontent2">
#{Html.RenderAction("Holdings", "Company");}
</div>
<div class="mycontent2">
#{Html.RenderAction("Transactions", "Company");}
</div>
The problem is that the partial view returned from the controller method returns the WHOLE page, not just the partial part of transactions. What am I doing wrong?
Return a model from the controller. Like this;
return PartialView("Transactions", model);
Do it for others partial.
Then, you will use model in your view.
Use #{ Layout = null; } in your partial view.

inline editing table / grid for for MVC

What is the easiest way to create a table where users can edit data directly (excel like) with minimum effort?
There are a lot of libraries and custom control but I am looking for something that is easy to implement and does not require a lot of coding.
In the controller create method for adding where you pass the parameter to with GET:
public bool EditData(int pkId, int statusID, string Comments)
{
// logic to edit
}
In your view add a table of data with your controls add the primary key to the ID of the control so that you can use it in jquery
<table class="table">
<tr>
<th>Status</th>
<th>Comments</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr class="searchable">
<td>
#Html.DropDownList("StatusID" + #Html.DisplayFor(modelItem => item.pkID), new SelectList(ViewBag.Status, "StatusID", "StatusTitle", item.StatusID), htmlAttributes: new { #class = "form-control", style = "width:100px" })
</td>
<td>
<textarea id="Comments_#Html.DisplayFor(modelItem => item.pkID)" rows="5" cols="20">#Html.DisplayFor(modelItem => item.Comments)</textarea>
</td>
<td>
<input type="button" class="btn btn-default" value="save" onclick='updateData("#Html.DisplayFor(modelItem => item.pkID)" )' />
</td>
</tr>
}
</table>
In the javascript add a call to the the edit method
function updateData(pkID) {
// the id of the drop down list is AssetEffectiveness + effectivnessid
var Status = $("#StatusID" + pkID).val();
var Comments= $("#Comments_" + pkID).val();
$.ajax({
url: "YOU_CONTROLLER_URL/EditData?pkId=" + pkID + "&statusID=" + Status + "&Comments=" + Comments,
cache: false
})
.done(function (data) {
if (data == 'True') {
// change bg of the tr
$("#Commects_" + pkID).closest('tr').css('background-color', '#eeffee');
// animate to indicate the save
$("#Commects_" + pkID).closest('tr').fadeOut(500).fadeIn(500);
// return color back after 2 seconds
setTimeout(function () { $("#Commects_" + pkID).closest('tr').css('background-color', ''); }, 1000);
}
else {
alert('not saved');
$("#Commects_" + pkID).closest('tr').css('background-color', '#ffcccc');
}
});
}

Can not save data 2nd time knockout mvc

I am new in knockout and asp.net mvc both.
I am trying to Insert update delete data in database with knockout. My knockout model is
function City(data) {
this.CityId = ko.observable(data.CityId);
this.CityName = ko.observable(data.CityName);
}
function CityViewModel() {
var self = this;
self.Citys = ko.observableArray([]);
self.CityId = ko.observable();
self.CityName = ko.observable();
self.selectedCity = ko.observable();
// self.City = ko.observable();
selectCity = function (item) {
self.selectedCity(item);
}
//load
loadCitys = function () {
$.getJSON("/Admin/GetCitys", {}, function (result) {
var mappedCitys = ko.utils.arrayMap(result.Data, function (item) {
return new City(item);
});
self.Citys([]);
self.Citys.push.apply(self.Citys, mappedCitys);
});
}
//edit
EditCity = function (item) {
//what need to do here
// is it possible to fill the hidden fild and the text box ??
}
//save
SaveCity = function (item) {
City = new City(item);
$.ajax({
type: "POST",
url: "/Admin/SaveCity",
data: ko.toJSON({ City: City }),
contentType: "application/json",
success: function (result) {
if (result.Edit) {
City.CityId = result.Success;
City.CityName = item.CityName;
self.Citys.push(City);
toastr.success('City Information Save Successfully', 'Success');
}
else if (result.Edit == false) {
toastr.success('City Information Update Successfully', 'Success');
}
else {
toastr.error('There is an error please try again later', 'Errror');
}
}
});
}
//delete
DeleteCity = function (City) {
$.ajax("/Admin/DeleteCity", {
data: ko.toJSON({ CityId: City.CityId }),
type: "POST", contentType: "application/json",
success: function (result) {
if (result.Success) {
self.Citys.remove(City);
toastr.success('City Remove Successfully', 'Success');
}
else {
alert("Error..");
}
}
});
}
}
(function () {
ko.applyBindings(new CityViewModel, document.getElementById("Citys"));
loadCitys();
});
And my Html codes are
<table class="table table-striped">
<thead>
<tr>
<th>City Id</th>
<th>City Name</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: $root.Citys">
<tr data-bind="click: selectCity">
<td><span data-bind="text:CityId"></span></td>
<td><span data-bind="text:CityName"></span></td>
<td><button data-bind="click: EditCity" class="btn btn-primary">Edit</button></td>
<td><button data-bind="click: DeleteCity" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
<fieldset>
<legend>Add new / Edit City</legend>
<label>City name</label>
<input type="hidden" data-bind="value: CityId" />
<input type="text" data-bind="value: CityName" placeholder="Type city nameā€¦">
<button type="submit" data-bind="click: SaveCity" class="btn">Submit</button>
</fieldset>
With this codes I can get data form database display them successfully in my view file,
I delete the data from database, and I also can Insert data to database but here is a problem I can save data only 1st time when I change the textbox value (without page refresh) and try to save city information then it say (in Firebug on my javascript code):
TypeError: City is not a constructor
City = new City(item);
My question is what have I done wrong in this codes, and I am trying to fill the textbox and the hidden field when edit button click, how can I do this?
Thanks in advance.
There are a number of faults with your javascript, including:
The methods on your viewmodel, such as SaveCity, DeleteCity, EditCity are all being defined without the 'this/self' prefixes, therefore they are being added to the global namespace.
In your SaveCity method, your are assigning a new instance of the City class to a variable called 'City', therefore destroying the City class. It will work the first time, but any other attempts to create an instance of a City will yield an exception.
Anyway, this should be a working version of your script and HTML without the ajax stuff. You will need to adapt that yourself. I have also created a working JsFiddle here..
function City(data) {
this.CityId = ko.observable(data.CityId);
this.CityName = ko.observable(data.CityName);
}
function CityViewModel() {
var self = this;
self.Citys = ko.observableArray([]);
self.SelectedCity = ko.observable();
self.EditingCity = ko.observable(new City({CityId: null, CityName: ''}));
self.EditCity = function(city){
self.EditingCity(new City(ko.toJSON(city)));
};
//load
self.loadCitys = function () {
self.Citys().push(new City({CityId: '1245', CityName: 'Los Angeles'}));
self.Citys().push(new City({CityId: '45678', CityName: 'San Diego'}));
};
//save
self.SaveCity = function () {
var city = self.EditingCity();
if(city.CityId()){
var cityIndex;
for(var i = 0; i < self.Citys().length; i++) {
if(self.Citys()[i].CityId() === city.CityId()) {
cityIndex = i;
break;
}
}
self.Citys[cityIndex] = city;
}
else{
city.CityId(Math.floor((Math.random()*1000000)+1));
self.Citys.push(city);
}
self.EditingCity(new City({CityId: null, CityName: ''}));
}
//delete
self.DeleteCity = function (city) {
self.Citys.remove(city);
};
}
var viewModel = new CityViewModel();
viewModel.loadCitys();
ko.applyBindings(viewModel, document.getElementById("Citys"));
HTML
<table class="table table-striped">
<thead>
<tr>
<th>City Id</th>
<th>City Name</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: Citys">
<tr data-bind="click: $root.SelectedCity">
<td><span data-bind="text:CityId"></span></td>
<td><span data-bind="text:CityName"></span></td>
<td><button data-bind="click: $root.EditCity" class="btn btn-primary">Edit</button></td>
<td><button data-bind="click: $root.DeleteCity" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
<fieldset data-bind='with:EditingCity'>
<legend>Add new / Edit City</legend>
<label>City name</label>
<input type="hidden" data-bind="value: CityId" />
<input type="text" data-bind="value: CityName" placeholder="Type city name" />
<button type="submit" data-bind="click: $root.SaveCity" class="btn">Submit</button>
</fieldset>

Resources